By default, Bugzilla does not search the list of RESOLVED bugs.
You can force it to do so by putting the upper-case word ALL in front of your search query, e.g.: ALL tdelibs
We recommend searching for bugs this way, as you may discover that your bug has already been resolved and fixed in a later release. View | Details | Raw Unified | Return to bug 1547
Collapse All | Expand All

(-)tdenetwork.ori/kopete/ConfigureChecks.cmake (-2 / +2 lines)
Lines 9-16 Link Here
9
#
9
#
10
#################################################
10
#################################################
11
11
12
# glib-2.0 (jabber, msn)
12
# glib-2.0 (jabber)
13
if( (BUILD_KOPETE_PROTOCOL_JABBER AND WITH_JINGLE) OR (BUILD_KOPETE_PROTOCOL_MSN AND WITH_WEBCAM) )
13
if( BUILD_KOPETE_PROTOCOL_JABBER AND WITH_JINGLE )
14
  pkg_search_module( GLIB2 glib-2.0 )
14
  pkg_search_module( GLIB2 glib-2.0 )
15
  if( GLIB2_FOUND )
15
  if( GLIB2_FOUND )
16
    set( HAVE_GLIB 1 CACHE INTERNAL "" FORCE )
16
    set( HAVE_GLIB 1 CACHE INTERNAL "" FORCE )
(-)tdenetwork.ori/kopete/KABC_INTEG_NOTES (-1 / +1 lines)
Lines 38-44 Link Here
38
38
39
brunes goals
39
brunes goals
40
the only points I wanted to make were 
40
the only points I wanted to make were 
41
1. I think the MSN / OSCAR picture support should somehow integrate with / use the picture in kaddressbook, and
41
1. I think the OSCAR picture support should somehow integrate with / use the picture in kaddressbook, and
42
2. we need to get the KAB guys to add >1 field for IM account in KAB, and all the contacts for a MC should have their accounts there
42
2. we need to get the KAB guys to add >1 field for IM account in KAB, and all the contacts for a MC should have their accounts there
43
43
44
Syncing policies
44
Syncing policies
(-)tdenetwork.ori/kopete/kopete/eventsrc (-175 lines)
Lines 997-1177 Link Here
997
Comment[zh_TW]=新郵件送達您的 Yahoo 收件匣
997
Comment[zh_TW]=新郵件送達您的 Yahoo 收件匣
998
default_presentation=16
998
default_presentation=16
999
999
1000
[msn_alert]
1001
Name=MSN Alert
1002
Name[bg]=MSN съобщение
1003
Name[ca]=Alerta del MSN
1004
Name[cs]=MSN upozornění
1005
Name[da]=MSN-alarm
1006
Name[de]=MSN-Warnung
1007
Name[el]=Ειδοποίηση του MSN
1008
Name[es]=Alerta MSN
1009
Name[et]=MSN teade
1010
Name[fa]=هشدار ام‌اس‌ان
1011
Name[fi]=MSN-varoitus
1012
Name[fr]=Alerte MSN
1013
Name[he]=אזהרה של MSN
1014
Name[hu]=MSN értesítő
1015
Name[is]=MSN skeyti
1016
Name[it]=Avviso MSN
1017
Name[km]=សេចក្ដី​ជូនដំណឹង MSN
1018
Name[lt]=MSN: „dėmesio!“
1019
Name[nb]=MSN-varsling
1020
Name[nds]=MSN-Alarm
1021
Name[ne]=एमएसएन सावधानी
1022
Name[nl]=MSN-melding
1023
Name[pa]=MSN ਚੇਤਾਵਨੀ
1024
Name[pl]=Alarm MSN
1025
Name[pt]=Alerta MSN
1026
Name[pt_BR]=Alerta do MSN
1027
Name[ru]=Предупреждение MSN
1028
Name[sk]=MSN Upozornenie
1029
Name[sl]=Alarm MSN
1030
Name[sr]=MSN аларм
1031
Name[sr@Latn]=MSN alarm
1032
Name[sv]=MSN-larm
1033
Name[tr]=MSN Uyarısı
1034
Name[uk]=Сигнал MSN
1035
Name[zh_CN]=MSN 提醒
1036
Name[zh_TW]=MSN 警告
1037
Comment=A new alert has been sent to you
1038
Comment[bg]=Изпратено ви е ново съобщение
1039
Comment[ca]=Se us ha enviat una nova alerta
1040
Comment[cs]=Bylo vám doručeno nové upozornění
1041
Comment[da]=En ny alarm er sendt til dig
1042
Comment[de]=Sie haben eine neue Warnung erhalten
1043
Comment[el]=Σας στάλθηκε μια νέα ειδοποίηση
1044
Comment[es]=Se le ha enviado una nueva alerta
1045
Comment[et]=Sulle saadeti uus teade
1046
Comment[fa]=هشدار جدیدی برای شما ارسال شده است
1047
Comment[fi]=Sinulle on lähetetty uusi varoitus
1048
Comment[fr]=Une nouvelle alerte vous a été envoyée
1049
Comment[he]=אזהרה חדשה נשלחה אליך
1050
Comment[hu]=Új értesítőt küldtek Önnek
1051
Comment[is]=Þér hefur verið sent nýtt skeyti
1052
Comment[it]=Ti è stato inviato un avviso
1053
Comment[ja]=新しいアラートを受信しました
1054
Comment[km]=បានផ្ញើ​សេចក្ដី​ជូន​ដំណឹង​ទៅឲ្យអ្នក
1055
Comment[lt]=Jums pasiųstas naujas „dėmesio!“ signalas
1056
Comment[nb]=En ny varsling er sendt til deg
1057
Comment[nds]=Een hett Di en niegen Alarm sendt
1058
Comment[ne]=तपाईँलाई एउटा नयाँ सावधानी सन्देश पठाएको छ
1059
Comment[nl]=U hebt een nieuwe melding ontvangen
1060
Comment[pl]=Nowy alarm został wysłany do Ciebie
1061
Comment[pt]=Foi enviada um novo alerta
1062
Comment[pt_BR]=Um novo alerta foi enviado para você
1063
Comment[ru]=Вам отправлено предупреждение
1064
Comment[sk]=Bolo vám poslané nové upozornenie
1065
Comment[sl]=Poslan vam je bil alarm
1066
Comment[sr]=Послат вам је нови аларм
1067
Comment[sr@Latn]=Poslat vam je novi alarm
1068
Comment[sv]=Ett nytt larm har skickats till dig
1069
Comment[tr]=Size yeni bir uyarı gönderildi
1070
Comment[uk]=Вам було відіслано новий сигнал
1071
Comment[zh_CN]=您收到了新提醒
1072
Comment[zh_TW]=一個新的警告已送達給您
1073
default_presentation=16
1074
1075
[msn_mail]
1076
Name=MSN Mail
1077
Name[ar]=بريد MSN
1078
Name[be]=Пошта MSN
1079
Name[bg]=Пристигна нова поща в MSN
1080
Name[bn]=এমএসএন মেইল
1081
Name[br]=Postel MSN
1082
Name[bs]=MSN mail
1083
Name[ca]=Correu de MSN
1084
Name[cs]=MSN pošta
1085
Name[da]=MSN-Mail
1086
Name[de]=MSN-Mail
1087
Name[es]=Correo MSN
1088
Name[fa]=نامۀ ام‌اس‌ان
1089
Name[fi]=MSN-sähköposti
1090
Name[fr]=Courriel MSN
1091
Name[gl]=Correo MSN
1092
Name[he]=דוא"ל של MSN
1093
Name[hi]=एमएसएन मेल
1094
Name[hr]=MSN pošta
1095
Name[hu]=MSN e-mail
1096
Name[is]=MSN póstur
1097
Name[it]=Posta MSN
1098
Name[ja]=MSN メール
1099
Name[ka]=MSN ფოსტა
1100
Name[kk]=MSN поштасы
1101
Name[km]=សំបុត្រ MSN
1102
Name[lt]=MSN Paštas
1103
Name[mk]=MSN-пошта
1104
Name[nb]=MSN e-post
1105
Name[nds]=MSN-Nettpost
1106
Name[ne]=एमएसएन मेल
1107
Name[nn]=MSN-e-post
1108
Name[pa]=MSN ਮੇਲ
1109
Name[pl]=Poczta MSN
1110
Name[pt]=E-mail MSN
1111
Name[ru]=Почта MSN
1112
Name[sl]=E-pošta MSN
1113
Name[sr]=MSN пошта
1114
Name[sr@Latn]=MSN pošta
1115
Name[sv]=MSN e-post
1116
Name[ta]=MSN மின்னஞ்சல்
1117
Name[tg]=Пости MSN
1118
Name[tr]=MSN Posta
1119
Name[uk]=Пошта MSN
1120
Name[zh_CN]=MSN 邮件
1121
Comment=New email has arrived in your MSN inbox
1122
Comment[be]=У вашай электроннай скрыні MSN новая пошта
1123
Comment[bg]=Пристигна нова поща в MSN
1124
Comment[bn]=আপনার এমএসএন ইনবক্সে নতুন ই-মেইল উপস্থিত হয়েছে
1125
Comment[br]=Deuet eo ur postel nevez d'em voest degemer MSN
1126
Comment[bs]=Stigla je nova pošta u vaš MSN sandučić
1127
Comment[ca]=Ha arribat un nou correu a la vostra bústia de MSN
1128
Comment[cs]=Přišla nová pošta do vaší MSN schránky
1129
Comment[da]=Ny e-mail ankom til din MSN-indbakke
1130
Comment[de]=Eine neue Nachricht befindet sich im MSN-Eingangsordner
1131
Comment[el]=Μόλις έφτασε νέο e-mail στα εισερχόμενα του MSN σας
1132
Comment[eo]=Nova poŝto ricevita
1133
Comment[es]=Tiene correo nuevo en la cuenta de MSN
1134
Comment[et]=Saabus uus kiri sinu MSN Inboxi
1135
Comment[eu]=E-posta berri bat jaso da zure MSN-ko sarrerako ontzian
1136
Comment[fa]=یک رایانامۀ جدید در دریافتی ام‌اس‌ان شما رسیده است
1137
Comment[fi]=Uutta postia saapunut MSN-sähköpostilaatikkoon
1138
Comment[fr]=Un nouveau message est arrivé dans votre boîte aux lettres MSN
1139
Comment[gl]=Unha nova mensaxe chegou ao teu cartafol de entrada de MSN
1140
Comment[he]=התקבל עבורך דואר חדש בתיבת הדוא"ל של MSN 
1141
Comment[hr]=Nova pošta je stigla u vaš MSN sandučić
1142
Comment[hu]=Új levél érkezett az MSN postaládába
1143
Comment[is]=Það er nýr póstur í MSN innhólfinu þínu
1144
Comment[it]=È arrivata nuova posta nella tua casella MSN
1145
Comment[ja]=MSN の受信箱に新しいメールが届きました
1146
Comment[ka]=ახალი ელფოსტა მოვიდა MSN საფოსტო ყუთში
1147
Comment[kk]=MSN пошта жәшігне хабарлама келді
1148
Comment[km]=អ៊ីមែល​ថ្មី​បាន​មក​ដល់​ក្នុង​ប្រអប់​ទទួល MSN របស់​អ្នក​​ហើយ
1149
Comment[lt]=Į MSN pašto dėžutę gautas naujas laiškas
1150
Comment[mk]=Пристигна нова пошта во вашето MSN-сандаче
1151
Comment[nb]=Ny e-post er ankommet i MSN-innboksen
1152
Comment[nds]=Du hest niege Nettpost in Dien MSN-Postingang
1153
Comment[ne]=तपाईँको एमएसएन पत्रमञ्जूषामा नयाँ इमेल छ
1154
Comment[nl]=Er is een nieuwe e-mail aangekomen in uw MSN-inbox
1155
Comment[nn]=Ny e-post er komen til MSN-innboksen
1156
Comment[pl]=Nadeszła nowa wiadomość do Twojej skrzynki odbiorczej w MSN
1157
Comment[pt]=Chegou uma mensagem nova à sua caixa de correio do MSN
1158
Comment[pt_BR]=chegou um novo e-mail em sua caixa de entrada MSN
1159
Comment[ru]=Пришли новые письма в MSN
1160
Comment[se]=Ođđa e-boasta lea boahtán du MSN-boastaboksii
1161
Comment[sk]=Do vašej schránky MSN prišla nová správa
1162
Comment[sl]=Nova e-pošta je prispela v vaš nabiralnik MSN
1163
Comment[sr]=Нова порука је стигла у ваше MSN сандуче
1164
Comment[sr@Latn]=Nova poruka je stigla u vaše MSN sanduče
1165
Comment[sv]=Ett nytt brev har anlänt i din MSN-inkorg
1166
Comment[ta]=உங்கள் எம்எஸ்என் அஞ்சல் பெட்டிக்கு புதிய மின்னஞ்சல் வந்துள்ளது
1167
Comment[tg]=Ба қутии пости MSN-и шумо пайёми электронии нав омад
1168
Comment[tr]=MSN gelen kutunuza yeni bir e-posta geldi
1169
Comment[uk]=Прийшли нові листи у вашу скриньку MSN
1170
Comment[zh_CN]=您的 MSN 收件箱中有新邮件到达
1171
Comment[zh_HK]=您的 MSN 收件匣有新郵件
1172
Comment[zh_TW]=新郵件送達您的 MSN 收件匣
1173
default_presentation=16
1174
1175
[icq_authorization]
1000
[icq_authorization]
1176
Name=ICQ Authorization
1001
Name=ICQ Authorization
1177
Name[be]=Спраўджванне асобы ICQ
1002
Name[be]=Спраўджванне асобы ICQ
(-)tdenetwork.ori/kopete/kopete/kimiface.h (-2 / +2 lines)
Lines 107-113 Link Here
107
	 * Get the KABC uid corresponding to the supplied IM address
107
	 * Get the KABC uid corresponding to the supplied IM address
108
	 * Protocols should be 
108
	 * Protocols should be 
109
	 * @param contactId the protocol specific identifier for the contact, eg UIN for ICQ, screenname for AIM, nick for IRC.
109
	 * @param contactId the protocol specific identifier for the contact, eg UIN for ICQ, screenname for AIM, nick for IRC.
110
	 * @param protocol the protocol, eg one of "AIMProtocol", "MSNProtocol", "ICTQProtocol", 
110
	 * @param protocol the protocol, eg one of "AIMProtocol", "ICTQProtocol", 
111
	 * @return a KABC uid or null if none found/
111
	 * @return a KABC uid or null if none found/
112
	 */
112
	 */
113
	virtual TQString locate( const TQString & contactId, const TQString & protocol ) = 0;
113
	virtual TQString locate( const TQString & contactId, const TQString & protocol ) = 0;
Lines 167-173 Link Here
167
	/**
167
	/**
168
	 * Add a contact to the contact list
168
	 * Add a contact to the contact list
169
	 * @param contactId the protocol specific identifier for the contact, eg UIN for ICQ, screenname for AIM, nick for IRC.
169
	 * @param contactId the protocol specific identifier for the contact, eg UIN for ICQ, screenname for AIM, nick for IRC.
170
	 * @param protocol the protocol, eg one of "AIMProtocol", "MSNProtocol", "ICTQProtocol", ...
170
	 * @param protocol the protocol, eg one of "AIMProtocol", "ICTQProtocol", ...
171
	 * @return whether the add succeeded.  False may signal already present, protocol not supported, or add operation not supported.
171
	 * @return whether the add succeeded.  False may signal already present, protocol not supported, or add operation not supported.
172
	 */
172
	 */
173
	virtual bool addContact( const TQString &contactId, const TQString &protocol ) = 0;
173
	virtual bool addContact( const TQString &contactId, const TQString &protocol ) = 0;
(-)tdenetwork.ori/kopete/kopete/kopeteiface.h (-2 / +2 lines)
Lines 105-117 Link Here
105
105
106
	/**
106
	/**
107
	 * load a plugin
107
	 * load a plugin
108
	 * the name is the name of the library: example: kopete_msn
108
	 * the name is the name of the library: example: kopete_icq
109
	 * but you can ommit the kopete_ prefix
109
	 * but you can ommit the kopete_ prefix
110
	 */
110
	 */
111
	bool loadPlugin( const TQString& name );
111
	bool loadPlugin( const TQString& name );
112
	/**
112
	/**
113
	 * unload a plugin
113
	 * unload a plugin
114
	 * the name is the name of the library: example: kopete_msn
114
	 * the name is the name of the library: example: kopete_icq
115
	 * but you can ommit the kopete_ prefix
115
	 * but you can ommit the kopete_ prefix
116
	 */
116
	 */
117
	bool unloadPlugin( const TQString& name );
117
	bool unloadPlugin( const TQString& name );
(-)tdenetwork.ori/kopete/kopete/tdeconf_update/kopete-account-tdeconf_update.cpp (-16 / +2 lines)
Lines 55-61 Link Here
55
{
55
{
56
	// Groups that are converted can almost certainly be removed entirely
56
	// Groups that are converted can almost certainly be removed entirely
57
57
58
	if ( group == "MSN" || group == "ICQ" || group == "Oscar" || group == "Gadu" || group == "Jabber" || group == "IRC" )
58
	if ( group == "ICQ" || group == "Oscar" || group == "Gadu" || group == "Jabber" || group == "IRC" )
59
	{
59
	{
60
		accountId = "EMPTY";
60
		accountId = "EMPTY";
61
		autoConnect = "true";
61
		autoConnect = "true";
Lines 82-102 Link Here
82
void parseKey( const TQString &group, const TQString &key, const TQString &value, const TQString &rawLine )
82
void parseKey( const TQString &group, const TQString &key, const TQString &value, const TQString &rawLine )
83
{
83
{
84
	//qcerr << "*** group='" << group << "'" << endl;
84
	//qcerr << "*** group='" << group << "'" << endl;
85
	if ( group == "MSN" )
85
	if ( group == "ICQ" )
86
	{
87
		if ( key == "UserID" )
88
			accountId = value;
89
		else if ( key == "Password" )
90
			password = value;
91
		else if ( key == "AutoConnect" )
92
			autoConnect = value;
93
		else if ( key == "Nick" )
94
			pluginData[ "displayName" ] = value;
95
96
		// All other keys are ignored for MSN, as these apply to stuff that's
97
		// now in libkopete (and the main app) instead.
98
	}
99
	else if ( group == "ICQ" )
100
	{
86
	{
101
		if ( key == "UIN" )
87
		if ( key == "UIN" )
102
			accountId = value;
88
			accountId = value;
(-)tdenetwork.ori/kopete/libkopete/API-TODO (-2 / +1 lines)
Lines 85-92 Link Here
85
85
86
Allow emoticons and emoticon sets to be flagged as being for only a specific protocol.
86
Allow emoticons and emoticon sets to be flagged as being for only a specific protocol.
87
Allow the user to have more than one emoticon set enabled at once, and to set priorities.
87
Allow the user to have more than one emoticon set enabled at once, and to set priorities.
88
This way, the user will be able to have a base theme, a set of MSN-specific emoticons, a
88
This way, the user will be able to have a base theme, a set of Gadu-Gadu-specific emoticons and so on.
89
set of Gadu-Gadu-specific emoticons and so on.
90
89
91
Possibly move emoticon support into a plugin?
90
Possibly move emoticon support into a plugin?
92
91
(-)tdenetwork.ori/kopete/libkopete/kopeteawaydialog.h (-1 / +1 lines)
Lines 128-134 Link Here
128
	 * Shows the away dialog, but maintains a "state"
128
	 * Shows the away dialog, but maintains a "state"
129
	 * so you can specify if you're setting away,
129
	 * so you can specify if you're setting away,
130
	 * do not disturb, gone, etc for protocols that
130
	 * do not disturb, gone, etc for protocols that
131
	 * support this like ICQ and MSN.
131
	 * support this like ICQ.
132
	 *
132
	 *
133
	 * This string does not have any special internal
133
	 * This string does not have any special internal
134
	 * meaning, but rather will get passed to setAway()
134
	 * meaning, but rather will get passed to setAway()
(-)tdenetwork.ori/kopete/libkopete/kopetecontact.h (-3 / +3 lines)
Lines 79-85 Link Here
79
	 * Across those boundaries ids may occur multiple times.
79
	 * Across those boundaries ids may occur multiple times.
80
	 * The id is solely for comparing items safely (using pointers is
80
	 * The id is solely for comparing items safely (using pointers is
81
	 * more crash-prone). DO NOT assume anything regarding the id's
81
	 * more crash-prone). DO NOT assume anything regarding the id's
82
	 * value! Even if it may look like an ICQ UIN or an MSN passport,
82
	 * value! Even if it may look like an ICQ UIN,
83
	 * this is undefined and may change at any time!
83
	 * this is undefined and may change at any time!
84
	 *
84
	 *
85
	 * @param account is the parent account. this constructor automatically register the contact to the account
85
	 * @param account is the parent account. this constructor automatically register the contact to the account
Lines 106-112 Link Here
106
	 * Across those boundaries ids may occur multiple times.
106
	 * Across those boundaries ids may occur multiple times.
107
	 * The id is solely for comparing items safely (using pointers is
107
	 * The id is solely for comparing items safely (using pointers is
108
	 * more crash-prone). DO NOT assume anything regarding the id's
108
	 * more crash-prone). DO NOT assume anything regarding the id's
109
	 * value! Even if it may look like an ICQ UIN or an MSN passport,
109
	 * value! Even if it may look like an ICQ UIN,
110
	 * this is undefined and may change at any time!
110
	 * this is undefined and may change at any time!
111
	 *
111
	 *
112
	 * @return The unique id of the contact
112
	 * @return The unique id of the contact
Lines 274-280 Link Here
274
	/**
274
	/**
275
	 * Returns the primary message manager affiliated with this contact
275
	 * Returns the primary message manager affiliated with this contact
276
	 * Although a contact can have more than one active message manager
276
	 * Although a contact can have more than one active message manager
277
	 * (as is the case with MSN at least), only one message manager will
277
	 * only one message manager will
278
	 * ever be the contacts "primary" message manager.. aka the 1 on 1 chat.
278
	 * ever be the contacts "primary" message manager.. aka the 1 on 1 chat.
279
	 * This function should always return that instance.
279
	 * This function should always return that instance.
280
	 *
280
	 *
(-)tdenetwork.ori/kopete/libkopete/kopetecontactlist.cpp (-22 / +5 lines)
Lines 358-368 Link Here
358
358
359
	emit globalIdentityChanged(Kopete::Global::Properties::self()->photo().key(), myself()->picture().path());
359
	emit globalIdentityChanged(Kopete::Global::Properties::self()->photo().key(), myself()->picture().path());
360
	mutex=false;
360
	mutex=false;
361
	/* The mutex is usefull to don't have such as stack overflow 
362
	Kopete::ContactList::slotPhotoChanged  ->  Kopete::ContactList::globalIdentityChanged  
363
	MSNAccount::slotGlobalIdentityChanged  ->  Kopete::Contact::propertyChanged 
364
	Kopete::MetaContact::slotPropertyChanged -> Kopete::MetaContact::photoChanged -> Kopete::ContactList::slotPhotoChanged 
365
	*/
366
}
361
}
367
362
368
///////////////////////////////////////////////////////////////////////////////////////////////
363
///////////////////////////////////////////////////////////////////////////////////////////////
Lines 522-528 Link Here
522
					{
517
					{
523
						// Convert address book fields.
518
						// Convert address book fields.
524
						// Jabber will be called "xmpp", Aim/Toc and Aim/Oscar both will
519
						// Jabber will be called "xmpp", Aim/Toc and Aim/Oscar both will
525
						// be called "aim". MSN, AIM, IRC, Oscar and SMS don't use address
520
						// be called "aim". AIM, IRC, Oscar and SMS don't use address
526
						// book fields yet; Gadu and ICQ can be converted as-is.
521
						// book fields yet; Gadu and ICQ can be converted as-is.
527
						// As Yahoo is unfinished we won't try to convert at all.
522
						// As Yahoo is unfinished we won't try to convert at all.
528
						TQString id   = oldContactElement.attribute( TQString::fromLatin1( "id" ), TQString() );
523
						TQString id   = oldContactElement.attribute( TQString::fromLatin1( "id" ), TQString() );
Lines 612-623 Link Here
612
							bool convertOldAim = false;
607
							bool convertOldAim = false;
613
							uint fieldCount = 1;
608
							uint fieldCount = 1;
614
							TQString addressBookLabel;
609
							TQString addressBookLabel;
615
							if( id == TQString::fromLatin1("MSNProtocol") )
610
							if( id == TQString::fromLatin1("IRCProtocol") )
616
							{
617
								fieldCount = 3;
618
								addressBookLabel = TQString::fromLatin1("msn");
619
							}
620
							else if( id == TQString::fromLatin1("IRCProtocol") )
621
							{
611
							{
622
								fieldCount = 3;
612
								fieldCount = 3;
623
								addressBookLabel = TQString::fromLatin1("irc");
613
								addressBookLabel = TQString::fromLatin1("irc");
Lines 657-663 Link Here
657
							}
647
							}
658
648
659
							// Do the actual conversion
649
							// Do the actual conversion
660
							if( id == TQString::fromLatin1( "MSNProtocol" ) || id == TQString::fromLatin1( "OscarProtocol" ) ||
650
							if ( id == TQString::fromLatin1( "OscarProtocol" ) ||
661
								id == TQString::fromLatin1( "AIMProtocol" ) || id == TQString::fromLatin1( "IRCProtocol" ) ||
651
								id == TQString::fromLatin1( "AIMProtocol" ) || id == TQString::fromLatin1( "IRCProtocol" ) ||
662
								id == TQString::fromLatin1( "ICTQProtocol" ) || id == TQString::fromLatin1( "JabberProtocol" ) ||
652
								id == TQString::fromLatin1( "ICTQProtocol" ) || id == TQString::fromLatin1( "JabberProtocol" ) ||
663
								id == TQString::fromLatin1( "SMSProtocol" ) || id == TQString::fromLatin1( "WPProtocol" ) ||
653
								id == TQString::fromLatin1( "SMSProtocol" ) || id == TQString::fromLatin1( "WPProtocol" ) ||
Lines 699-712 Link Here
699
									else
689
									else
700
										dataField.appendChild( newList.createTextNode( strList[ idx + 1 ] ) );
690
										dataField.appendChild( newList.createTextNode( strList[ idx + 1 ] ) );
701
691
702
									if( id == TQString::fromLatin1("MSNProtocol") )
692
									if( id == TQString::fromLatin1("IRCProtocol") )
703
									{
704
										dataField = newList.createElement( TQString::fromLatin1( "plugin-data-field" ) );
705
										pluginData[ id ].appendChild( dataField );
706
										dataField.setAttribute( TQString::fromLatin1( "key" ), TQString::fromLatin1( "groups" ) );
707
										dataField.appendChild( newList.createTextNode( strList[ idx + 2 ] ) );
708
									}
709
									else if( id == TQString::fromLatin1("IRCProtocol") )
710
									{
693
									{
711
										dataField = newList.createElement( TQString::fromLatin1( "plugin-data-field" ) );
694
										dataField = newList.createElement( TQString::fromLatin1( "plugin-data-field" ) );
712
										pluginData[ id ].appendChild( dataField );
695
										pluginData[ id ].appendChild( dataField );
Lines 742-748 Link Here
742
										idx += 2;
725
										idx += 2;
743
									}
726
									}
744
727
745
									// MSN, AIM, IRC, Oscar and SMS didn't store address book fields up
728
									// AIM, IRC, Oscar and SMS didn't store address book fields up
746
									// to now, so create one
729
									// to now, so create one
747
									if( id != TQString::fromLatin1("ICTQProtocol") && id != TQString::fromLatin1("JabberProtocol") && id != TQString::fromLatin1("WPProtocol") && id != TQString::fromLatin1("GaduProtocol") )
730
									if( id != TQString::fromLatin1("ICTQProtocol") && id != TQString::fromLatin1("JabberProtocol") && id != TQString::fromLatin1("WPProtocol") && id != TQString::fromLatin1("GaduProtocol") )
748
									{
731
									{
(-)tdenetwork.ori/kopete/libkopete/kopetemetacontact.h (-1 / +1 lines)
Lines 483-489 Link Here
483
	 *
483
	 *
484
	 * Like sendMessage, but this time a full-blown chat will be opened.
484
	 * Like sendMessage, but this time a full-blown chat will be opened.
485
	 * Most protocols can't distinguish between the two and are either
485
	 * Most protocols can't distinguish between the two and are either
486
	 * completely session based like MSN or completely message based like
486
	 * completely session based like ICQ or completely message based like
487
	 * ICQ the only true difference is the GUI shown to the user.
487
	 * ICQ the only true difference is the GUI shown to the user.
488
	 *
488
	 *
489
	 * returns the Contact that was chosen as the preferred
489
	 * returns the Contact that was chosen as the preferred
(-)tdenetwork.ori/kopete/libkopete/kopeteonlinestatus.h (-4 / +1 lines)
Lines 74-83 Link Here
74
		/**
74
		/**
75
		 * Refers to protocols where state cannot be determined. This
75
		 * Refers to protocols where state cannot be determined. This
76
		 * applies to SMS contacts (text messages via mobile phones),
76
		 * applies to SMS contacts (text messages via mobile phones),
77
		 * since there's no presence information over SMS, but also
77
		 * since there's no presence information over SMS. Lastly, libkopete
78
		 * to e.g. MSN contacts that are not on your contact list,
79
		 * since MSN only allows a user to query online state for
80
		 * users that are formally on the contact list. Lastly, libkopete
81
		 * itself uses the Unknown state in @ref MetaContact for
78
		 * itself uses the Unknown state in @ref MetaContact for
82
		 * meta contacts that have no child contacts at all.
79
		 * meta contacts that have no child contacts at all.
83
		 */
80
		 */
(-)tdenetwork.ori/kopete/plugins/CMakeLists.txt (-1 lines)
Lines 22-28 Link Here
22
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HIGHLIGHT highlight )
22
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HIGHLIGHT highlight )
23
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ALIAS alias )
23
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ALIAS alias )
24
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY motionautoaway )
24
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY motionautoaway )
25
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_NETMEETING netmeeting )
26
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS addbookmarks )
25
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS addbookmarks )
27
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_STATISTICS statistics )
26
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_STATISTICS statistics )
28
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_SMPPPDCS smpppdcs )
27
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_SMPPPDCS smpppdcs )
(-)tdenetwork.ori/kopete/plugins/history/converter.cpp (-10 / +2 lines)
Lines 68-80 Link Here
68
68
69
		if(accountId.isNull() || protocolId.isNull())
69
		if(accountId.isNull() || protocolId.isNull())
70
		{
70
		{
71
			if(fi->fileName() == "MSNProtocol" || fi->fileName() == "msn_logs" )
71
      if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
72
			{
73
				protocolId="MSNProtocol";
74
				TDEGlobal::config()->setGroup("MSN");
75
				accountId=TDEGlobal::config()->readEntry( "UserID" );
76
			}
77
			else if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
78
			{
72
			{
79
				protocolId="ICTQProtocol";
73
				protocolId="ICTQProtocol";
80
				TDEGlobal::config()->setGroup("ICQ");
74
				TDEGlobal::config()->setGroup("ICQ");
Lines 325-333 Link Here
325
		if( dynamic_cast<Kopete::Protocol *>( Kopete::PluginManager::self()->plugin( fi->fileName() ) ) )
319
		if( dynamic_cast<Kopete::Protocol *>( Kopete::PluginManager::self()->plugin( fi->fileName() ) ) )
326
			return true;
320
			return true;
327
321
328
		if(fi->fileName() == "MSNProtocol" || fi->fileName() == "msn_logs" )
322
    if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
329
			return true;
330
		else if(fi->fileName() == "ICTQProtocol" || fi->fileName() == "icq_logs" )
331
			return true;
323
			return true;
332
		else if(fi->fileName() == "AIMProtocol" || fi->fileName() == "aim_logs" )
324
		else if(fi->fileName() == "AIMProtocol" || fi->fileName() == "aim_logs" )
333
			return true;
325
			return true;
(-)tdenetwork.ori/kopete/plugins/latex/latexplugin.cpp (-4 lines)
Lines 178-184 Link Here
178
void LatexPlugin::slotMessageAboutToSend( Kopete::Message& msg)
178
void LatexPlugin::slotMessageAboutToSend( Kopete::Message& msg)
179
{
179
{
180
	Q_UNUSED(msg)
180
	Q_UNUSED(msg)
181
	//disabled because to work correctly, we need to find what special has the gif we can send over MSN
182
#if 0
181
#if 0
183
	TDEConfig *config = TDEGlobal::config();
182
	TDEConfig *config = TDEGlobal::config();
184
	config->setGroup("Latex Plugin");
183
	config->setGroup("Latex Plugin");
Lines 189-196 Link Here
189
	TQString messageText = msg.plainBody();
188
	TQString messageText = msg.plainBody();
190
	if( !messageText.contains("$$"))
189
	if( !messageText.contains("$$"))
191
		return;
190
		return;
192
/*	if( msg.from()->protocol()->pluginId()!="MSNProtocol" )
193
	return;*/
194
191
195
	// this searches for $$formula$$
192
	// this searches for $$formula$$
196
	TQRegExp rg("^\\s*\\$\\$([^$]+)\\$\\$\\s*$");
193
	TQRegExp rg("^\\s*\\$\\$([^$]+)\\$\\$\\s*$");
Lines 226-232 Link Here
226
			
223
			
227
	TQString argumentRes = "-r %1x%2";
224
	TQString argumentRes = "-r %1x%2";
228
	TQString argumentOut = "-o %1";
225
	TQString argumentOut = "-o %1";
229
	//TQString argumentFormat = "-fgif";  //we uses gif format because MSN only handle gif
230
	int hDPI, vDPI;
226
	int hDPI, vDPI;
231
	hDPI = LatexConfig::self()->horizontalDPI();
227
	hDPI = LatexConfig::self()->horizontalDPI();
232
	vDPI = LatexConfig::self()->verticalDPI();
228
	vDPI = LatexConfig::self()->verticalDPI();
(-)tdenetwork.ori/kopete/plugins/Makefile.am (-1 / +1 lines)
Lines 8-12 Link Here
8
8
9
SUBDIRS = latex autoreplace history contactnotes cryptography\
9
SUBDIRS = latex autoreplace history contactnotes cryptography\
10
	connectionstatus translator nowlistening webpresence texteffect\
10
	connectionstatus translator nowlistening webpresence texteffect\
11
	highlight alias $(MOTIONAUTOAWAY_SUBDIR) netmeeting addbookmarks\
11
	highlight alias $(MOTIONAUTOAWAY_SUBDIR) addbookmarks\
12
	statistics $(SMPPPDCS_SUBDIR) 
12
	statistics $(SMPPPDCS_SUBDIR) 
(-)tdenetwork.ori/kopete/plugins/netmeeting/CMakeLists.txt (-56 lines)
Lines 1-56 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
if( NOT BUILD_KOPETE_PROTOCOL_MSN )
13
  tde_message_fatal( "netmeeting plugin needs msn protocol.\n Add -DBUILD_KOPETE_PROTOCOL_MSN=ON to cmake flags." )
14
endif( )
15
16
include_directories(
17
  ${CMAKE_CURRENT_BINARY_DIR}
18
  ${CMAKE_BINARY_DIR}
19
  ${CMAKE_SOURCE_DIR}/kopete/libkopete
20
  ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
21
  ${CMAKE_SOURCE_DIR}/kopete/protocols/msn
22
  ${TDE_INCLUDE_DIR}
23
  ${TQT_INCLUDE_DIRS}
24
)
25
26
link_directories(
27
  ${TQT_LIBRARY_DIRS}
28
)
29
30
31
##### other data ################################
32
33
install( FILES kopete_netmeeting.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
34
install( FILES kopete_netmeeting_config.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tdeconfiguredialog )
35
install( FILES netmeetingchatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_netmeeting )
36
37
38
##### kopete_netmeeting (module) ################
39
40
tde_add_kpart( kopete_netmeeting AUTOMOC
41
  SOURCES
42
    netmeetingplugin.cpp netmeetinginvitation.cpp
43
    netmeetingguiclient.cpp
44
  LINK kopete_msn_shared-shared kopete-shared
45
  DESTINATION ${PLUGIN_INSTALL_DIR}
46
)
47
48
49
##### kcm_kopete_netmeeting (module) ############
50
51
tde_add_kpart( kcm_kopete_netmeeting AUTOMOC
52
  SOURCES
53
    netmeetingprefs_ui.ui netmeetingpreferences.cpp
54
  LINK tdeutils-shared
55
  DESTINATION ${PLUGIN_INSTALL_DIR}
56
)
(-)tdenetwork.ori/kopete/plugins/netmeeting/kopete_netmeeting_config.desktop (-77 lines)
Lines 1-77 Link Here
1
[Desktop Entry]
2
Icon=highlight
3
Type=Service
4
ServiceTypes=TDECModule
5
6
X-TDE-ModuleType=Library
7
X-TDE-Library=kopete_netmeeting
8
X-TDE-FactoryName=NetmeetingConfigFactory
9
X-TDE-ParentApp=kopete_netmeeting
10
X-TDE-ParentComponents=kopete_netmeeting
11
12
Name=Netmeeting
13
Name[ar]=الاجتماع على الشبكة
14
Name[bg]=Видео чат
15
Name[bn]=নেট মিটিং
16
Name[da]=Netmøde
17
Name[eo]=Reta renkontiĝo
18
Name[fa]=نت میتینگ
19
Name[fr]=Vidéo-conférence
20
Name[hi]=नेटमीटिंग
21
Name[ja]=ネットミーティング
22
Name[km]=ប្រជុំ​លើ​បណ្ដាញ
23
Name[lt]=Bendravimas tinkle
24
Name[nds]=Nettmööt
25
Name[ne]=नेट मिटिङ
26
Name[nl]=NetMeeting
27
Name[pa]=ਨੈੱਟ-ਮੀਟਿੰਗ
28
Name[sv]=Nätverksmöte
29
Name[ta]=இணைய சந்திப்பு
30
Name[tg]=Вохӯриҳои шабакавӣ
31
Comment=Voice and Video with MSN Messenger
32
Comment[be]=Гук і відэа праз MSN Messenger
33
Comment[bg]=Приставка за разговор с глас и видео с MSN Messenger
34
Comment[bn]=এমএসএন বার্তাবাহকের সঙ্গে স্বর এবং ভিডিও
35
Comment[bs]=Glas i video sa MSN Messengerom
36
Comment[ca]=Veu i vídeo amb MSN Messenger
37
Comment[cs]=Hlas a video pomocí MSN Messenger
38
Comment[da]=Stemme og video med MSN Messenger
39
Comment[de]=Sprache und Video mit dem MSN-Messenger verwenden
40
Comment[el]=Βίντεο και εικόνα με το MSN Messenger
41
Comment[es]=Voz y vídeo con MSN Messenger
42
Comment[et]=Audio ja video kasutamine MSN Messengeriga
43
Comment[eu]=Ahotsa eta bideoa MSN Messenger-ekin
44
Comment[fa]=ویدیو و صدا با پیام‌رسان ام‌اس‌ان
45
Comment[fi]=Ääni ja videokuva MSN Messengerin kanssa
46
Comment[fr]=Voix et vidéo avec MSN Messenger
47
Comment[gl]=Voz e video con MSN Messenger
48
Comment[he]=חוזי ושמע עם MSN Messenger
49
Comment[hu]=Hang és videó az MSN Messengerrel
50
Comment[is]=Hljóð og vídeó með MSN Messenger
51
Comment[it]=Voce e video con MSN Messenger
52
Comment[ja]=MSN メッセンジャーとボイス/ビデオチャット
53
Comment[ka]=ხმა და ვიდეო MSN მესინჯერთან
54
Comment[kk]=MSN Messenger дыбыс пен бейнемен
55
Comment[km]=សំឡេង និង​វីដេអូ​ដោយ​ប្រើ​កម្មវិធី​ផ្ញើ​សារ MSN
56
Comment[lt]=Bendravimas balsu ir vaizdu per MSN Messenger
57
Comment[mk]=Глас и видео со Гласникот на MSN
58
Comment[nb]=Lyd og bilde med MSN Messenger
59
Comment[nds]=Spraak un Video mit dat MSN-Kortnarichtenprogramm
60
Comment[ne]=एमएसएन मेसेन्जरसँग आवाज र भिडियो
61
Comment[nl]=Beeld en geluid met MSN Messenger
62
Comment[nn]=Lyd og bilete med MSN Messenger
63
Comment[pl]=Głos i wideo za pomocą MSN Messenger
64
Comment[pt]=Voz e Vídeo com o MSN Messenger
65
Comment[pt_BR]=Voz e Vídeo com o MSN Messenger
66
Comment[ru]=Аудио и видео с MSN Messenger
67
Comment[sk]=Hlas a video pomocou MSN Messenger
68
Comment[sl]=Glas in video z MSN Messenger
69
Comment[sr]=Глас и видео са MSN Messenger-ом
70
Comment[sr@Latn]=Glas i video sa MSN Messenger-om
71
Comment[sv]=Ljud och video med MSN Messenger
72
Comment[ta]=எம்எஸ்என் செய்தியில் குரல் மற்றும் படக்காட்சி
73
Comment[tr]=MSN Messenger ile Video ve Ses
74
Comment[uk]=Аудіо і відео з MSN Messenger
75
Comment[zh_CN]=与 MSN Messenger 一起使用影音
76
Comment[zh_HK]=和 MSN Messenger 一起使用語音和視像
77
Comment[zh_TW]=MSN Messenger 影像與聲音
(-)tdenetwork.ori/kopete/plugins/netmeeting/kopete_netmeeting.desktop (-81 lines)
Lines 1-81 Link Here
1
[Desktop Entry]
2
Type=Service
3
X-Kopete-Version=1000900
4
Icon=phone
5
ServiceTypes=Kopete/Plugin
6
X-TDE-Library=kopete_netmeeting
7
X-TDE-PluginInfo-Author=Olivier Goffart
8
X-TDE-PluginInfo-Email=ogoffart@tiscalinet.be
9
X-TDE-PluginInfo-Name=kopete_netmeeting
10
X-TDE-PluginInfo-Version=0.8.0
11
X-TDE-PluginInfo-Website=http://kopete.kde.org
12
X-TDE-PluginInfo-Category=Plugins
13
X-TDE-PluginInfo-Depends=kopete_msn
14
X-TDE-PluginInfo-License=GPL
15
X-TDE-PluginInfo-EnabledByDefault=false
16
Name=Netmeeting
17
Name[ar]=الاجتماع على الشبكة
18
Name[bg]=Видео чат
19
Name[bn]=নেট মিটিং
20
Name[da]=Netmøde
21
Name[eo]=Reta renkontiĝo
22
Name[fa]=نت میتینگ
23
Name[fr]=Vidéo-conférence
24
Name[hi]=नेटमीटिंग
25
Name[ja]=ネットミーティング
26
Name[km]=ប្រជុំ​លើ​បណ្ដាញ
27
Name[lt]=Bendravimas tinkle
28
Name[nds]=Nettmööt
29
Name[ne]=नेट मिटिङ
30
Name[nl]=NetMeeting
31
Name[pa]=ਨੈੱਟ-ਮੀਟਿੰਗ
32
Name[sv]=Nätverksmöte
33
Name[ta]=இணைய சந்திப்பு
34
Name[tg]=Вохӯриҳои шабакавӣ
35
Comment=Voice and Video with MSN Messenger
36
Comment[be]=Гук і відэа праз MSN Messenger
37
Comment[bg]=Приставка за разговор с глас и видео с MSN Messenger
38
Comment[bn]=এমএসএন বার্তাবাহকের সঙ্গে স্বর এবং ভিডিও
39
Comment[bs]=Glas i video sa MSN Messengerom
40
Comment[ca]=Veu i vídeo amb MSN Messenger
41
Comment[cs]=Hlas a video pomocí MSN Messenger
42
Comment[da]=Stemme og video med MSN Messenger
43
Comment[de]=Sprache und Video mit dem MSN-Messenger verwenden
44
Comment[el]=Βίντεο και εικόνα με το MSN Messenger
45
Comment[es]=Voz y vídeo con MSN Messenger
46
Comment[et]=Audio ja video kasutamine MSN Messengeriga
47
Comment[eu]=Ahotsa eta bideoa MSN Messenger-ekin
48
Comment[fa]=ویدیو و صدا با پیام‌رسان ام‌اس‌ان
49
Comment[fi]=Ääni ja videokuva MSN Messengerin kanssa
50
Comment[fr]=Voix et vidéo avec MSN Messenger
51
Comment[gl]=Voz e video con MSN Messenger
52
Comment[he]=חוזי ושמע עם MSN Messenger
53
Comment[hu]=Hang és videó az MSN Messengerrel
54
Comment[is]=Hljóð og vídeó með MSN Messenger
55
Comment[it]=Voce e video con MSN Messenger
56
Comment[ja]=MSN メッセンジャーとボイス/ビデオチャット
57
Comment[ka]=ხმა და ვიდეო MSN მესინჯერთან
58
Comment[kk]=MSN Messenger дыбыс пен бейнемен
59
Comment[km]=សំឡេង និង​វីដេអូ​ដោយ​ប្រើ​កម្មវិធី​ផ្ញើ​សារ MSN
60
Comment[lt]=Bendravimas balsu ir vaizdu per MSN Messenger
61
Comment[mk]=Глас и видео со Гласникот на MSN
62
Comment[nb]=Lyd og bilde med MSN Messenger
63
Comment[nds]=Spraak un Video mit dat MSN-Kortnarichtenprogramm
64
Comment[ne]=एमएसएन मेसेन्जरसँग आवाज र भिडियो
65
Comment[nl]=Beeld en geluid met MSN Messenger
66
Comment[nn]=Lyd og bilete med MSN Messenger
67
Comment[pl]=Głos i wideo za pomocą MSN Messenger
68
Comment[pt]=Voz e Vídeo com o MSN Messenger
69
Comment[pt_BR]=Voz e Vídeo com o MSN Messenger
70
Comment[ru]=Аудио и видео с MSN Messenger
71
Comment[sk]=Hlas a video pomocou MSN Messenger
72
Comment[sl]=Glas in video z MSN Messenger
73
Comment[sr]=Глас и видео са MSN Messenger-ом
74
Comment[sr@Latn]=Glas i video sa MSN Messenger-om
75
Comment[sv]=Ljud och video med MSN Messenger
76
Comment[ta]=எம்எஸ்என் செய்தியில் குரல் மற்றும் படக்காட்சி
77
Comment[tr]=MSN Messenger ile Video ve Ses
78
Comment[uk]=Аудіо і відео з MSN Messenger
79
Comment[zh_CN]=与 MSN Messenger 一起使用影音
80
Comment[zh_HK]=和 MSN Messenger 一起使用語音和視像
81
Comment[zh_TW]=MSN Messenger 影像與聲音
(-)tdenetwork.ori/kopete/plugins/netmeeting/Makefile.am (-23 lines)
Lines 1-23 Link Here
1
METASOURCES = AUTO
2
3
AM_CPPFLAGS = $(KOPETE_INCLUDES) -I$(top_srcdir)/kopete/protocols/msn $(all_includes)
4
5
kde_module_LTLIBRARIES = kopete_netmeeting.la kcm_kopete_netmeeting.la
6
7
kopete_netmeeting_la_SOURCES     = netmeetingplugin.cpp netmeetinginvitation.cpp netmeetingguiclient.cpp
8
kopete_netmeeting_la_LDFLAGS     = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
9
kopete_netmeeting_la_LIBADD      = $(top_builddir)/kopete/libkopete/libkopete.la $(top_builddir)/kopete/protocols/msn/libkopete_msn_shared.la
10
11
service_DATA = kopete_netmeeting.desktop
12
servicedir = $(kde_servicesdir)
13
14
mydatadir = $(kde_datadir)/kopete_netmeeting
15
mydata_DATA = netmeetingchatui.rc
16
17
kcm_kopete_netmeeting_la_SOURCES = netmeetingprefs_ui.ui netmeetingpreferences.cpp
18
kcm_kopete_netmeeting_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
19
kcm_kopete_netmeeting_la_LIBADD  = $(LIB_KOPETECOMPAT) $(LIB_TDEUTILS)
20
21
22
kcm_DATA = kopete_netmeeting_config.desktop
23
kcmdir = $(kde_servicesdir)/tdeconfiguredialog
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingchatui.rc (-9 lines)
Lines 1-9 Link Here
1
<!DOCTYPE kpartgui>
2
<kpartgui version="1" name="kopete_msn_netmeeting">
3
	<MenuBar>
4
		<Menu name="tools">
5
			<text>&amp;Tools</text>
6
			<Action name="netmeeting" />
7
		</Menu>
8
	</MenuBar>
9
</kpartgui>
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingguiclient.cpp (-61 lines)
Lines 1-61 Link Here
1
/*
2
    netmeetingguiclient.cpp
3
4
    Kopete NetMeeting plugin
5
6
    Copyright (c) 2003-2004 by Olivier Goffart <ogoffart @ kde.org>
7
8
    Kopete    (c) 2003-2004 by the Kopete developers  <kopete-devel@kde.org>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#include <tqvariant.h>
21
22
#include <kdebug.h>
23
#include <tdeaction.h>
24
#include <tdelocale.h>
25
#include <kgenericfactory.h>
26
27
#include "msnchatsession.h"
28
#include "msncontact.h"
29
30
#include "netmeetingguiclient.h"
31
#include "netmeetinginvitation.h"
32
33
class NetMeetingPlugin;
34
35
NetMeetingGUIClient::NetMeetingGUIClient( MSNChatSession *parent,  const char *name )
36
: TQObject( parent, name ) , KXMLGUIClient(parent)
37
{
38
	setInstance(KGenericFactory<NetMeetingPlugin>::instance());
39
	m_manager=parent;
40
41
	new TDEAction( i18n( "Invite to Use NetMeeting" ), 0, this, TQT_SLOT( slotStartInvitation() ), actionCollection() , "netmeeting" ) ;
42
43
	setXMLFile("netmeetingchatui.rc");
44
}
45
46
NetMeetingGUIClient::~NetMeetingGUIClient()
47
{
48
49
}
50
51
void NetMeetingGUIClient::slotStartInvitation()
52
{
53
	TQPtrList<Kopete::Contact> c=m_manager->members();
54
	NetMeetingInvitation *i=new NetMeetingInvitation(false, static_cast<MSNContact*>(c.first()),m_manager);
55
	m_manager->initInvitation(i);
56
}
57
58
#include "netmeetingguiclient.moc"
59
60
// vim: set noet ts=4 sts=4 sw=4:
61
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingguiclient.h (-61 lines)
Lines 1-61 Link Here
1
/*
2
    netmeetingguiclient.h
3
4
    Kopete NetMeeting Plugin
5
6
    Copyright (c) 2003 by Olivier Goffart <ogoffart @ kde.org>
7
8
    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#ifndef TRANSLATORGUICLIENT_H
21
#define TRANSLATORGUICLIENT_H
22
23
#include <tqobject.h>
24
#include <kxmlguiclient.h>
25
26
namespace Kopete { class ChatSession; }
27
class MSNChatSession;
28
class NetMeetingPlugin;
29
30
/**
31
  * @author Olivier Goffart <ogoffart @ kde.org>
32
  */
33
34
class NetMeetingGUIClient : public TQObject , public KXMLGUIClient
35
{
36
	Q_OBJECT
37
  
38
39
public:
40
	NetMeetingGUIClient( MSNChatSession *parent, const char *name=0L);
41
	~NetMeetingGUIClient();
42
43
private slots:
44
	void slotStartInvitation();
45
46
private:
47
	MSNChatSession *m_manager;
48
	NetMeetingPlugin *m_plugin;
49
};
50
51
#endif
52
53
/*
54
 * Local variables:
55
 * c-indentation-style: k&r
56
 * c-basic-offset: 8
57
 * indent-tabs-mode: t
58
 * End:
59
 */
60
// vim: set noet ts=4 sts=4 sw=4:
61
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetinginvitation.cpp (-183 lines)
Lines 1-183 Link Here
1
/*
2
    msninvitation.cpp
3
4
    Copyright (c) 2003 by Olivier Goffart        <ogoffart @ kde.org>
5
6
    *************************************************************************
7
    *                                                                       *
8
    * This program is free software; you can redistribute it and/or modify  *
9
    * it under the terms of the GNU General Public License as published by  *
10
    * the Free Software Foundation; either version 2 of the License, or     *
11
    * (at your option) any later version.                                   *
12
    *                                                                       *
13
    *************************************************************************
14
*/
15
16
#include "netmeetinginvitation.h"
17
18
#include "kopeteuiglobal.h"
19
20
#include "msnchatsession.h"
21
#include "msnswitchboardsocket.h"
22
#include "msncontact.h"
23
#include "kopetemetacontact.h"
24
25
#include <tdelocale.h>
26
#include <tdemessagebox.h>
27
#include <kdebug.h>
28
#include <tdeconfig.h>
29
#include <tdeglobal.h>
30
31
32
#include <tqtimer.h>
33
#include <kprocess.h>
34
35
NetMeetingInvitation::NetMeetingInvitation(bool incoming, MSNContact *c, TQObject *parent)
36
 : TQObject(parent) , MSNInvitation( incoming, NetMeetingInvitation::applicationID() , i18n("NetMeeting") )
37
{
38
	m_contact=c;
39
	oki=false;
40
}
41
42
43
NetMeetingInvitation::~NetMeetingInvitation()
44
{
45
}
46
47
48
TQString NetMeetingInvitation::invitationHead()
49
{
50
	TQTimer::singleShot( 10*60000, this, TQT_SLOT( slotTimeout() ) ); //send TIMEOUT in 10 minute if the invitation has not been accepted/refused
51
	return TQString( MSNInvitation::invitationHead()+
52
				"Session-Protocol: SM1\r\n"
53
  				"Session-ID: {6672F94C-45BF-11D7-B4AE-00010A1008DF}\r\n" //FIXME i don't know what is the session id
54
				"\r\n").utf8();
55
}
56
57
void NetMeetingInvitation::parseInvitation(const TQString& msg)
58
{
59
	TQRegExp rx("Invitation-Command: ([A-Z]*)");
60
	rx.search(msg);
61
	TQString command=rx.cap(1);
62
	if( msg.contains("Invitation-Command: INVITE") )
63
	{
64
		MSNInvitation::parseInvitation(msg); //for the cookie
65
66
		unsigned int result = KMessageBox::questionYesNo( Kopete::UI::Global::mainWidget(),
67
					i18n("%1 wants to start a chat with NetMeeting; do you want to accept it? " ).arg(m_contact->metaContact()->displayName()),
68
					i18n("MSN Plugin") , i18n("Accept"),i18n("Refuse"));
69
70
		MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
71
72
		if(manager && manager->service())
73
		{
74
			if(result==3) // Yes == 3
75
			{
76
				TQCString message=TQString(
77
					"MIME-Version: 1.0\r\n"
78
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
79
					"\r\n"
80
					"Invitation-Command: ACCEPT\r\n"
81
					"Invitation-Cookie: " + TQString::number(cookie()) + "\r\n"
82
					"Session-ID: {6672F94C-45BF-11D7-B4AE-00010A1008DF}\r\n" //FIXME
83
					"Session-Protocol: SM1\r\n"
84
					"Launch-Application: TRUE\r\n"
85
					"Request-Data: IP-Address:\r\n"
86
					"IP-Address: " + manager->service()->getLocalIP()+ "\r\n"
87
					"\r\n" ).utf8();
88
89
90
				manager->service()->sendCommand( "MSG" , "N", true, message );
91
				oki=false;
92
				TQTimer::singleShot( 10* 60000, this, TQT_SLOT( slotTimeout() ) ); //TIMOUT afte 10 min
93
			}
94
			else //No
95
			{
96
				manager->service()->sendCommand( "MSG" , "N", true, rejectMessage() );
97
				emit done(this);
98
			}
99
		}
100
	}
101
	else if( msg.contains("Invitation-Command: ACCEPT") )
102
	{
103
		if( ! incoming() )
104
		{
105
			MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
106
			if(manager && manager->service())
107
			{
108
				TQCString message=TQString(
109
					"MIME-Version: 1.0\r\n"
110
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
111
					"\r\n"
112
					"Invitation-Command: ACCEPT\r\n"
113
					"Invitation-Cookie: " + TQString::number(cookie()) + "\r\n"
114
					"Session-ID: {6672F94C-45BF-11D7-B4AE-00010A1008DF}\r\n" //FIXME: what is session id?
115
					"Session-Protocol: SM1\r\n"
116
					"Launch-Application: TRUE\r\n"
117
					"Request-Data: IP-Address:\r\n"
118
					"IP-Address: " + manager->service()->getLocalIP() + "\r\n"
119
					"\r\n" ).utf8();
120
				manager->service()->sendCommand( "MSG" , "N", true, message );
121
			}
122
			rx=TQRegExp("IP-Address: ([0-9\\:\\.]*)");
123
			rx.search(msg);
124
			TQString ip_address = rx.cap(1);
125
	    	startMeeting(ip_address);
126
			kdDebug() << k_funcinfo << ip_address << endl;
127
		}
128
		else
129
		{
130
			rx=TQRegExp("IP-Address: ([0-9\\:\\.]*)");
131
			rx.search(msg);
132
			TQString ip_address = rx.cap(1);
133
134
			startMeeting(ip_address);
135
		}
136
	}
137
	else //CANCEL
138
	{
139
		emit done(this);
140
	}
141
}
142
143
void NetMeetingInvitation::slotTimeout()
144
{
145
	if(oki)
146
		return;
147
148
 	MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
149
150
	if(manager && manager->service())
151
	{
152
		manager->service()->sendCommand( "MSG" , "N", true, rejectMessage("TIMEOUT") );
153
	}
154
	emit done(this);
155
156
}
157
158
159
void NetMeetingInvitation::startMeeting(const TQString & ip_address)
160
{
161
	//TODO: use TDEProcess
162
	
163
	TDEConfig *config=TDEGlobal::config();
164
	config->setGroup("Netmeeting Plugin");
165
	TQString app=config->readEntry("NetmeetingApplication","ekiga -c callto://%1").arg(ip_address);
166
	
167
	kdDebug() << k_funcinfo << app <<  endl ;
168
	
169
	TQStringList args=TQStringList::split(" ", app);
170
	
171
	TDEProcess p;
172
	for(TQStringList::Iterator it=args.begin() ; it != args.end() ; ++it)
173
	{
174
		p << *it;
175
	}
176
	p.start();
177
}
178
179
#include "netmeetinginvitation.moc"
180
181
182
183
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetinginvitation.h (-57 lines)
Lines 1-57 Link Here
1
/*
2
    netmeetinginvitation.cpp
3
4
    Copyright (c) 2003 by Olivier Goffart        <ogoffart @ kde.org>
5
6
    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
#ifndef MSNVOICEINVITATION_H
18
#define MSNVOICEINVITATION_H
19
20
#include <tqobject.h>
21
#include "msninvitation.h"
22
23
class MSNContact;
24
25
/**
26
 *@author Olivier Goffart
27
 */
28
class NetMeetingInvitation : public TQObject , public MSNInvitation
29
{
30
Q_OBJECT
31
  
32
public:
33
	NetMeetingInvitation(bool incoming ,MSNContact*, TQObject *parent = 0);
34
	~NetMeetingInvitation();
35
36
	static TQString applicationID() { return "44BBA842-CC51-11CF-AAFA-00AA00B6015C"; }
37
	TQString invitationHead();
38
39
	virtual void parseInvitation(const TQString& invitation);
40
41
	virtual TQObject* object() { return this; }
42
43
signals:
44
	void done( MSNInvitation * );
45
46
private slots:
47
	void slotTimeout();
48
49
private:
50
	MSNContact *m_contact;
51
	bool oki;
52
	void startMeeting(const TQString & ip_address);
53
54
};
55
56
57
#endif
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingplugin.cpp (-91 lines)
Lines 1-91 Link Here
1
/*
2
    netmeetingplugin.cpp
3
4
    Copyright (c) 2003-2004 by Olivier Goffart <ogoffart @ kde.org>
5
6
    *************************************************************************
7
    *                                                                       *
8
    * This program is free software; you can redistribute it and/or modify  *
9
    * it under the terms of the GNU General Public License as published by  *
10
    * the Free Software Foundation; either version 2 of the License, or     *
11
    * (at your option) any later version.                                   *
12
    *                                                                       *
13
    *************************************************************************
14
*/
15
16
#include "netmeetingplugin.h"
17
18
#include <kdebug.h>
19
#include <kgenericfactory.h>
20
#include <tdeaction.h>
21
#include <tdeversion.h>
22
#include <tdeaboutdata.h>
23
24
#include "kopetepluginmanager.h"
25
#include "kopetechatsessionmanager.h"
26
27
#include "msnchatsession.h"
28
#include "msnprotocol.h"
29
#include "msncontact.h"
30
31
#include "netmeetinginvitation.h"
32
#include "netmeetingguiclient.h"
33
34
35
static const TDEAboutData aboutdata("kopete_netmeeting", I18N_NOOP("NetMeeting") , "1.0" );
36
K_EXPORT_COMPONENT_FACTORY( kopete_netmeeting, KGenericFactory<NetMeetingPlugin>( &aboutdata )  )
37
38
NetMeetingPlugin::NetMeetingPlugin( TQObject *parent, const char *name, const TQStringList &/*args*/ )
39
: Kopete::Plugin( TDEGlobal::instance(), parent, name )
40
{
41
	if(MSNProtocol::protocol())
42
		slotPluginLoaded(MSNProtocol::protocol());
43
	else
44
		connect(Kopete::PluginManager::self() , TQT_SIGNAL(pluginLoaded(Kopete::Plugin*) ), this, TQT_SLOT(slotPluginLoaded(Kopete::Plugin*)));
45
46
47
	connect( Kopete::ChatSessionManager::self(), TQT_SIGNAL( chatSessionCreated( Kopete::ChatSession * )) , TQT_SLOT( slotNewKMM( Kopete::ChatSession * ) ) );
48
	//Add GUI action to all already existing kmm (if the plugin is launched when kopete already rining)
49
	TQValueList<Kopete::ChatSession*> sessions = Kopete::ChatSessionManager::self()->sessions();
50
	for (TQValueListIterator<Kopete::ChatSession*> it= sessions.begin(); it!=sessions.end() ; ++it)
51
	{
52
		slotNewKMM(*it);
53
	}
54
}
55
56
NetMeetingPlugin::~NetMeetingPlugin()
57
{
58
59
}
60
61
void NetMeetingPlugin::slotPluginLoaded(Kopete::Plugin *p)
62
{
63
	if(p->pluginId()=="MSNProtocol")
64
	{
65
		connect( p , TQT_SIGNAL(invitation(MSNInvitation*& ,  const TQString & , long unsigned int , MSNChatSession*  , MSNContact* )) ,
66
			this, TQT_SLOT( slotInvitation(MSNInvitation*& ,  const TQString & , long unsigned int , MSNChatSession*  , MSNContact* )));
67
	}
68
}
69
70
void NetMeetingPlugin::slotNewKMM(Kopete::ChatSession *KMM)
71
{
72
	MSNChatSession *msnMM=dynamic_cast<MSNChatSession*>(KMM);
73
	if(msnMM)
74
	{
75
		connect(this , TQT_SIGNAL( destroyed(TQObject*)) ,
76
			new NetMeetingGUIClient(msnMM)
77
		 , TQT_SLOT(deleteLater()));
78
	}
79
}
80
81
82
void NetMeetingPlugin::slotInvitation(MSNInvitation*& invitation,  const TQString &bodyMSG , long unsigned int /*cookie*/ , MSNChatSession* msnMM , MSNContact* c )
83
{
84
	if(!invitation &&  bodyMSG.contains(NetMeetingInvitation::applicationID()))
85
	{
86
		invitation=new NetMeetingInvitation(true,c,msnMM);
87
		invitation->parseInvitation(bodyMSG);
88
	}
89
}
90
91
#include "netmeetingplugin.moc"
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingplugin.h (-47 lines)
Lines 1-47 Link Here
1
/*
2
    netmeetingplugin.h
3
4
    Copyright (c) 2003 by Olivier Goffart <ogoffart @ kde.org>
5
6
    *************************************************************************
7
    *                                                                       *
8
    * This program is free software; you can redistribute it and/or modify  *
9
    * it under the terms of the GNU General Public License as published by  *
10
    * the Free Software Foundation; either version 2 of the License, or     *
11
    * (at your option) any later version.                                   *
12
    *                                                                       *
13
    *************************************************************************
14
*/
15
16
17
18
#ifndef NetMeetingPLUGIN_H
19
#define NetMeetingPLUGIN_H
20
21
#include "kopeteplugin.h"
22
23
namespace Kopete { class ChatSession; }
24
class MSNChatSession;
25
class MSNContact;
26
class MSNInvitation;
27
28
29
class NetMeetingPlugin : public Kopete::Plugin
30
{
31
	Q_OBJECT
32
  
33
34
public:
35
	NetMeetingPlugin( TQObject *parent, const char *name, const TQStringList &args );
36
	~NetMeetingPlugin();
37
38
private slots:
39
	void slotNewKMM(Kopete::ChatSession *);
40
	void slotPluginLoaded(Kopete::Plugin*);
41
	void slotInvitation(MSNInvitation*& invitation,  const TQString &bodyMSG , long unsigned int cookie , MSNChatSession* msnMM , MSNContact* c );
42
43
44
};
45
46
#endif
47
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingpreferences.cpp (-81 lines)
Lines 1-81 Link Here
1
/***************************************************************************
2
                          Netmeetingpreferences.cpp  -  description
3
                             -------------------
4
    copyright            : (C) 2004 by Olivier Goffart
5
    email                : ogoffart @ kde.org
6
 ***************************************************************************/
7
8
/***************************************************************************
9
 *                                                                         *
10
 *   This program is free software; you can redistribute it and/or modify  *
11
 *   it under the terms of the GNU General Public License as published by  *
12
 *   the Free Software Foundation; either version 2 of the License, or     *
13
 *   (at your option) any later version.                                   *
14
 *                                                                         *
15
 ***************************************************************************/
16
17
#include <tqlayout.h>
18
#include <tqcheckbox.h>
19
20
#include <kcombobox.h>
21
#include <klineedit.h>
22
#include <tdeparts/componentfactory.h>
23
#include <tdelocale.h>
24
#include <tdeconfig.h>
25
#include <tdeglobal.h>
26
#include <kcombobox.h>
27
#include <tdelistview.h>
28
#include <kgenericfactory.h>
29
#include <kcolorbutton.h>
30
#include <kinputdialog.h>
31
#include <kurlrequester.h>
32
#include <kregexpeditorinterface.h>
33
#include <kdebug.h>
34
35
#include "netmeetingplugin.h"
36
#include "netmeetingprefs_ui.h"
37
#include "netmeetingpreferences.h"
38
39
typedef KGenericFactory<NetmeetingPreferences> NetmeetingPreferencesFactory;
40
K_EXPORT_COMPONENT_FACTORY( kcm_kopete_netmeeting, NetmeetingPreferencesFactory( "kcm_kopete_netmeeting" )  )
41
42
NetmeetingPreferences::NetmeetingPreferences(TQWidget *parent, const char* /*name*/, const TQStringList &args)
43
							: TDECModule(NetmeetingPreferencesFactory::instance(), parent, args)
44
{
45
	( new TQVBoxLayout( this ) )->setAutoAdd( true );
46
	preferencesDialog = new NetmeetingPrefsUI(this);
47
48
	connect(preferencesDialog->m_app , TQT_SIGNAL(textChanged(const TQString &)) , this , TQT_SLOT(slotChanged()));
49
50
	load();
51
}
52
53
NetmeetingPreferences::~NetmeetingPreferences()
54
{
55
}
56
57
void NetmeetingPreferences::load()
58
{
59
	TDEConfig *config=TDEGlobal::config();
60
	config->setGroup("Netmeeting Plugin");
61
	preferencesDialog->m_app->setCurrentText(config->readEntry("NetmeetingApplication","ekiga -c callto://%1"));
62
	emit TDECModule::changed(false);
63
}
64
65
void NetmeetingPreferences::save()
66
{
67
	TDEConfig *config=TDEGlobal::config();
68
	config->setGroup("Netmeeting Plugin");
69
	config->writeEntry("NetmeetingApplication",preferencesDialog->m_app->currentText());
70
	emit TDECModule::changed(false);
71
}
72
73
74
void NetmeetingPreferences::slotChanged()
75
{
76
	emit TDECModule::changed(true);
77
}
78
79
#include "netmeetingpreferences.moc"
80
81
// vim: set noet ts=4 sts=4 sw=4:
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingpreferences.h (-47 lines)
Lines 1-47 Link Here
1
/***************************************************************************
2
                          netmeetingpreferences.h  -  description
3
                             -------------------
4
    copyright            : (C) 2004 by Olivier Goffart
5
    email                : ogoffart @ kde.org
6
 ***************************************************************************/
7
8
/***************************************************************************
9
 *                                                                         *
10
 *   This program is free software; you can redistribute it and/or modify  *
11
 *   it under the terms of the GNU General Public License as published by  *
12
 *   the Free Software Foundation; either version 2 of the License, or     *
13
 *   (at your option) any later version.                                   *
14
 *                                                                         *
15
 ***************************************************************************/
16
17
#ifndef NetmeetingPREFERENCES_H
18
#define NetmeetingPREFERENCES_H
19
20
#include <tdecmodule.h>
21
#include <tqstring.h>
22
23
class NetmeetingPrefsUI;
24
25
/**
26
  *@author Olivier Goffart
27
  */
28
29
class NetmeetingPreferences : public TDECModule  {
30
   Q_OBJECT
31
  
32
public:
33
34
	NetmeetingPreferences(TQWidget *parent = 0, const char* name = 0, const TQStringList &args = TQStringList());
35
	~NetmeetingPreferences();
36
37
	virtual void save();
38
	virtual void load();
39
40
private:
41
	NetmeetingPrefsUI *preferencesDialog;
42
	
43
private slots:
44
	void slotChanged();
45
};
46
47
#endif
(-)tdenetwork.ori/kopete/plugins/netmeeting/netmeetingprefs_ui.ui (-148 lines)
Lines 1-148 Link Here
1
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
2
<class>NetmeetingPrefsUI</class>
3
<author>Olivier Goffart</author>
4
<widget class="TQWidget">
5
    <property name="name">
6
        <cstring>Form1</cstring>
7
    </property>
8
    <property name="geometry">
9
        <rect>
10
            <x>0</x>
11
            <y>0</y>
12
            <width>424</width>
13
            <height>297</height>
14
        </rect>
15
    </property>
16
    <vbox>
17
        <property name="name">
18
            <cstring>unnamed</cstring>
19
        </property>
20
        <widget class="TQLabel">
21
            <property name="name">
22
                <cstring>textLabel1</cstring>
23
            </property>
24
            <property name="text">
25
                <string>The NetMeeting Plugin allows you to start a video or voice chat with your MSN Messenger contacts.
26
27
This is not the same as webcam chat you can find in the newer Windows Messenger®,  but uses the older NetMeeting chat you can find in old versions.</string>
28
            </property>
29
            <property name="alignment">
30
                <set>WordBreak|AlignVCenter</set>
31
            </property>
32
        </widget>
33
        <widget class="Line">
34
            <property name="name">
35
                <cstring>line1</cstring>
36
            </property>
37
            <property name="frameShape">
38
                <enum>HLine</enum>
39
            </property>
40
            <property name="frameShadow">
41
                <enum>Sunken</enum>
42
            </property>
43
            <property name="orientation">
44
                <enum>Horizontal</enum>
45
            </property>
46
        </widget>
47
        <widget class="TQLayoutWidget">
48
            <property name="name">
49
                <cstring>layout1</cstring>
50
            </property>
51
            <hbox>
52
                <property name="name">
53
                    <cstring>unnamed</cstring>
54
                </property>
55
                <widget class="TQLabel">
56
                    <property name="name">
57
                        <cstring>textLabel2</cstring>
58
                    </property>
59
                    <property name="text">
60
                        <string>Application to launch:</string>
61
                    </property>
62
                </widget>
63
                <widget class="KComboBox">
64
                    <item>
65
                        <property name="text">
66
                            <string>ekiga -c callto://%1</string>
67
                        </property>
68
                    </item>
69
                    <item>
70
                        <property name="text">
71
                            <string>konference callto://%1</string>
72
                        </property>
73
                    </item>
74
                    <property name="name">
75
                        <cstring>m_app</cstring>
76
                    </property>
77
                    <property name="sizePolicy">
78
                        <sizepolicy>
79
                            <hsizetype>3</hsizetype>
80
                            <vsizetype>0</vsizetype>
81
                            <horstretch>0</horstretch>
82
                            <verstretch>0</verstretch>
83
                        </sizepolicy>
84
                    </property>
85
                    <property name="editable">
86
                        <bool>true</bool>
87
                    </property>
88
                    <property name="autoCompletion">
89
                        <bool>true</bool>
90
                    </property>
91
                </widget>
92
            </hbox>
93
        </widget>
94
        <widget class="TQLabel">
95
            <property name="name">
96
                <cstring>textLabel3</cstring>
97
            </property>
98
            <property name="text">
99
                <string>&lt;b&gt;%1&lt;/b&gt; will be replaced by the ip to call</string>
100
            </property>
101
            <property name="alignment">
102
                <set>WordBreak|AlignVCenter</set>
103
            </property>
104
        </widget>
105
        <spacer>
106
            <property name="name">
107
                <cstring>spacer1</cstring>
108
            </property>
109
            <property name="orientation">
110
                <enum>Vertical</enum>
111
            </property>
112
            <property name="sizeType">
113
                <enum>Expanding</enum>
114
            </property>
115
            <property name="sizeHint">
116
                <size>
117
                    <width>21</width>
118
                    <height>60</height>
119
                </size>
120
            </property>
121
        </spacer>
122
        <widget class="KActiveLabel">
123
            <property name="name">
124
                <cstring>kActiveLabel1</cstring>
125
            </property>
126
            <property name="sizePolicy">
127
                <sizepolicy>
128
                    <hsizetype>5</hsizetype>
129
                    <vsizetype>5</vsizetype>
130
                    <horstretch>0</horstretch>
131
                    <verstretch>0</verstretch>
132
                </sizepolicy>
133
            </property>
134
            <property name="text">
135
                <string>You can download Konference here: &lt;a href="http://www.kde-apps.org/content/show.php?content=10395"&gt;http://www.kde-apps.org/content/show.php?content=10395&lt;/a&gt;</string>
136
            </property>
137
        </widget>
138
    </vbox>
139
</widget>
140
<customwidgets>
141
</customwidgets>
142
<layoutdefaults spacing="6" margin="11"/>
143
<includehints>
144
    <includehint>kcombobox.h</includehint>
145
    <includehint>klineedit.h</includehint>
146
    <includehint>kactivelabel.h</includehint>
147
</includehints>
148
</UI>
(-)tdenetwork.ori/kopete/plugins/nowlistening/nowlisteningplugin.cpp (-78 / +30 lines)
Lines 258-341 Link Here
258
		TQPtrList<Kopete::Account> accountsList = Kopete::AccountManager::self()->accounts();
258
		TQPtrList<Kopete::Account> accountsList = Kopete::AccountManager::self()->accounts();
259
		for( Kopete::Account* a = accountsList.first(); a; a = accountsList.next() )
259
		for( Kopete::Account* a = accountsList.first(); a; a = accountsList.next() )
260
		{
260
		{
261
			/*
261
			if( NowListeningConfig::self()->appendStatusAdvertising() )
262
				NOTE:
262
      {
263
				MSN status message(personal message) use a special tag to advert the current music playing. 
263
        // Check for the now listening message in parenthesis, 
264
				So, we don't send the all formatted string, send a special string seperated by ";".
264
        // include the header to not override other messages in parenthesis.
265
				
265
        TQRegExp statusSong( TQString(" \\(%1.*\\)$").arg( NowListeningConfig::header()) );
266
				Also, do not use MSN hack in appending mode.
266
        
267
			*/
267
        // HACK: Don't keep appending the now listened song. Replace it in the status message.
268
			if( a->protocol()->pluginId() == "MSNProtocol" && !NowListeningConfig::self()->appendStatusAdvertising() )
268
        advert = a->myself()->property( Kopete::Global::Properties::self()->awayMessage() ).value().toString();
269
			{
269
        // Remove the braces when they are no listened song.
270
				TQString track, artist, album, mediaList;
270
        TQString mediaAdvert = mediaPlayerAdvert(false);
271
				bool isPlaying=false;
271
        if(!mediaAdvert.isEmpty())
272
272
        {
273
				if( NowListeningConfig::self()->useSpecifiedMediaPlayer() && d->m_currentMediaPlayer )
273
          if(statusSong.search(advert) != -1)
274
				{
274
          {
275
					if( d->m_currentMediaPlayer->playing() )
275
            advert = advert.replace(statusSong, TQString(" (%1)").arg(mediaPlayerAdvert(false)) );
276
					{
276
          }
277
						track = d->m_currentMediaPlayer->track();
277
          else
278
						artist = d->m_currentMediaPlayer->artist();
278
          {
279
						album = d->m_currentMediaPlayer->album();
279
            advert += TQString(" (%1)").arg( mediaPlayerAdvert(false) );
280
						mediaList = track + ";" + artist + ";" + album;
280
          }
281
						isPlaying = true;
281
        }
282
					}
282
        else
283
				}
283
        {
284
				else
284
          advert = advert.replace(statusSong, "");
285
				{
285
        }
286
					for ( NLMediaPlayer* i = d->m_mediaPlayerList.first(); i; i = d->m_mediaPlayerList.next() )
286
      }
287
					{
287
      else
288
						if( i->playing() )
288
      {
289
						{
289
        advert = mediaPlayerAdvert(false); // newTrackPlaying has done the update.
290
							track = i->track();
290
      }
291
							artist = i->artist();
292
							album = i->album();
293
							mediaList = track + ";" + artist + ";" + album;
294
							isPlaying = true;
295
						}
296
					}
297
				}
298
299
				// KDE4 TODO: Use the new status message framework, and remove this "hack".
300
				if( isPlaying )
301
				{
302
					advert = TQString("[Music]%1").arg(mediaList);
303
				}
304
305
			}
306
			else
307
			{
308
				if( NowListeningConfig::self()->appendStatusAdvertising() )
309
				{
310
					// Check for the now listening message in parenthesis, 
311
					// include the header to not override other messages in parenthesis.
312
					TQRegExp statusSong( TQString(" \\(%1.*\\)$").arg( NowListeningConfig::header()) );
313
					
314
					// HACK: Don't keep appending the now listened song. Replace it in the status message.
315
					advert = a->myself()->property( Kopete::Global::Properties::self()->awayMessage() ).value().toString();
316
					// Remove the braces when they are no listened song.
317
					TQString mediaAdvert = mediaPlayerAdvert(false);
318
					if(!mediaAdvert.isEmpty())
319
					{
320
						if(statusSong.search(advert) != -1)
321
						{
322
							advert = advert.replace(statusSong, TQString(" (%1)").arg(mediaPlayerAdvert(false)) );
323
						}
324
						else
325
						{
326
							advert += TQString(" (%1)").arg( mediaPlayerAdvert(false) );
327
						}
328
					}
329
					else
330
					{
331
						advert = advert.replace(statusSong, "");
332
					}
333
				}
334
				else
335
				{
336
					advert = mediaPlayerAdvert(false); // newTrackPlaying has done the update.
337
				}
338
			}
339
291
340
			a->setOnlineStatus(a->myself()->onlineStatus(), advert);
292
			a->setOnlineStatus(a->myself()->onlineStatus(), advert);
341
		}
293
		}
(-)tdenetwork.ori/kopete/plugins/webpresence/webpresence_html_images.xsl (-3 lines)
Lines 24-32 Link Here
24
24
25
	<xsl:template match="protocol">
25
	<xsl:template match="protocol">
26
		<xsl:choose>
26
		<xsl:choose>
27
			<xsl:when test=".='MSNProtocol'">
28
				<img src="{$images}/msn_protocol.png" alt="MSN" title="MSN"/>
29
			</xsl:when>
30
			<xsl:when test=".='ICQProtocol'">
27
			<xsl:when test=".='ICQProtocol'">
31
				<img src="{$images}/icq_protocol.png" alt="ICQ" title="ICQ"/>
28
				<img src="{$images}/icq_protocol.png" alt="ICQ" title="ICQ"/>
32
			</xsl:when>
29
			</xsl:when>
(-)tdenetwork.ori/kopete/plugins/webpresence/webpresence_html.xsl (-3 lines)
Lines 57-65 Link Here
57
			<xsl:when test=".='AIMProtocol'">
57
			<xsl:when test=".='AIMProtocol'">
58
				<xsl:text>AIM</xsl:text>
58
				<xsl:text>AIM</xsl:text>
59
			</xsl:when>
59
			</xsl:when>
60
			<xsl:when test=".='MSNProtocol'">
61
				<xsl:text>MSN</xsl:text>
62
			</xsl:when>
63
			<xsl:when test=".='ICQProtocol'">
60
			<xsl:when test=".='ICQProtocol'">
64
				<xsl:text>ICQ</xsl:text>
61
				<xsl:text>ICQ</xsl:text>
65
			</xsl:when>
62
			</xsl:when>
(-)tdenetwork.ori/kopete/plugins/webpresence/webpresenceprefs.ui (-3 / +2 lines)
Lines 200-215 Link Here
200
                        <string>Repla&amp;ce protocol text with images in (X)HTML</string>
200
                        <string>Repla&amp;ce protocol text with images in (X)HTML</string>
201
                    </property>
201
                    </property>
202
                    <property name="toolTip" stdset="0">
202
                    <property name="toolTip" stdset="0">
203
                        <string>Replaces the protocol names, such as MSN and IRC with images.</string>
203
                        <string>Replaces the protocol names, such as IRC with images.</string>
204
                    </property>
204
                    </property>
205
                    <property name="whatsThis" stdset="0">
205
                    <property name="whatsThis" stdset="0">
206
                        <string>Replaces the protocol names, such as MSN and IRC with images.
206
                        <string>Replaces the protocol names, such as IRC with images.
207
207
208
Note that you have to manually copy the PNG files into place.
208
Note that you have to manually copy the PNG files into place.
209
209
210
The following files are used by default:
210
The following files are used by default:
211
211
212
images/msn_protocol.png
213
images/icq_protocol.png
212
images/icq_protocol.png
214
images/jabber_protocol.png
213
images/jabber_protocol.png
215
images/yahoo_protocol.png
214
images/yahoo_protocol.png
(-)tdenetwork.ori/kopete/plugins/webpresence/webpresence_xhtml_images.xsl (-3 lines)
Lines 25-33 Link Here
25
25
26
	<xsl:template match="protocol">
26
	<xsl:template match="protocol">
27
		<xsl:choose>
27
		<xsl:choose>
28
			<xsl:when test=".='MSNProtocol'">
29
				<img src="{$images}/msn_protocol.png" alt="MSN" title="MSN"/>
30
			</xsl:when>
31
			<xsl:when test=".='ICQProtocol'">
28
			<xsl:when test=".='ICQProtocol'">
32
				<img src="{$images}/icq_protocol.png" alt="ICQ" title="ICQ"/>
29
				<img src="{$images}/icq_protocol.png" alt="ICQ" title="ICQ"/>
33
			</xsl:when>
30
			</xsl:when>
(-)tdenetwork.ori/kopete/plugins/webpresence/webpresence_xhtml.xsl (-3 lines)
Lines 56-64 Link Here
56
			<xsl:when test=".='AIMProtocol'">
56
			<xsl:when test=".='AIMProtocol'">
57
				<xsl:text>AIM</xsl:text>
57
				<xsl:text>AIM</xsl:text>
58
			</xsl:when>
58
			</xsl:when>
59
			<xsl:when test=".='MSNProtocol'">
60
				<xsl:text>MSN</xsl:text>
61
			</xsl:when>
62
			<xsl:when test=".='ICQProtocol'">
59
			<xsl:when test=".='ICQProtocol'">
63
				<xsl:text>ICQ</xsl:text>
60
				<xsl:text>ICQ</xsl:text>
64
			</xsl:when>
61
			</xsl:when>
(-)tdenetwork.ori/kopete/protocols/CMakeLists.txt (-1 lines)
Lines 11-17 Link Here
11
11
12
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_TESTBED testbed )
12
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_TESTBED testbed )
13
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_GROUPWISE groupwise )
13
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_GROUPWISE groupwise )
14
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_MSN msn )
15
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_IRC irc )
14
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_IRC irc )
16
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_OSCAR oscar )
15
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_OSCAR oscar )
17
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_YAHOO yahoo )
16
tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_YAHOO yahoo )
(-)tdenetwork.ori/kopete/protocols/configure.in.in (-15 / +1 lines)
Lines 104-130 Link Here
104
104
105
PKG_CHECK_MODULES(GLIB, glib-2.0 gmodule-2.0, have_glib=yes, have_glib=no)
105
PKG_CHECK_MODULES(GLIB, glib-2.0 gmodule-2.0, have_glib=yes, have_glib=no)
106
if test x$have_glib = xno; then
106
if test x$have_glib = xno; then
107
	AC_MSG_WARN([GLib 2.0 is required for MSN webcam and Jabber Jingle. You can get it from http://www.gtk.org/])
107
	AC_MSG_WARN([GLib 2.0 is required for Jabber Jingle. You can get it from http://www.gtk.org/])
108
else
108
else
109
	AC_SUBST(GLIB_CFLAGS)
109
	AC_SUBST(GLIB_CFLAGS)
110
	AC_SUBST(GLIB_LIBS)
110
	AC_SUBST(GLIB_LIBS)
111
	AC_DEFINE(HAVE_GLIB, 1, [Glib is required for oRTP code and libmimic code])
111
	AC_DEFINE(HAVE_GLIB, 1, [Glib is required for oRTP code and libmimic code])
112
fi
112
fi
113
113
114
if test "x$have_glib" != "xyes"; then
115
    compile_msn_webcam=no
116
    msn_webcam_val=0
117
else
118
    compile_msn_webcam=yes
119
    msn_webcam_val=1
120
fi
121
122
AC_MSG_CHECKING([if MSN webcam support should be enabled])
123
AC_MSG_RESULT($compile_msn_webcam)
124
AC_DEFINE_UNQUOTED(MSN_WEBCAM, $msn_webcam_val, [Define if MSN webcam support can be enabled])
125
126
AM_CONDITIONAL(include_msn_webcam, test "x$compile_msn_webcam" = "xyes")
127
128
# Check for sms protocol
114
# Check for sms protocol
129
AC_ARG_ENABLE(smsgsm,
115
AC_ARG_ENABLE(smsgsm,
130
      AC_HELP_STRING([--disable-smsgsm], [disable the GSM SMS protocol]),
116
      AC_HELP_STRING([--disable-smsgsm], [disable the GSM SMS protocol]),
(-)tdenetwork.ori/kopete/protocols/jabber/jabbertransport.cpp (-3 / +1 lines)
Lines 54-62 Link Here
54
54
55
#if KOPETE_IS_VERSION(0,11,51)  //setCustomIcon is new in kopete 0.12
55
#if KOPETE_IS_VERSION(0,11,51)  //setCustomIcon is new in kopete 0.12
56
	TQString cIcon;
56
	TQString cIcon;
57
	if(gateway_type=="msn")
57
  if(gateway_type=="icq")
58
		cIcon="jabber_gateway_msn";
59
	else if(gateway_type=="icq")
60
		cIcon="jabber_gateway_icq";
58
		cIcon="jabber_gateway_icq";
61
	else if(gateway_type=="aim")
59
	else if(gateway_type=="aim")
62
		cIcon="jabber_gateway_aim";
60
		cIcon="jabber_gateway_aim";
(-)tdenetwork.ori/kopete/protocols/jabber/jabbertransport.h (-1 / +1 lines)
Lines 47-53 Link Here
47
	 * constructor called when the transport is created by info from server  (i.e not when loading kopete)
47
	 * constructor called when the transport is created by info from server  (i.e not when loading kopete)
48
	 * @param parentAccount is the parent jabber account.
48
	 * @param parentAccount is the parent jabber account.
49
	 * @param item is the roster item of the gateway
49
	 * @param item is the roster item of the gateway
50
	 * @param gateway_type eg: "msn" or "icq"  only used when the account is not loaded from config file for determining the icon
50
	 * @param gateway_type eg: "icq"  only used when the account is not loaded from config file for determining the icon
51
	 */
51
	 */
52
	JabberTransport (JabberAccount * parentAccount, const XMPP::RosterItem &item, const TQString& gateway_type=TQString());
52
	JabberTransport (JabberAccount * parentAccount, const XMPP::RosterItem &item, const TQString& gateway_type=TQString());
53
	
53
	
(-)tdenetwork.ori/kopete/protocols/Makefile.am (-1 / +1 lines)
Lines 18-21 Link Here
18
SMS=sms
18
SMS=sms
19
endif
19
endif
20
20
21
SUBDIRS = $(TESTBED) groupwise msn irc oscar yahoo winpopup $(SMS) $(JABBER) $(GADU) $(MEANWHILE)
21
SUBDIRS = $(TESTBED) groupwise irc oscar yahoo winpopup $(SMS) $(JABBER) $(GADU) $(MEANWHILE)
(-)tdenetwork.ori/kopete/protocols/msn/Changelog (-106 lines)
Lines 1-106 Link Here
1
Have fun using this all-improved plugin and feel free to contribute patches
2
and other improvements to our mailing list! Although we all like to boast
3
about our great work, we're sure there are still bugs remaining, which is
4
why we don't call this release 1.0, but only 0.5.
5
6
Nevertheless, we feel this new MSN plugin is an enormous step forward from
7
the last 0.4.1 release and we recommend anyone to try out this all-improved
8
plugin. Please read the release notes first before reporting bugs, but please
9
do report anything not listed there!
10
11
Thanks for your interest in Kopete!
12
13
                        October 2002, the Kopete team <kopete-devel@kde.org>
14
15
16
CHANGES IN THE MSN PLUGIN SINCE KOPETE 0.4.1
17
18
- Ported the plugin to the new MetaContact API, allowing a locally cached
19
  copy of the contact list to be always available (even when offline) and
20
  to combine your MSN contacts with other messaging systems in one entry
21
  in the contact list.
22
23
- Added additional online states ('be right back', 'out to lunch', 'busy',
24
  'invisible') and the possibility to connect directly with a particular
25
  status (especially useful with 'invisible')
26
27
- Fix multi-user chat now the API finally supports it properly
28
29
- Fix a grave bug in Kopete 0.4.1 where Kopete would popup the 'new user'
30
  dialog for every user in your block list, asking whether you want to
31
  allow or block the user, often crashing Kopete completely
32
33
- Fix support for Unicode messages
34
35
- Fix the 'unhandled error 219' problem that caused Kopete to disconnect
36
  unexpectedly for some people
37
38
- Added possibility to talk with users who aren't in the contact list
39
40
- Incoming filetransfers
41
42
- As usual, several other bugfixes
43
44
CHANGES IN THE MSN PLUGIN SINCE KOPETE 0.4
45
46
- Added block/unblock user
47
48
- Don't show contacts from the allow list if they are not also in the
49
  friend list (like deleted contacts). Small problem: there already was
50
  a need to have a gui for manipulating blocked/allowed contacts, with
51
  this change this is even a bit more urgent...
52
53
- Hopefully fix a problem with an empty reverse list on a fresh MSN account.
54
  can't test, because by the time the recompile was done the reverse list
55
  was no longer empty...
56
57
- Fix a problem with MSN users no longer receiving messages. Apparently
58
  Microsoft changed the server so messages without an explicit font name are
59
  no longer passed on.
60
61
- Fixed UTF8 handling not really being UTF8. MSN should work fine now with
62
  all unicode characters
63
64
- Moved the plugin to use KGenericFactory as preparation for more KDE-style
65
  plugin handling (as opposed to the current custom code)
66
67
- Fixed crash when disconnecting while an earlier connect was still running
68
69
- Made the connect code asynchronous, so connecting doesn't hang kopete
70
  while processing
71
72
- Fixed minor memory leak in the connect code
73
74
CHANGES IN THE MSN PLUGIN SINCE KOPETE 0.3
75
76
Many things changed since 0.3. I won't mention them all, because so much of
77
the internal code changed that the individual commits often fix more than I
78
was even aware of at that time. Below are the bigger changes and fixes:
79
80
- Ported the plugin to the new KopeteMessageManager. This move unifies the
81
  handling of various resources like chat windows, balloons, system tray
82
  flashing, and more. In Kopete 0.3 this was the exclusive domain of the
83
  ICQ plugin, in this release all plugins except IRC already use the shared
84
  code.
85
86
- Rewrote almost all of the internal protocol handling, fixing an awful lot
87
  of bugs during the process. The main goal was to make the code more
88
  maintainable and extensible, but the gratuitous bug fixes are of course
89
  much more useful for most people. The most important fix of all is a
90
  grave bug that caused the plugin to read a fixed-size 1kb buffer in Kopete
91
  0.3 without checking for additional data, often causing the plugin to
92
  seemingly 'hang'.
93
94
- Added the ability to change the display name while connected. This can
95
  currently only be done from the context menu. The option in the
96
  preferences never worked, and still does not do what you'd expect it to
97
  do. Sorry :)
98
99
- Added much more useful debug code for developers, testers and other
100
  interested people. It is also a lot *more* debug output, so if you're
101
  scared of console output, better not start Kopete from it...
102
103
- All those tiny bugfixes of which I don't even know whether they fix
104
  regressions introduced during the development of version 0.4, or whether
105
  they fix long-standing bugs.
106
(-)tdenetwork.ori/kopete/protocols/msn/CMakeLists.txt (-72 lines)
Lines 1-72 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
add_subdirectory( ui )
13
add_subdirectory( icons )
14
add_subdirectory( config )
15
16
if( WITH_WEBCAM )
17
  add_subdirectory( webcam )
18
  add_definitions( -DMSN_WEBCAM )
19
  set( WEBCAM_LIBRARIES mimicwrapper-static kopete_videodevice-shared ${GLIB2_LIBRARIES} )
20
endif( )
21
22
include_directories(
23
  ${CMAKE_CURRENT_BINARY_DIR}
24
  ${CMAKE_CURRENT_BINARY_DIR}/ui
25
  ${CMAKE_CURRENT_SOURCE_DIR}
26
  ${CMAKE_CURRENT_SOURCE_DIR}/ui
27
  ${CMAKE_CURRENT_SOURCE_DIR}/webcam
28
  ${CMAKE_BINARY_DIR}
29
  ${CMAKE_SOURCE_DIR}/kopete/libkopete
30
  ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
31
  ${CMAKE_SOURCE_DIR}/kopete/libkopete/private
32
  ${TDE_INCLUDE_DIR}
33
  ${TQT_INCLUDE_DIRS}
34
)
35
36
link_directories(
37
  ${TQT_LIBRARY_DIRS}
38
)
39
40
41
##### other data ################################
42
43
install( FILES kopete_msn.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
44
install( FILES msnchatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_msn )
45
46
47
##### kopete_msn (module) #######################
48
49
tde_add_kpart( kopete_msn AUTOMOC
50
  SOURCES
51
    dummy.cpp webcam.cpp
52
  LINK kopete_msn_shared-shared
53
  DESTINATION ${PLUGIN_INSTALL_DIR}
54
)
55
56
57
##### kopete_msn_shared (shared) ################
58
59
tde_add_library( kopete_msn_shared SHARED AUTOMOC
60
  SOURCES
61
    msnprotocol.cpp msnaccount.cpp msnaddcontactpage.cpp msncontact.cpp
62
    msnsocket.cpp msnchatsession.cpp msndebugrawcmddlg.cpp
63
    msnnotifysocket.cpp msnswitchboardsocket.cpp
64
    msnfiletransfersocket.cpp msninvitation.cpp sha1.cpp
65
    msnsecureloginhandler.cpp msnchallengehandler.cpp
66
    dispatcher.cpp p2p.cpp messageformatter.cpp incomingtransfer.cpp
67
    outgoingtransfer.cpp webcam.cpp
68
  VERSION 0.0.0
69
  LINK
70
    kopetemsnui-static ${WEBCAM_LIBRARIES} kopete-shared
71
  DESTINATION ${LIB_INSTALL_DIR}
72
)
(-)tdenetwork.ori/kopete/protocols/msn/config/CMakeLists.txt (-38 lines)
Lines 1-38 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
include_directories(
13
  ${CMAKE_CURRENT_BINARY_DIR}
14
  ${CMAKE_SOURCE_DIR}/kopete/libkopete
15
  ${TDE_INCLUDE_DIR}
16
  ${TQT_INCLUDE_DIRS}
17
)
18
19
link_directories(
20
  ${TQT_LIBRARY_DIRS}
21
)
22
23
24
##### other data ################################
25
26
install( FILES
27
    kopete_msn_config.desktop
28
  DESTINATION ${SERVICES_INSTALL_DIR}/tdeconfiguredialog )
29
30
31
##### kcm_kopete_msn (module) ###################
32
33
tde_add_kpart( kcm_kopete_msn AUTOMOC
34
  SOURCES
35
    msnprefs.ui msnpreferences.cpp
36
  LINK kopete-shared
37
  DESTINATION ${PLUGIN_INSTALL_DIR}
38
)
(-)tdenetwork.ori/kopete/protocols/msn/config/kopete_msn_config.desktop (-123 lines)
Lines 1-123 Link Here
1
[Desktop Entry]
2
Icon=msn_protocol
3
Type=Service
4
ServiceTypes=TDECModule
5
6
X-TDE-ModuleType=Library
7
X-TDE-Library=kopete_msn
8
X-TDE-FactoryName=MSNProtocolConfigFactory
9
X-TDE-ParentApp=kopete_msn
10
X-TDE-ParentComponents=kopete_msn
11
12
Name=MSN Plugin
13
Name[ar]=توصيلة MSN
14
Name[be]=Модуль MSN
15
Name[bg]=MSN
16
Name[bn]=এমএসএন প্লাগিন
17
Name[br]=Lugent MSN
18
Name[bs]=MSN dodatak
19
Name[ca]=Connector de MSN
20
Name[cs]=MSN modul
21
Name[cy]=Ategyn MSN
22
Name[da]=MSN-Plugin
23
Name[de]=MSN-Modul
24
Name[el]=Πρόσθετο MSN
25
Name[es]=Complemento de MSN
26
Name[et]=MSN plugin
27
Name[eu]=MSN Plugin-a
28
Name[fa]=وصلۀ ام‌اس‌ان
29
Name[fi]=MSN-liitännäinen
30
Name[fr]=Module MSN
31
Name[ga]=Breiseán MSN
32
Name[gl]=Plugin para MSN
33
Name[he]=תוסף MSN
34
Name[hi]=एमएसएन प्लगइन
35
Name[hr]=MSN umetak
36
Name[hu]=MSN modul
37
Name[is]=MSN íforrit
38
Name[it]=Plugin MSN
39
Name[ja]=MSN プラグイン
40
Name[ka]=MSN მოდული
41
Name[kk]=MSN плагин модулі
42
Name[km]=កម្មវិធី​ជំនួយ MSN
43
Name[lt]=MSN įskiepis
44
Name[mk]=MSN-приклучок
45
Name[nb]=MSN programtillegg
46
Name[nds]=MSN-Moduul
47
Name[ne]=एमएसएन प्लगइन
48
Name[nl]=MSN-plugin
49
Name[nn]=MSN-programtillegg
50
Name[pa]=MSN ਪਲੱਗਇਨ
51
Name[pl]=Wtyczka MSN
52
Name[pt]='Plugin' MSN
53
Name[pt_BR]=Plug-in MSN
54
Name[ro]=Modul MSN
55
Name[ru]=Модуль MSN
56
Name[se]=MSN-lassemoduvla
57
Name[sk]=Modul MSN
58
Name[sl]=Vstavek za MSN
59
Name[sr]=MSN прикључак
60
Name[sr@Latn]=MSN priključak
61
Name[sv]=MSN-insticksprogram
62
Name[ta]=MSN செருகல்
63
Name[tg]=Модули MSN
64
Name[tr]=MSN Eklentisi
65
Name[uk]=Втулок MSN
66
Name[uz]=MSN plagini
67
Name[uz@cyrillic]=MSN плагини
68
Name[wa]=Tchôke-divins MSN
69
Name[zh_CN]=MSN 插件
70
Name[zh_HK]=MSN 插件
71
Name[zh_TW]=MSN 外掛程式
72
Comment=Microsoft Network Protocol
73
Comment[ar]=بروتوكول شبكة Microsoft
74
Comment[be]=Пратакол сеткі Microsoft Network
75
Comment[bg]=Протокол за връзка с Microsoft Network
76
Comment[bn]=মাইক্রোসফ্ট নেটওয়ার্ক প্রোটোকল
77
Comment[br]=Komenad rouedad Microsoft
78
Comment[bs]=Microsoft Network protokol
79
Comment[ca]=Protocol per a la xarxa de Microsoft
80
Comment[cs]=Protokol sítě Microsoft
81
Comment[cy]=Protocol Rhwydwaith Microsoft
82
Comment[de]=Microsoft Netzwerk-Protokoll
83
Comment[el]=Πρωτόκολλο Microsoft Network
84
Comment[es]=Protocolo de red de Microsoft
85
Comment[et]=Microsofti võrguprotokoll
86
Comment[fa]=قرارداد شبکۀ میکروسافت
87
Comment[fi]=Microsoft Network -yhteyskäytäntö
88
Comment[fr]=Protocole réseau Microsoft
89
Comment[ga]=Prótacal Gréasáin Mhicrosoft
90
Comment[gl]=Protocolo para a rede de Microsoft
91
Comment[he]=תוסף חיבור לרשת מיקרוסופט
92
Comment[hi]=माइक्रोसॉफ्ट नेटवर्क प्रोटोकॉल
93
Comment[hr]=Microsoft mrežni protokol
94
Comment[hu]=Microsoft hálózati protokoll
95
Comment[is]=Microsoft Network Protocol 
96
Comment[it]=Protocollo di rete Microsoft
97
Comment[ja]=Microsoft ネットワークプロトコル
98
Comment[ka]=Microsoft ქსელის ოქმი
99
Comment[kk]=Microsoft Network желі протоколы
100
Comment[km]=ពិធីការ​បណ្ដាញ​ម៉ៃក្រូសូហ្វ
101
Comment[lt]=Microsoft tinklo protokolas
102
Comment[mk]=Мрежен протокол на Microsoft
103
Comment[nds]=Microsoft-Nettwarkprotokoll
104
Comment[ne]=माइक्रोसफ्ट सञ्जाल प्रोटोकल
105
Comment[nl]=Protocol voor Microsoft Network
106
Comment[nn]=Microsoft Network-protokoll
107
Comment[pl]=Protokół Microsoft Network
108
Comment[pt]=Protocolo da Microsoft Network
109
Comment[pt_BR]=Protocolo de Rede Microsoft
110
Comment[ru]=Протокол сети Microsoft Network
111
Comment[sl]=Protokol za povezavo na MSN
112
Comment[sv]=Microsoft-nätverksprotokoll
113
Comment[ta]=மைக்ரோசாப்ட் இணைய விதிமுறை
114
Comment[tg]=Қарордоди Шабакаи Microsoft
115
Comment[tr]=Microsoft Ağ Protokolü
116
Comment[uk]=Мережний протокол Microsoft
117
Comment[uz]=Microsoft tarmogʻi bilan aloqa oʻrnatish uchun protokol
118
Comment[uz@cyrillic]=Microsoft тармоғи билан алоқа ўрнатиш учун протокол
119
Comment[wa]=Protocole pol rantoele da Microsoft
120
Comment[zh_CN]=Microsoft Network 协议
121
Comment[zh_HK]=Microsoft 網絡通訊協定
122
Comment[zh_TW]=Microsoft 網路協定
123
(-)tdenetwork.ori/kopete/protocols/msn/config/Makefile.am (-12 lines)
Lines 1-12 Link Here
1
METASOURCES = AUTO
2
AM_CPPFLAGS = $(KOPETE_INCLUDES) $(all_includes)
3
4
kde_module_LTLIBRARIES = kcm_kopete_msn.la
5
6
kcm_kopete_msn_la_SOURCES = msnprefs.ui msnpreferences.cpp
7
kcm_kopete_msn_la_LDFLAGS = -no-undefined -module $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
8
kcm_kopete_msn_la_LIBADD  = ../../../libkopete/libkopete.la $(LIB_TDEUTILS)
9
10
service_DATA = kopete_msn_config.desktop
11
servicedir = $(kde_servicesdir)/tdeconfiguredialog
12
(-)tdenetwork.ori/kopete/protocols/msn/config/msnpreferences.cpp (-33 lines)
Lines 1-33 Link Here
1
/*
2
    msnpreferences.cpp - MSN Preferences Widget
3
4
    Copyright (c) 2002-2003 by Olivier Goffart        <ogoffart @ kde.org>
5
    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include <kgenericfactory.h>
18
#include "kcautoconfigmodule.h"
19
#include "msnprefs.h"
20
21
class MSNPreferences;
22
23
typedef KGenericFactory<MSNPreferences> MSNProtocolConfigFactory;
24
K_EXPORT_COMPONENT_FACTORY( kcm_kopete_msn, MSNProtocolConfigFactory( "kcm_kopete_msn" ) )
25
26
class MSNPreferences : public KCAutoConfigModule
27
{
28
public:
29
	MSNPreferences( TQWidget *parent = 0, const char * = 0, const TQStringList &args = TQStringList() ) : KCAutoConfigModule( MSNProtocolConfigFactory::instance(), parent, args )
30
	{
31
		setMainWidget( new msnPrefsUI( this ) , "MSN");
32
	}
33
};
(-)tdenetwork.ori/kopete/protocols/msn/config/msnprefs.ui (-217 lines)
Lines 1-217 Link Here
1
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
2
<class>msnPrefsUI</class>
3
<author>Duncan Mac-Vicar P.</author>
4
<widget class="TQWidget">
5
    <property name="name">
6
        <cstring>msnPrefsUI</cstring>
7
    </property>
8
    <property name="geometry">
9
        <rect>
10
            <x>0</x>
11
            <y>0</y>
12
            <width>522</width>
13
            <height>347</height>
14
        </rect>
15
    </property>
16
    <vbox>
17
        <property name="name">
18
            <cstring>unnamed</cstring>
19
        </property>
20
        <widget class="TQLabel">
21
            <property name="name">
22
                <cstring>TextLabel3_2_2_2_3</cstring>
23
            </property>
24
            <property name="font">
25
                <font>
26
                    <bold>1</bold>
27
                </font>
28
            </property>
29
            <property name="text">
30
                <string>General</string>
31
            </property>
32
        </widget>
33
        <widget class="TQFrame">
34
            <property name="name">
35
                <cstring>Frame3_3_3_2_3</cstring>
36
            </property>
37
            <property name="sizePolicy">
38
                <sizepolicy>
39
                    <hsizetype>1</hsizetype>
40
                    <vsizetype>0</vsizetype>
41
                    <horstretch>0</horstretch>
42
                    <verstretch>0</verstretch>
43
                </sizepolicy>
44
            </property>
45
            <property name="frameShape">
46
                <enum>HLine</enum>
47
            </property>
48
            <property name="frameShadow">
49
                <enum>Sunken</enum>
50
            </property>
51
        </widget>
52
        <widget class="TQCheckBox">
53
            <property name="name">
54
                <cstring>NotifyNewChat</cstring>
55
            </property>
56
            <property name="text">
57
                <string>&amp;Automatically open a chat window when someone starts a conversation</string>
58
            </property>
59
        </widget>
60
        <widget class="TQCheckBox">
61
            <property name="name">
62
                <cstring>AutoDownloadPicture</cstring>
63
            </property>
64
            <property name="text">
65
                <string>&amp;Automatically download the display picture if possible</string>
66
            </property>
67
            <property name="checked">
68
                <bool>true</bool>
69
            </property>
70
        </widget>
71
        <widget class="TQCheckBox">
72
            <property name="name">
73
                <cstring>useCustomEmoticons</cstring>
74
            </property>
75
            <property name="text">
76
                <string>Download and show custom emoticons (experimental)</string>
77
            </property>
78
        </widget>
79
        <widget class="TQLabel">
80
            <property name="name">
81
                <cstring>TextLabel1_3_3_3</cstring>
82
            </property>
83
            <property name="text">
84
                <string></string>
85
            </property>
86
        </widget>
87
        <widget class="TQLabel">
88
            <property name="name">
89
                <cstring>TextLabel3_2_2_2_2</cstring>
90
            </property>
91
            <property name="font">
92
                <font>
93
                    <bold>1</bold>
94
                </font>
95
            </property>
96
            <property name="text">
97
                <string>Away Messages</string>
98
            </property>
99
        </widget>
100
        <widget class="TQFrame">
101
            <property name="name">
102
                <cstring>Frame3_3_3_2_2</cstring>
103
            </property>
104
            <property name="sizePolicy">
105
                <sizepolicy>
106
                    <hsizetype>1</hsizetype>
107
                    <vsizetype>0</vsizetype>
108
                    <horstretch>0</horstretch>
109
                    <verstretch>0</verstretch>
110
                </sizepolicy>
111
            </property>
112
            <property name="frameShape">
113
                <enum>HLine</enum>
114
            </property>
115
            <property name="frameShadow">
116
                <enum>Sunken</enum>
117
            </property>
118
        </widget>
119
        <widget class="TQCheckBox">
120
            <property name="name">
121
                <cstring>SendAwayMessages</cstring>
122
            </property>
123
            <property name="sizePolicy">
124
                <sizepolicy>
125
                    <hsizetype>7</hsizetype>
126
                    <vsizetype>0</vsizetype>
127
                    <horstretch>0</horstretch>
128
                    <verstretch>0</verstretch>
129
                </sizepolicy>
130
            </property>
131
            <property name="text">
132
                <string>Send &amp;away messages</string>
133
            </property>
134
            <property name="checked">
135
                <bool>true</bool>
136
            </property>
137
        </widget>
138
        <widget class="TQLayoutWidget">
139
            <property name="name">
140
                <cstring>layout18</cstring>
141
            </property>
142
            <hbox>
143
                <property name="name">
144
                    <cstring>unnamed</cstring>
145
                </property>
146
                <widget class="TQLabel">
147
                    <property name="name">
148
                        <cstring>textLabel3</cstring>
149
                    </property>
150
                    <property name="text">
151
                        <string>Do not send more than one away message every</string>
152
                    </property>
153
                </widget>
154
                <widget class="KIntNumInput">
155
                    <property name="name">
156
                        <cstring>AwayMessageSeconds</cstring>
157
                    </property>
158
                    <property name="value">
159
                        <number>90</number>
160
                    </property>
161
                    <property name="minValue">
162
                        <number>1</number>
163
                    </property>
164
                </widget>
165
                <widget class="TQLabel">
166
                    <property name="name">
167
                        <cstring>textLabel4</cstring>
168
                    </property>
169
                    <property name="text">
170
                        <string>seconds</string>
171
                    </property>
172
                </widget>
173
            </hbox>
174
        </widget>
175
        <spacer>
176
            <property name="name">
177
                <cstring>spacer7</cstring>
178
            </property>
179
            <property name="orientation">
180
                <enum>Vertical</enum>
181
            </property>
182
            <property name="sizeType">
183
                <enum>Expanding</enum>
184
            </property>
185
            <property name="sizeHint">
186
                <size>
187
                    <width>21</width>
188
                    <height>70</height>
189
                </size>
190
            </property>
191
        </spacer>
192
    </vbox>
193
</widget>
194
<connections>
195
    <connection>
196
        <sender>SendAwayMessages</sender>
197
        <signal>toggled(bool)</signal>
198
        <receiver>AwayMessageSeconds</receiver>
199
        <slot>setEnabled(bool)</slot>
200
    </connection>
201
</connections>
202
<tabstops>
203
    <tabstop>NotifyNewChat</tabstop>
204
    <tabstop>AutoDownloadPicture</tabstop>
205
    <tabstop>useCustomEmoticons</tabstop>
206
    <tabstop>SendAwayMessages</tabstop>
207
    <tabstop>AwayMessageSeconds</tabstop>
208
</tabstops>
209
<includes>
210
    <include location="global" impldecl="in implementation">knuminput.h</include>
211
</includes>
212
<layoutdefaults spacing="6" margin="11"/>
213
<includehints>
214
    <includehint>knuminput.h</includehint>
215
    <includehint>knuminput.h</includehint>
216
</includehints>
217
</UI>
(-)tdenetwork.ori/kopete/protocols/msn/dispatcher.cpp (-647 lines)
Lines 1-647 Link Here
1
/*
2
    dispatcher.cpp - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include "dispatcher.h"
18
#include "incomingtransfer.h"
19
#include "outgoingtransfer.h"
20
21
#if MSN_WEBCAM
22
#include "webcam.h"
23
#endif
24
25
using P2P::Dispatcher;
26
using P2P::Message;
27
using P2P::TransferContext;
28
using P2P::IncomingTransfer;
29
using P2P::OutgoingTransfer;
30
31
#include "msnswitchboardsocket.h"
32
33
// Kde includes
34
#include <kdebug.h>
35
#include <kmdcodec.h>
36
#include <kstandarddirs.h>
37
#include <tdetempfile.h>
38
39
// TQt includes
40
#include <tqdatastream.h>
41
#include <tqfile.h>
42
#include <tqregexp.h>
43
#include <tqtextcodec.h>
44
#include <tqtextstream.h>
45
46
// Kopete includes
47
#include <kopetechatsession.h>  // Just for getting the contact
48
#include <kopeteaccount.h>
49
#include <kopetetransfermanager.h>
50
51
#include <stdlib.h>
52
53
Dispatcher::Dispatcher(TQObject *parent, const TQString& contact, const TQStringList &ip)
54
	: TQObject(parent) ,  m_contact(contact) , m_callbackChannel(0l) , m_ip(ip)
55
{}
56
57
Dispatcher::~Dispatcher()
58
{
59
	kdDebug(14140) << k_funcinfo << endl;
60
61
	if(m_callbackChannel)
62
	{
63
		delete m_callbackChannel;
64
		m_callbackChannel = 0l;
65
	}
66
}
67
68
void Dispatcher::detach(TransferContext* transfer)
69
{
70
	m_sessions.remove(transfer->m_sessionId);
71
	transfer->deleteLater();
72
}
73
74
TQString Dispatcher::localContact()
75
{
76
	return m_contact;
77
}
78
79
void Dispatcher::requestDisplayIcon(const TQString& from, const TQString& msnObject)
80
{
81
	TQ_UINT32 sessionId = rand()%0xFFFFFF00 + 4;
82
	TransferContext* current =
83
		new IncomingTransfer(from, this, sessionId);
84
85
	current->m_branch = P2P::Uid::createUid();
86
	current->m_callId = P2P::Uid::createUid();
87
	current->setType(P2P::UserDisplayIcon);
88
	current->m_object = msnObject;
89
	// Add the transfer to the list.
90
	m_sessions.insert(sessionId, current);
91
92
	kdDebug(14140) << k_funcinfo << "Requesting, " << msnObject << endl;
93
94
	TQString context = TQString::fromUtf8(KCodecs::base64Encode(msnObject.utf8()));
95
	// NOTE remove the \0 character automatically
96
	// appended to a TQCString.
97
	context.replace("=", TQString());
98
	TQString content =
99
			"EUF-GUID: {A4268EEC-FEC5-49E5-95C3-F126696BDBF6}\r\n"
100
			"SessionID: " + TQString::number(sessionId) + "\r\n"
101
			"AppID: 1\r\n"
102
			"Context: " + context + "\r\n"
103
			"\r\n";
104
	// Send the sending client an invitation message.
105
	current->sendMessage(INVITE, content);
106
}
107
108
void Dispatcher::sendFile(const TQString& path, TQ_INT64 fileSize, const TQString& to)
109
{
110
	// Create a new transfer context that will handle
111
	// the file transfer.
112
	TQ_UINT32 sessionId = rand()%0xFFFFFF00 + 4;
113
	TransferContext *current =
114
		new OutgoingTransfer(to, this, sessionId);
115
	current->m_branch = P2P::Uid::createUid();
116
	current->m_callId = P2P::Uid::createUid();
117
	current->setType(P2P::File);
118
	// Add the transfer to the list.
119
	m_sessions.insert(sessionId, current);
120
121
	// Set the transfer context file.
122
	current->m_file = new TQFile(path);
123
	// Create the file context data.
124
	TQString context;
125
126
	TQByteArray header(638);
127
	header.fill('\0');
128
	TQDataStream writer(header, IO_WriteOnly);
129
	writer.setByteOrder(TQDataStream::LittleEndian);
130
131
	// Write the header length to the stream.
132
	writer << (TQ_INT32)638;
133
	// Write client version to the stream.
134
	writer << (TQ_INT32)3;
135
	// Write the file size to the stream.
136
	writer << fileSize;
137
	// Write the file transfer flag to the stream.
138
	// TODO support file preview. For now disable file preview.
139
	writer << (TQ_INT32)1;
140
	// Write the file name in utf-16 to the stream.
141
	TQTextStream ts(header, IO_WriteOnly);
142
	ts.setEncoding(TQTextStream::RawUnicode);
143
	ts.device()->at(20);
144
	ts << path.section('/', -1);
145
	// NOTE Background Sharing base64 [540..569]
146
	// TODO add support for background sharing.
147
	// Write file exchange type to the stream.
148
	// NOTE File - 0xFFFFFFFF
149
	// NOTE Background Sharing - 0xFFFFFFFE
150
	writer.device()->at(570);
151
	writer << (TQ_UINT32)0xFFFFFFFF;
152
153
	// Encode the file context header to base64 encoding.
154
	context = TQString::fromUtf8(KCodecs::base64Encode(header));
155
156
	// Send an INVITE message to the recipient.
157
	TQString content = "EUF-GUID: {5D3E02AB-6190-11D3-BBBB-00C04F795683}\r\n"
158
			"SessionID: " + TQString::number(sessionId) + "\r\n"
159
			"AppID: 2\r\n"
160
			"Context: "   + context + "\r\n"
161
			"\r\n";
162
	current->sendMessage(INVITE, content);
163
}
164
165
void Dispatcher::sendImage(const TQString& /*fileName*/, const TQString& /*to*/)
166
{
167
// 	TODO kdDebug(14140) << k_funcinfo << endl;
168
// 	TQFile imageFile(fileName);
169
// 	if(!imageFile.open(IO_ReadOnly))
170
// 	{
171
// 		kdDebug(14140) << k_funcinfo << "Error opening image file."
172
// 			<< endl;
173
// 		return;
174
// 	}
175
//
176
// 	OutgoingTransfer *outbound =
177
// 		new OutgoingTransfer(to, this, 64);
178
//
179
// 	outbound->sendImage(imageFile.readAll());
180
}
181
182
#if MSN_WEBCAM
183
void Dispatcher::startWebcam(const TQString &/*myHandle*/, const TQString &msgHandle, bool wantToReceive)
184
{
185
	TQ_UINT32 sessionId = rand()%0xFFFFFF00 + 4;
186
	Webcam::Who who= wantToReceive ? Webcam::wViewer : Webcam::wProducer;
187
	TransferContext* current =
188
			new Webcam(who, msgHandle, this, sessionId);
189
190
	current->m_branch = P2P::Uid::createUid();
191
	current->m_callId = P2P::Uid::createUid();
192
	current->setType(P2P::WebcamType);
193
	// Add the transfer to the list.
194
	m_sessions.insert(sessionId, current);
195
196
	//  {4BD96FC0-AB17-4425-A14A-439185962DC8}  <- i want to show you my webcam
197
	//  {1C9AA97E-9C05-4583-A3BD-908A196F1E92}  <- i want to see your webcam
198
	TQString GUID= (who==Webcam::wProducer) ? "4BD96FC0-AB17-4425-A14A-439185962DC8" : "1C9AA97E-9C05-4583-A3BD-908A196F1E92"  ;
199
200
	TQString content="EUF-GUID: {"+GUID+"}\r\n"
201
			"SessionID: "+ TQString::number(sessionId)+"\r\n"
202
			"AppID: 4\r\n"
203
			"Context: ewBCADgAQgBFADcAMABEAEUALTQBFADIAQwBBAC0ANAA0ADAAMAAtAEEARTQAwADMALQA4ADgARgBGADgANTQBCADkARgA0AEUAOAB9AA==\r\n\r\n";
204
205
        // context is the base64 of the utf16 of {B8BE70DE-E2CA-4400-AE03-88FF85B9F4E8}
206
207
	current->sendMessage( INVITE , content );
208
}
209
#endif
210
211
212
213
void Dispatcher::slotReadMessage(const TQString &from, const TQByteArray& stream)
214
{
215
	P2P::Message receivedMessage =
216
		m_messageFormatter.readMessage(stream);
217
218
	receivedMessage.source = from;
219
220
	if(receivedMessage.contentType == "application/x-msnmsgrp2p")
221
	{
222
		if((receivedMessage.header.dataSize == 0)/* && ((receivedMessage.header.flag & 0x02) == 0x02)*/)
223
		{
224
			TransferContext *current = 0l;
225
			TQMap<TQ_UINT32, TransferContext*>::Iterator it = m_sessions.begin();
226
			for(; it != m_sessions.end(); it++)
227
			{
228
				if(receivedMessage.header.ackSessionIdentifier == it.data()->m_identifier){
229
					current = it.data();
230
					break;
231
				}
232
			}
233
234
			if(current){
235
    			// Inform the transfer object of the acknowledge.
236
    			current->m_ackSessionIdentifier = receivedMessage.header.identifier;
237
    			current->m_ackUniqueIdentifier = receivedMessage.header.ackSessionIdentifier;
238
				current->acknowledged();
239
			}
240
			else
241
			{
242
				kdDebug(14140) << k_funcinfo
243
					<< "no transfer context with identifier, "
244
					<< receivedMessage.header.ackSessionIdentifier
245
					<< endl;
246
			}
247
			return;
248
		}
249
250
		if(m_messageBuffer.contains(receivedMessage.header.identifier))
251
		{
252
			kdDebug(14140) << k_funcinfo
253
				<< TQString("retrieving buffered messsage, %1").arg(receivedMessage.header.identifier)
254
				<< endl;
255
256
			// The message was split, try to reconstruct the message
257
			// with this received piece.
258
			Message bufferedMessage = m_messageBuffer[receivedMessage.header.identifier];
259
			// Remove the buffered message.
260
			m_messageBuffer.remove(receivedMessage.header.identifier);
261
262
			bufferedMessage.body.resize(bufferedMessage.body.size() + receivedMessage.header.dataSize);
263
			for(TQ_UINT32 i=0; i < receivedMessage.header.dataSize; i++){
264
				// Add the remaining message data to the buffered message.
265
				bufferedMessage.body[receivedMessage.header.dataOffset + i] = receivedMessage.body[i];
266
			}
267
			bufferedMessage.header.dataSize += receivedMessage.header.dataSize;
268
			bufferedMessage.header.dataOffset = 0;
269
270
			receivedMessage = bufferedMessage;
271
		}
272
273
		// Dispatch the received message.
274
		dispatch(receivedMessage);
275
	}
276
}
277
278
void Dispatcher::dispatch(const P2P::Message& message)
279
280
{
281
	TransferContext *messageHandler = 0l;
282
283
	if(message.header.sessionId > 0)
284
	{
285
		if(m_sessions.contains(message.header.sessionId)){
286
			messageHandler = m_sessions[message.header.sessionId];
287
		}
288
	}
289
	else
290
	{
291
		TQString body =
292
			TQCString(message.body.data(), message.header.dataSize);
293
		TQRegExp regex("SessionID: ([0-9]*)\r\n");
294
		if(regex.search(body) > 0)
295
		{
296
			TQ_UINT32 sessionId = regex.cap(1).toUInt();
297
			if(m_sessions.contains(sessionId)){
298
				// Retrieve the message handler associated with the specified session Id.
299
				messageHandler = m_sessions[sessionId];
300
			}
301
		}
302
		else
303
		{
304
			// Otherwise, try to retrieve the message handler
305
			// based on the acknowlegded unique identifier.
306
			if(m_sessions.contains(message.header.ackUniqueIdentifier)){
307
				messageHandler =
308
					m_sessions[message.header.ackUniqueIdentifier];
309
			}
310
311
			if(!messageHandler)
312
			{
313
				// If the message handler still has not been found,
314
				// try to retrieve the handler based on the call id.
315
				regex = TQRegExp("Call-ID: \\{([0-9A-F\\-]*)\\}\r\n");
316
				regex.search(body);
317
				TQString callId = regex.cap(1);
318
319
				TransferContext *current = 0l;
320
				TQMap<TQ_UINT32, TransferContext*>::Iterator it = m_sessions.begin();
321
				for(; it != m_sessions.end(); it++)
322
				{
323
					current = it.data();
324
					if(current->m_callId == callId){
325
						messageHandler = current;
326
						break;
327
					}
328
				}
329
			}
330
		}
331
	}
332
333
	if(messageHandler){
334
		// Process the received message using the
335
		// retrieved registered handler.
336
		messageHandler->m_ackSessionIdentifier = message.header.identifier;
337
    	messageHandler->m_ackUniqueIdentifier = message.header.ackSessionIdentifier;
338
		messageHandler->processMessage(message);
339
	}
340
	else
341
	{
342
		// There are no objects registered, with the retrieved session Id,
343
		// to handle the received message; default to this dispatcher.
344
345
		if(message.header.totalDataSize > message.header.dataOffset + message.header.dataSize)
346
		{
347
			// The entire message has not been received;
348
			// buffer the recevied portion of the original message.
349
			kdDebug(14140) << k_funcinfo
350
				<< TQString("Buffering messsage, %1").arg(message.header.identifier)
351
				<< endl;
352
			m_messageBuffer.insert(message.header.identifier, message);
353
			return;
354
		}
355
356
		TQString body =
357
			TQCString(message.body.data(), message.header.dataSize);
358
		kdDebug(14140) << k_funcinfo << "received, " << body << endl;
359
360
		if(body.startsWith("INVITE"))
361
		{
362
			// Retrieve the branch, call id, and session id.
363
			// These fields will be used later on in the p2p
364
			// transaction.
365
			TQRegExp regex(";branch=\\{([0-9A-F\\-]*)\\}\r\n");
366
			regex.search(body);
367
			TQString branch = regex.cap(1);
368
			regex = TQRegExp("Call-ID: \\{([0-9A-F\\-]*)\\}\r\n");
369
			regex.search(body);
370
			TQString callId = regex.cap(1);
371
			regex = TQRegExp("SessionID: ([0-9]*)\r\n");
372
			regex.search(body);
373
			TQString sessionId = regex.cap(1);
374
			// Retrieve the contact that requested the session.
375
			regex = TQRegExp("From: <msnmsgr:([^>]*)>");
376
			regex.search(body);
377
			TQString from = regex.cap(1);
378
			// Retrieve the application identifier which
379
			// is used to determine what type of session
380
			// is being requested.
381
			regex = TQRegExp("AppID: ([0-9]*)\r\n");
382
			regex.search(body);
383
			TQ_UINT32 applicationId = regex.cap(1).toUInt();
384
385
			if(applicationId == 1  || applicationId == 11 || applicationId == 12 )
386
			{                         //the AppID is 12 since Messenger 7.5
387
				// A contact has requested a session to download
388
				// a display icon (User Display Icon or CustomEmotion).
389
390
				regex = TQRegExp("Context: ([0-9a-zA-Z+/=]*)");
391
				regex.search(body);
392
				TQCString msnobj;
393
394
				// Decode the msn object from base64 encoding.
395
				KCodecs::base64Decode(regex.cap(1).utf8() , msnobj);
396
				kdDebug(14140) << k_funcinfo << "Contact requested, "
397
					<< msnobj << endl;
398
399
				// Create a new transfer context that will handle
400
				// the user display icon transfer.
401
				TransferContext *current =
402
					new OutgoingTransfer(from, this, sessionId.toUInt());
403
				current->m_branch = branch;
404
				current->m_callId = callId;
405
				current->setType(P2P::UserDisplayIcon);
406
				// Add the transfer to the list.
407
				m_sessions.insert(sessionId.toUInt(), current);
408
409
				// Determine the display icon being requested.
410
				TQString fileName = objectList.contains(msnobj)
411
				    ? objectList[msnobj]
412
					: m_pictureUrl;
413
				TQFile *source = new TQFile(fileName);
414
				// Try to open the source file for reading.
415
				// If an error occurs, send an internal
416
				// error message to the recipient.
417
				if(!source->open(IO_ReadOnly))
418
				{
419
					current->error();
420
					return;
421
				}
422
423
				current->m_file = source;
424
				// Acknowledge the session request.
425
				current->acknowledge(message);
426
427
				current->m_ackSessionIdentifier = message.header.identifier;
428
    			current->m_ackUniqueIdentifier = message.header.ackSessionIdentifier;
429
				// Send a 200 OK message to the recipient.
430
				TQString content = TQString("SessionID: %1\r\n\r\n").arg(sessionId);
431
				current->sendMessage(OK, content);
432
			}
433
			else if(applicationId == 2)
434
			{
435
				// A contact has requested a session to
436
				// send a file.
437
438
				kdDebug(14140) << k_funcinfo << "File transfer invitation." << endl;
439
440
				// Create a new transfer context that will handle
441
				// the file transfer.
442
				TransferContext *transfer =
443
					new IncomingTransfer(from, this, sessionId.toUInt());
444
				transfer->m_branch = branch;
445
				transfer->m_callId = callId;
446
				transfer->setType(P2P::File);
447
				// Add the transfer to the list.
448
				m_sessions.insert(sessionId.toUInt(), transfer);
449
450
				regex = TQRegExp("Context: ([0-9a-zA-Z+/=]*)");
451
				regex.search(body);
452
				TQByteArray context;
453
454
				// Decode the file context from base64 encoding.
455
				KCodecs::base64Decode(regex.cap(1).utf8(), context);
456
				TQDataStream reader(context, IO_ReadOnly);
457
				reader.setByteOrder(TQDataStream::LittleEndian);
458
				//Retrieve the file info from the context field.
459
				// File Size [8..15] Int64
460
				reader.device()->at(8);
461
				TQ_INT64 fileSize;
462
				reader >> fileSize;
463
				// Flag [15..18] Int32
464
				// 0x00 File transfer with preview data.
465
				// 0x01 File transfer without preview data.
466
				// 0x02 Background sharing.
467
				TQ_INT32 flag;
468
				reader >> flag;
469
				kdDebug(14140) << flag << endl;
470
				// FileName UTF16 (Unicode) [19..539]
471
				TQByteArray bytes(520);
472
				reader.readRawBytes(bytes.data(), bytes.size());
473
				TQTextStream ts(bytes, IO_ReadOnly);
474
				ts.setEncoding(TQTextStream::Unicode);
475
				TQString fileName;
476
				fileName = ts.readLine().utf8();
477
478
				emit incomingTransfer(from, fileName, fileSize);
479
480
   				kdDebug(14140) <<
481
   					TQString("%1, %2 bytes.").arg(fileName, TQString::number(fileSize))
482
   					<< endl
483
   					<< endl;
484
485
				// Get the contact that is sending the file.
486
				Kopete::Contact *contact = getContactByAccountId(from);
487
488
				if(contact)
489
				{
490
					// Acknowledge the file invitation message.
491
					transfer->acknowledge(message);
492
493
					transfer->m_ackSessionIdentifier = message.header.identifier;
494
    				transfer->m_ackUniqueIdentifier = message.header.ackSessionIdentifier;
495
496
					TQObject::connect(Kopete::TransferManager::transferManager(), TQT_SIGNAL(accepted(Kopete::Transfer*, const TQString&)), transfer, TQT_SLOT(slotTransferAccepted(Kopete::Transfer*, const TQString&)));
497
					TQObject::connect(Kopete::TransferManager::transferManager(), TQT_SIGNAL(refused(const Kopete::FileTransferInfo&)), transfer, TQT_SLOT(slotTransferRefused(const Kopete::FileTransferInfo&)));
498
499
					// Show the file transfer accept/decline dialog.
500
					Kopete::TransferManager::transferManager()->askIncomingTransfer(contact, fileName, fileSize, TQString(), sessionId);
501
				}
502
				else
503
				{
504
					kdWarning(14140) << fileName << " from " << from
505
						<< " has failed; could not retrieve contact from contact list."
506
						<< endl;
507
					transfer->m_ackSessionIdentifier = message.header.identifier;
508
    				transfer->m_ackUniqueIdentifier = message.header.ackSessionIdentifier;
509
					transfer->sendMessage(ERROR);
510
				}
511
			}
512
			else if(applicationId == 4)
513
			{
514
#if MSN_WEBCAM
515
				regex = TQRegExp("EUF-GUID: \\{([0-9a-zA-Z\\-]*)\\}");
516
				regex.search(body);
517
				TQString GUID=regex.cap(1);
518
519
				kdDebug(14140) << k_funcinfo << "webcam " << GUID << endl;
520
521
				Webcam::Who who;
522
				if(GUID=="4BD96FC0-AB17-4425-A14A-439185962DC8")
523
				{  //that mean "I want to send MY webcam"
524
					who=Webcam::wViewer;
525
				}
526
				else if(GUID=="1C9AA97E-9C05-4583-A3BD-908A196F1E92")
527
				{ //that mean "I want YOU to send YOUR webcam"
528
					who=Webcam::wProducer;
529
				}
530
				else
531
				{ //unknown GUID
532
					//current->error();
533
					kdWarning(14140) << k_funcinfo << "Unknown GUID " << GUID << endl;
534
					return;
535
				}
536
537
				TransferContext *current = new P2P::Webcam(who, from, this, sessionId.toUInt());
538
				current->m_branch = branch;
539
				current->m_callId = callId;
540
541
					// Add the transfer to the list.
542
				m_sessions.insert(sessionId.toUInt(), current);
543
					// Acknowledge the session request.
544
				current->acknowledge(message);
545
				TQTimer::singleShot(0,current, TQT_SLOT(askIncommingInvitation()) );
546
#endif
547
			}
548
		}
549
		else if(message.header.sessionId == 64)
550
		{
551
			// A contact has sent an inkformat (handwriting) gif.
552
			// NOTE The entire message body is UTF16 encoded.
553
			TQString body = "";
554
			for (TQ_UINT32 i=0; i < message.header.totalDataSize; i++){
555
				if (message.body[i] != TQChar('\0')){
556
					body += TQChar(message.body[i]);
557
				}
558
			}
559
560
			TQRegExp regex("Content-Type: ([A-Za-z0-9$!*/\\-]*)");
561
			regex.search(body);
562
			TQString contentType = regex.cap(1);
563
564
			if(contentType == "image/gif")
565
			{
566
				IncomingTransfer transfer(message.source, this, message.header.sessionId);
567
				transfer.acknowledge(message);
568
569
				regex = TQRegExp("base64:([0-9a-zA-Z+/=]*)");
570
				regex.search(body);
571
				TQString base64 = regex.cap(1);
572
				TQByteArray image;
573
// 				Convert from base64 encoding to byte array.
574
				KCodecs::base64Decode(base64.utf8(), image);
575
// 				Create a temporary file to store the image data.
576
				KTempFile *ink = new KTempFile(locateLocal("tmp", "inkformatgif-" ), ".gif");
577
				ink->setAutoDelete(true);
578
// 				Save the image data to disk.
579
				ink->file()->writeBlock(image);
580
				ink->file()->close();
581
				displayIconReceived(ink, "inkformatgif");
582
				ink = 0l;
583
			}
584
		}
585
	}
586
}
587
588
void Dispatcher::messageAcknowledged(unsigned int correlationId, bool fullReceive)
589
{
590
	if(fullReceive)
591
	{
592
		TransferContext *current = 0l;
593
		TQMap<TQ_UINT32, TransferContext*>::Iterator it = m_sessions.begin();
594
		for(; it != m_sessions.end(); it++)
595
		{
596
			current = it.data();
597
			if(current->m_transactionId == correlationId)
598
			{
599
				// Inform the transfer object of the acknowledge.
600
				current->readyWrite();
601
				break;
602
			}
603
		}
604
	}
605
}
606
607
Kopete::Contact* Dispatcher::getContactByAccountId(const TQString& accountId)
608
{
609
	Kopete::Contact *contact = 0l;
610
	if(parent())
611
	{
612
		// Retrieve the contact from the current chat session context.
613
		Kopete::ChatSession *session = dynamic_cast<Kopete::ChatSession*>(parent()->parent());
614
		if(session)
615
		{
616
			contact = session->account()->contacts()[accountId];
617
			session->setCanBeDeleted(false);
618
		}
619
	}
620
	return contact;
621
}
622
623
Dispatcher::CallbackChannel::CallbackChannel(MSNSwitchBoardSocket *switchboard)
624
{
625
	m_switchboard = switchboard;
626
}
627
628
Dispatcher::CallbackChannel::~CallbackChannel()
629
{}
630
631
TQ_UINT32 Dispatcher::CallbackChannel::send(const TQByteArray& stream)
632
{
633
	return m_switchboard->sendCommand("MSG", "D", true, stream, true);
634
}
635
636
Dispatcher::CallbackChannel* Dispatcher::callbackChannel()
637
{
638
	if(m_callbackChannel == 0l){
639
		MSNSwitchBoardSocket *callback = dynamic_cast<MSNSwitchBoardSocket *>(parent());
640
		if(callback == 0l) return 0l;
641
		m_callbackChannel = new Dispatcher::CallbackChannel(callback);
642
	}
643
644
	return m_callbackChannel;
645
}
646
647
#include "dispatcher.moc"
(-)tdenetwork.ori/kopete/protocols/msn/dispatcher.h (-108 lines)
Lines 1-108 Link Here
1
/*
2
    dispatcher.h - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#ifndef DISPATCHER_H
18
#define DISPATCHER_H
19
20
#include <tqobject.h>
21
#include <tqstringlist.h>
22
23
#include "kopete_export.h"
24
25
#include "p2p.h"
26
#include "messageformatter.h"
27
#include "incomingtransfer.h"
28
#include "outgoingtransfer.h"
29
30
31
namespace Kopete { class Contact; }
32
class MSNSwitchBoardSocket;
33
34
/**
35
@author Kopete Developers
36
*/
37
namespace P2P{
38
	class IncomingTransfer;
39
	class OutgoingTransfer;
40
41
	class KOPETE_EXPORT Dispatcher : public TQObject
42
	{	Q_OBJECT
43
  
44
		public:
45
			Dispatcher(TQObject *parent, const TQString& contact, const TQStringList &ip);
46
			~Dispatcher();
47
48
			void detach(TransferContext* transfer);
49
			TQString localContact();
50
			void requestDisplayIcon(const TQString& from, const TQString& msnObject);
51
			void sendFile(const TQString& path, TQ_INT64 fileSize, const TQString& to);
52
			void sendImage(const TQString& fileName, const TQString& to);
53
			TQString m_pictureUrl;
54
			TQMap<TQString, TQString> objectList;
55
56
#if MSN_WEBCAM
57
			void startWebcam(const TQString &myHandle, const TQString &msgHandle, bool wantToReceive);
58
#endif
59
60
61
		public slots:
62
			void slotReadMessage(const TQString &from, const TQByteArray& stream);
63
			void messageAcknowledged(unsigned int correlationId, bool fullReceive);
64
65
		signals:
66
			void sendCommand(const TQString &cmd, const TQString &args = TQString(), bool addId = true, const TQByteArray &body = TQByteArray(), bool binary=false);
67
			void displayIconReceived(KTempFile* file, const TQString& msnObject);
68
			void incomingTransfer(const TQString& from, const TQString& fileName, TQ_INT64 fileSize);
69
70
		private:
71
				class CallbackChannel
72
				{
73
					public:
74
						CallbackChannel(MSNSwitchBoardSocket *switchboard);
75
						~CallbackChannel();
76
77
						TQ_UINT32 send(const TQByteArray& stream);
78
79
					private:
80
						MSNSwitchBoardSocket *m_switchboard;
81
				};
82
83
		public:
84
			CallbackChannel* callbackChannel();
85
			/**
86
			 * IP's of this compiter,  the first one is the one seen by the server.
87
			 */
88
			TQStringList localIp() { return m_ip; }
89
90
91
		private:
92
			void dispatch(const P2P::Message& message);
93
			Kopete::Contact* getContactByAccountId(const TQString& accountId);
94
95
			P2P::MessageFormatter m_messageFormatter;
96
			TQMap<TQ_UINT32, P2P::TransferContext*> m_sessions;
97
			TQMap<TQ_UINT32, P2P::Message> m_messageBuffer;
98
			TQString m_contact;
99
			CallbackChannel *m_callbackChannel;
100
			TQStringList m_ip;
101
102
			friend class P2P::TransferContext;
103
			friend class P2P::IncomingTransfer;
104
			friend class P2P::OutgoingTransfer;
105
	};
106
}
107
108
#endif
(-)tdenetwork.ori/kopete/protocols/msn/dummy.cpp (-3 lines)
Lines 1-3 Link Here
1
#include "kdemacros.h"
2
extern "C" KDE_EXPORT void *init_libkopete_msn_shared();
3
extern "C" KDE_EXPORT void *init_kopete_msn() { return init_libkopete_msn_shared(); }
(-)tdenetwork.ori/kopete/protocols/msn/icons/CMakeLists.txt (-12 lines)
Lines 1-12 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr128-app-msn_protocol.png (-63 lines)
Lines 1-63 Link Here
1
‰PNG
2
3
IHDR€€Ã>aËgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<>°IDATxÚbüÿÿ?Ã(¹ €FÀŒH˜*q@,£a:h#š	ˆ™¡4SgÃi6VNÂj#@þ?$üŠÿC1I €A©€‘‘q4ÈG¤ƒ"œyzßÃ@6V{V=–ÿ¿­ÞßGíÁðŸ[’á‹À‰Ï_Þî¸qûèæóSïõýâßÐDñŸØ €FÀÀ&H¤?pââäcùÿÇñéA>†'ûþ¿<ŒÖϐZú?A·ÃiµH†OÿX×­ÛÒ^µïÐÜç@™@üš&€Mñ,s&?Oä`çÉa~wAçÿí%àˆ‡æan`-ÈÏË ¨¤†ÒV{÷üÃË'Ï~ý&`"ø«‘ôùÒ퓙fDìŠ|…–	%€M”ãçL~‘ÄÉÉ[Íôx‹ìÿ«Ó€Qö,)ÀÆÀ diÏ cjÏÀ­fLà"àÿDð”
4
î;ÈpqÃ*†Ï¯^5ª10Xu3Üyõ¤¦¥×}.PÑ' þ‰/€â €Fëøýyx„{˜ŸnÕa¸>á?(â9^QA’AÝ+‚AЋé°¢9ü‡Åœaå|†«20pI20¸.a8qiwò̩ۀ
5
>BÁ?\	 €F}sWãi)9L.Ø0ÜFü›Óðˆ×
Jfà6öDD,z„#'b¯ïÝaØÕXÊð‹MŠáŸÓ¼/gŸ^¾¶÷´$ø­aŠ{€Mt¨çN×ÀöïC%ÃÕN†çûÀq¦(ŒøÀDnCÖEáñ‹»7Ž20<¼aÿø‚°ƒ›ANØ0gxÁ,ʰ§·™á—”Ãùˆ#Åõz‰@¯¡m‚?Ø@&æz`qïÂÏ'6‹ááR9†[ÓÀ-zQ!]1Û6n¹Ô–ÿÌÀpjÃÅ]ï_×±cçfØýàÃãW_þ;/d8rãt悅[@íF þŽ^
6
€â €F‚hS׃r}#û¿•ÿO'30¼=ÍÀ
7
,Œ­ý³xÄ!qñïfŽÿŒì£K.ïFõ~~e°f`xô
8
Ⱦ8‘Aߨ>È:Äß ½ŒR €FK*ù}m—TÄŔ×0=Y®Ëp˜ëfãa0/e`S²Ä]σ"þÄr†«{ÿŸ•Mä8ß¡Gÿn½*v^ÀpèډœÅ«K7…ß — ¸ Ñ€ŠEþ¬‰OBx9Øf2\.âgx¹œë͝­d|‹ Å=8ÇÿGM?õùE`üœ\NZnnj$˜€	h×í•ê*‘þ@¡ý@ü[)@£	€:€eÞÔWŜŸw0œ¯¶»o0ˆŠp3ØF¦1°©9Csò̜X=Ÿ^	¬ï¿¢V ÈÓ=06	£ü<lª‚ÀDðpƒ˜nž«Š¢™Ôû§>@K”@£	€
9
}ûÅ3?.`ùz9šáR¸ÈWÓTd0
10
Ëg`TĞëŸ_÷ó…òH®§êÈ0K uÏ1¸;f»À¤R^ÖÐh  ò*öŠ()™Îgy³Ý›áz
¤¡g©Ã P,¸1sý/`N¿°XÏoߣ‘s=zâ ²$Pàgd`eZùü0ƒ´j¦Ph)¨Ÿ-à	 €F™‘_Y¼UTEÅbó«-º7‘I'OA»lHdÿûšëß3à¡~`|Y¼c‹t*~&†›Ï3ð7è¹\@̍sx5@L£qINäoÕÖ´ßÃ|§^÷ÿ­.`¾rò÷b´Í€äz8þ
¡/¯f`ØQÅÀðõ5i•#eՃ$DÓ»ËÜN9:ЀÙ4€M$F~=°Ø×ÖpØÃü|…îÿ—%½GB:ƒ YZäñO[®­Ç™ØØTl(ÛàãÍu%+h`E¶ €F«»zJòF˜ßlÕý¿ùNaÑlòVhõ=PåÇGÀ†ÞT†ooÈo^RØ`æu^6F†OÀ  j«â€Æ9¬@£	€„®Þ¢°|ØõÿN-´Î·a`StÆl콸lì-öñ¿ŽL·$y	àãmn	h€Z
€Û4Z9Â7{òód–_¢t#ßÙʁM/Y¿u=?>ÊÀpv:0x¿a/ÞÉ)(¨D8ANüÂÀÇΩÔ„Ç;@&""J÷n6æ×“þÿýÌ`g!Ë hŒÙà{
11
Œü+‹ˆTBí*”"œPC>Þa0Õ÷—ƒ–ðx Ñ@ º*
12
7‹ðK¬a¸ÏðÿÏg.1«`²¡&€gǁýû¥øs/9Ja#Q˜‹R3€¬´Ž´€÷h´
@ Ñ§©n3ñù,ÙÿŸÎ0(kQ%Ç$`AÊíçC|ÏO30\_‰Aÿ),þS§`g†2€Õ€ ¿reþ¿„¯`BÃ#mʐiÖÄgÉ,ß.{3<›Î ÈÃÀ`dglV+#çƒrþg`kÿî&üMi7ÂRDŠX
13
|¼ËÀÏ#*Ô›@,X¬bžÖßøÿÿÂþü'g/n=êìóÀ€º!«¢¿8gµ(c'ÍZðz|Si6e/H·ÍáÿxÏÀpy0ý }ò[NÇ×K t°ø÷ÿ#z@È	€iæ¤Ç&B‚R«Ÿ¿û/÷ñó?°¹8äU¦Múà Ìÿÿɟ¿¿ž|ÿþ騗/ï.?~rõBïä°{Ð.l‡ÊpH̺ÚÎs_Ïçÿÿó)ƒž#ƒ ¦4ç#õõo.D>19ŸÅ;™ã"ÀvÀ“O/D„ätŠ°)KŒSûî*óòJí:xñ7ÿûÏÁkÓÁCÚ úß ý$&ÃÂÌ #ÀÃg!&,Ä #§Æ0kê÷§lÌߎùúîèÝ{göO¼MÄPڀÈ4µû®3Ëß·ÞÿŸ‹~^]KYÔþþÃ]ß^`Öû¤æVb
14
¥;Pó÷— xdDOKLÀœ_ÿå?þOßþ1ˆK22ø{²2˜è2CJ;hbxøøÃׯÿÁôë7ÿ=úÃpýÔin¶qé	I9†ù3¾]ÿÿï˱»Î.oíò<ËY‘ú{%f^^‘Ù÷ÒÁc-`GZ‘ûáóC†W'é_¼“™@+6– ´é–˜YXØ}Þ~þÍÀÅËÈÉ &njX}u°¼XLCZ:K`´>|ôáúÍ¿7nþfØ|à¯&‡¦ª‚còÌÉߟ2ü³æâå]K¦ÍN¾Í€X‘òwVL3'<Ibúv^öÿ—3ÊRŒâ¶@ÿ³@ë~ §ÿ‹ü‡[¨2TKôÐ/…%€Ãɧþ}yĈù`Ӟù?s·¨0¢%˜1©¢îGøOŒÀEA‰A˜8\Yþ£öú¿ç/üf8pú4+“@¾ºRLþì)!§¾}{¶2¿L4Rò)1š„Pž¿A„‹ƒ¯óÿÍ:6`Èèiò;҆¨uÿ‹#@—¤|°‡Ü❌Ä[NÈÏʬ…Þ£ 䚴6”ƒ<Ôùi½âÏ_ÿŽ#ôãgHŽå|&p@‰21È
H?30Ahi1K	&†°`vpb8zü7ÎÃÿÍd%äÌfNþVüÿßë5¶tMݱ{*°ï\•
15
Zô«(™2|ØÌÏð냆2#·œj«ÿûk†7çðG2¹#mÛHi¥
@(	€ØÍ¶ÿ¡í>Ú|äë·ÿÀ
BpøIwþ³ÿBÅAz¥Å­D	`‚dö;4‰AM™á30ñœ¿ð‡aËÖR|\By®Î=‰þÞ¥6níž2BaÖ
16
v6Î,†3Á‰[C˜ûù4€þÿ‹”û’>Ð3XÚðE­e€‹	ÑÈ;¾øÇðyLÌÈå	Äöÿ@3 •
17
DÃçoÿ®ÝùÃpå&$ðr32(Ë31ƒ¬3ƒµ5+ƒ¹)ÃÍ[¶lûÉûí³`®‹sOZBø1U“ª’y ÷ó|ÿ?cÐæ~6	Ô¢´‡ïÛSâêmJK*·dx‘K”(@ÁÀÿŸ¿¾àåb·xõíÊ%Häc«pP[‰ÿ1È'`›âìåß§/üVŒZj,Ú꬚Ì*Ê\ÀFã_†mÛð~ÿ"˜Ð—àâÒRRm¸€²‘V"У×ÀÂÅÉ_Åðh$÷+³S¯
18
jË´—”H&§@Ãñ.aQ†¯XŽ ØPð¿?~=æãddøñ‘áÙÛÿˆF H3‚KfcFpâ€Ë11 äQøŒ¿þüg8LW}cXÄ7îþfPTbbÈÍábðdcØsôïÃgªs¦~>”Ÿµ´ˆØ/``¦ñ04ÓäÎÛAL¿îÊþÿz–AV˜ûE´¡C½Ð©ÞoO€õÿsÂC´Ô˜ÁÃe…æsð	sóeq€‚'€/_ÞäaG䓧ÿÁ‰þ?´aȋhfDD3ò<10 ñ‘ÔAäÞ¼ûǰcÿO†9K¿2>ù“AR𑡏›AV‘aýŽßêBÂÁ[gL|Ôïâ˜&thÊ&µ'oìÿ·ËÀ}5 ‡y” ƒ>Püþ<îÜGìØ=¡i_F´!RJbZ¸lìX x¸s÷Ô!VF^`)pçÞx *ˆœÃ¡¹Ÿ\À"¹t€Ë1!a,¥#þÌ\ç¯üf˜·ì+þ£?X
19
¸ž¼úäóÅùõî«,Þâjž0 4RuÌ¿±â€
20
+Óo/†Ïd%xD€ý`&Däÿvù~¼Äظ"™ÒR€Ê%˜8Vq€‚'Ðîïß?®K»t7oÿ?*8ÙÅ:¬`Æ(òáÅ>3rngF‹|XA.% r×oÿV
_Î_ýÅÎÁ`ïȰi÷OI6Ç¥»®7Ý(ÈYÚÌJÅ*IBT%ù …ÊÀ¸gà”BíûtƒüY9F"0™‘LŠz6pŽÃV<€\ïÞ?[-ÂËìî12\½)8ف¹‚31Š|d9,	„¥]ÀˆùÈUË¥k¿–­ýÊðñ?CN6ãç?NËœ1ñíþ¨ÐV}Pbf€,m¢F•ÀÌÊÆýÿÃf`ø?ƒœ4ÐXNYÈ2/X"øúw 3Ò¨À@dB!pB6ci,r þ¾~óð&ÐX0ÂoÝE4%…™PJÔf„7
21
QäÐ3F¢aÄ4**}Nœý	l'ü`°µcgPQgfX»åš©qÎöâœÕ *Ÿ
22
Uc{íIc¦?/eÿ;Ë ,“DD<(|‚Øà«Ø§U;€”R€àä&&†ÿXR@!'€¿Sf&Üùþãó)!&pøð‰Ü×âcDhl‘‰V ´Ç€%Ñ «a‚V
àjZZ¼ûðaסžôà`ضï;'·Û¢ö†“ÅÐ*},ƒ”â_P@*ö?°ø…‹
23
(°‹¡ÿß×è¢E;€È„BT€ÈX@1¡
ýz÷îéJ`o4Ä{é
24
$͈	0‚G	Ñ#¹xÇÝ ÄÖ3ÀÒ¥DևV"Üyð‡áĹß~~œ®}cxöR¥ljÏÝéHí2‚™•…݇áã 	B@²	C‡~A	àÃO,?b‹aF*´¨Õ#à¦çßX‡=üMÖ01üý,ÁÏÄpåÆ?șu@ -„ÖDÏь8‹èu>jD3¢ W0µ€îØ{䃦+ן€í¿i=÷[š…*@Û¤$ƶšÆL_Éþÿq‹AV”ûEQsÿÄ·´jP"Å.V†oïß!v@¡— qøïÞ?ê
|ùÂÀpù:¨-ÀÈ 	¬‘º‚˜­|⊱á-% rÀ¶É}Ðh˜ð¨z`³
25
™¸ÆÔÈ_šˆí!0	òK‹UPñÊýÈõÿïwø‹YRÇhÕ ¦*–è`+=€Âöh¦Ž˜ŸÄ¥ÀÉ3ÿÀy8€m^FÔÁ&hÑMâ@3"”Æ%´]c3³02|ýÅÄðý'Ó翶îý«>m¥‰¡)‰€™……Í–áë9nPñÏT΃”€ø×[TSpå8\Ë0HÚà. t0•GC €°µþ€&e>}z½N˜ë?-ø€´$€¥zc¥:`„6ú¨3P‰xFŒ¡eP"`ãae“cf…'‚&¾
26
Xl+´ûÈV–³^•‰á‡Îÿ/äAÅ?¤„Õÿ?_Ch<‘Nl	@v#í^p ÿüú™á?òò0 l-hp)pìäª.×ì qÐj’3ÿddAA`bxÃÈðýt˜ð?#xp	Ã59Dƒ˜=dú¾pI=|†h&ryõǂ;.N†÷ߔ¤~1ì9Ä¢>uP4â̅Í÷ gã՗풖Иd+üþóóɝ{§fóñ‰ë3|=6JB´ˆRïƒÝ¤¿?BqÖÙ:¤¦Óÿ¿¿1tBfCˆ‘…:¥ÀK.>†?@û|þÄðéÏ£khGN.Wýž³0禥yèz9A±À3þ2ܾì*)30Èìös$ÏÃ#éàˆFŽ0¨Ü1ԋzŒ‚ùÿÑ̄&‚—Ÿþ3èªþb8r’U5!jÂ`…jú!-¡>ƒ-ZLœ‘áË'f&¯¿=ÿÿåX»$( ý~½¢_˜ÿ÷/Ãÿ_¿àôÐÒ§?Yæ?RÄ£³á뤁	‘ˆAÅ2+˜
i˜)üOd)€­’çäcøö›2©óÞ΃'M€Â5šRðã艕]ì ¶#ñÿÁBíVVÌAlC¿D1’8PĈÔ8·A€ùõÇljr¿Î^b5ìiº8ÚEäeaa–Wbg–ggPÕâdWb‰©1|;îþ±+ !€uݗ[Ààù	ÌÀˆþùáß×ß¿døûñÿo½Ã/ÀÈÿY(„TÁ0¢±±vÿõþûõ…áß÷÷¿¾šù–áßO`ñüïå3…Ø¿(8 ~|úÉghe@±àY@ògÞ¢¼¦Ae¤ãÏ>ùËpýƒ†&0×02<yYmŠÈɰ"Rà1 åöÿhÕòz˜«˜ÐÌB_s.%€j@k•ÿ‚ÊäêX\¼ó‡A_å'Ãíû‚Þ͕‡Ÿ¿xyçH?30ñþ¯Wecøóû;Ëg!?øñ²ôù0gÿúŽøÿ~£Ö–øÎRü67!È|&¨(
®>€mÿ?¿‚6™X¸™…a)
>lë€]@PnùñéÃ'qûhrßx:¸K¸z}S+ÓßϲÀà¹ÿ~ü`dbdà`Ç3"Hç"›]€‡áñk&`cõϟŠ)r2z@µ,¬ŒålPÌÃËÂÀ$šÎ !Ê
Žøÿß>1ü{ÌåïA¹ü$RP–3‡3“ë	·ÜQäþK‡OÀ’á%°¤ùYgGéL¡ˆ,Ã×ï*í#ÛW´Í;ÄD`ÙïÝûf=ûîÉ)`Ñÿó'#åːÚZRKq>€E 6°×ò‡á)°ÏÍ:Kʲ©…¾˜T
27
\½ð‰áã7Y†7¿‚þ¾öçHLjF쑈ƒÚPŒ¢ÆoÞ`Uô÷°Šøù‘aIí^²B¦rß¾|ŽÌÏ_ß¾DZn.'ˆÐŒ¸-Y ÐöïïÏg
28
Àœí:ÇÀ¾3´@DÊ@ØlìÌ/¾ò0¼ûøáã‡/Àë/¨4‡%‚Ïÿ@20νbxüÅGWwއ«g$1‘ —Œ»…ÿÿ@Âÿß_I_1Ä'.:þ–Úï><yžˆP— .ÕýçšD¹¸Å鉓JFy–2‰3ÐE¿_1üæºÅpúÙ}&öWÏ_|exÿö?Jše„FÀÎ'•?ÿòà.òqÇ2¢$ŽÿØ06”ÆšpFðpÕðïëHã“Ø¶€€8°^>{	nJ=}u–`·Œ11SðÈkU£ÕÚE³>¤È	ð™\~þŸáÎm`ÿ[2uZ
ÙCëÆaé—üg„¯4…÷õ‘“ú8ʐf×ÜÖòýÅðêïI >ÅðþÏeøÕÿÿÞ?•ae•aà½Í`¦«¬" 	à`4îÓ/I†³¯C¬$ F>Î"—#‡`3áh"·m‘Ú–ð҄Ñ5Æp¨!ýX¼a`bã&vÂ+‡ùÅÁ9é¨È–Wô<e@ۙ@Ä.ªiú¶÷Àœ|v¦?_$€æì¹?€Õ¬´ ¶"QD321`Èã[Q„Ñı¢èã†sÿjŽþÉd¸ýo
()>þƒV1é7ž2\ùxœáýWOüfø
ÝÝËý0úìË`†?%°&öF,gcí
29
â"F;qüÕ	¸
30
l¼ŸûCˆÊƒ‹Åwo€=€Oϯ1 nÚ'€"6€G.+¹þæÍÅÒÐ2Μþ^F-ʇž°/E*ÆÝ>@[+€¶¢èã}†SëNñ;ƫЛö ø?¨íY€c Ál<ÿzŸ´1öœ?àR
31
VÀðϼGŸÅav½±Wÿ™ˆ"&¦•ŽÜèc@h\OÆ¿_Ÿ	á
XBð2|ÿËÄðöÑ}†ï¬Â [ï€"eY(Õ|Ï)QmùóëëMEA†»wÿ1<|ðŸA´^Çò0j
Ånÿ_ÁpøO0⯀#šá,œ‰xh	­à€ì{¯€#úǏÿo_ÿAiÀè˯݀¥€8ö¢-çc6–Þ#zÆÇ‘0°µ
$ªÿ¿¿»‹°Ç–ˆ8Pß¾…ìcüÆ.ù
32
ù(›nˆ”𚂾œ<³¾˜—í?¨*8uò/Ão ¨?ZWßÒ1Wøûÿ0Ü&XñŽxfH.‡'p"€&¨8ȾgßîÁ#äV¤Üh02~ƒ?òñ5	µê™ÍcŶà?¾éfäöR/„1ìS€6Ÿ3üçQ`xøæÑE,rˆÔ…•àá”Y	ǟ¿¼;MŠTýg8{ò'#¸$ÀÈíT(ºüo.ÃGƐfa„G>$ç#û@üŸ…Q€ø@¿ÿûÆðþçk”b¹!/^!•ØŠh&\Ý9”êá?ž^J]­D`B®b‰ªR@¥xx@ÀÃÛ÷U<ÕÛ{oaKDÎÊZpƒ° \³õׯϷîßÿËpÿÎ_HUÀ‚ѽa¸,ú·@s>,⡑̄ƒ×ÿLDñŸ5!Üût£îg@£AøÐÃh´œV43h§‡wxqt9‘'@p—¨U¸*
gƒøÜÀH”ÖÙÀàÉ3†oÌBŸ¿¾ª+~¢'€"'ÀÆ>Ÿ9»¹ˆ“å÷1n†“Ç1|ýüØ dŒpRŠ˜PŠNý›„’Ñ1r¢€•ÿa
@¤ÄÒ{õÝIxñZ!‹ž¡}é…Çb˜1„%ò‘Zò8ÇÿqÕߨZþÄ.ÖÐþÿO2AÖïi€ñã/`Oèþ]†Ïì’÷¡¹ÿrˆÜµõày‚©s?~kа*`štäÀOð¥	|\h›?
1aºòo9ÃW¦×©ó<äÄ^üŒTB@ñ½/W0r>F)mzØÿŒø‹}ìB@´HûÖÏÇZ
33
 Ëášýƒ7
34
¿BŠ@Å?0`ï\¾.þ_~ûy…²ëvT%›+ÀUAYñÄÏ_ÞìW–:Ÿ?üe8wò'?'##ZîÆ2¼[Qȹ¢è7ÓW†›‘"ž	‰Í€Z*°`+! ½˜øÿߞ€50"E>_|îÂðã7ޱ´F!–Q=l½&ìÿÿ	
7c‹lô*’Ü?P8Ik1ü&€û7ï20ˆÛ1\½³ÿ<®@”$x¯`ÉÊò<ÆßŸËó30ܹù<èj°°`©Û‰(zÂpœ‘úùÐnZ½ùŒH¥Á$ýgßîÇÚD. l`•öе®fÀ‘{‘#—Èõh¹ý?îúþ?¶Y@<ÓÍ
35
`s>ýbdx|í2ÃO^Í××îx­ÿQÆ@ €(Ý^ž,:rbù“ã§Ö¤ó³KP{àІ¯Ÿþ2ðsáh1Ptýÿf¤ˆ„ÔéàÄÀÂgCê}è¢øÿm?0 ·€øþ׫H	¹À€Q"\|愥Ýň§ˆcº˜W¢`$còˆÀ”0ˆR¶`øl>xlüý“`xýýÛihîÿ-5öׁŠ”o³f¿ûàLµ4Ï.Öÿ‡v|VÑ@6;#jñOÄ@Ñ7ÆWoïÃ#É,Ð"	¹4@®4 %
36
]Ï~Þgxÿû5Ö6rCD|ø!Îpá©#î.!ޤnÒޅ¢Xª2v 1*›‚fT®Ÿ<¬
37
<ž½ºy‰rQ¬€ˆ	à?Ôà/
ŽóÞ|¾IX0ýýÇp`Û&ð(!3Žž¶¢G' ½¤\̍|Fìm41hÂÆõO§‰j‚Kä@äfÿ8rçœÓÉhòd¶@”’8pAÝ¿o2üá×ÿ¶å`ïahøÅ€å؀¢Ö¡ÿ |ίÐÈùýóË-Y>`Š6
38
/ú¬
39
 kþ°mÇ2Pôš`õ8j;©-€ÔØC®PÔ2!ôƒÃ¹ûq7ÑŃwº¾‹át¼	„s$‘À/b·›¡K©Û30HªƒöçcR&N_¼¬
@ jžºñZÌ|œ·4/Œñ÷çÛ*‚ÀÆÜݟçŽ@–A&ÌÁ·÷á9–ëá|ؤ	"F¤„—‡V;°ÄÂm‰¿øõáß7ðv–!¬!Â'î{½%÷#wÝðõó‰ÃÃgSa`4
40
†xò÷†ÿï3HÛÿa`gåAšÄzJ+@QûؐEßOž]÷ðÔù%lŒ¿¿Hósôw®ý`àF_Gˆ¥:ø
41
¬ÿ[ÿH95Â9Òø’Xm¨ÜD)•?þn+Ö. ¶áÆ3ò6„º”wïRŒ6ÉðÖõÿË;X퍄x®1°±pˆJ‰iðâ3 €hqîx|`ÞÒÜ£‡Ž/ågûóE脫§¿2<½÷“›©û‡e èÓ+¤9óÿh· r3#Òj p$ÿG8zb@Â0þo§±	£®‚ÅhTðúsS¢eXCV®à^áK¨JÁ7åŒ|&ûlvH ¾¼ÍÀ Ì<üÒtTœÔЎˆGD‹o.\QtôÀхñ‚ÀH%‚‹G>ƒ«6¤ñ´¢ßŒ_á‰èÿˆˆD)Þ¡¹)bÁqÇL(0³þ3|üûŠáÁ÷kx‚(¥Ã¦˜;„…ã¬w¾ÿ'¢
ÀHDߟù6™[ÉAžüöžáßÍÿ̀âÀJx¹?2Ȉë0 n
42
Èo€¢ÕÉ[ÿ`óKV—¹wÿL Ç9`ÃðґÏïÿÖOØ'Þ2ރGz"G,¼hg@R‡” ˜¡E>8 '†ÿðD¢/|9p&¼
Aäjà?áˈmmþ,%#š"F"«	9²FLÖéÀœÏ
	´??þœÍÀà¤ôßGð8ð|dø÷ÿÈÇ·…Á@ÑòÒ(xÏ u‚çÜ;÷NÕ	°CÁE`"¸rìxzµ>ÿÚøc„²P#%A€äÑJ¤*–P.}=Àðóÿ7¬Ý@ô† hX¹`ÄV¼cYQŽsjeÃ	j»å<O,‰ƒQÁ’Q?‘óÿü`ø··Á^œAŒÞÓc„š%È+¥ƒT`$3€¢õ­a°žÁ§ŽI¾söšÆÏúçhœàå½oö¿gøõæ7Fϑƒ±$ÆÿHE>4×3¢–èzà%j•qéëA¢‚ Iÿq—ùèUÄÜã<E1ëýY8u5}Åå`±¿"ƒ¥0ƒ¬Šs@¥€´Ä#ÈJ]´¢‘@ÑãÚ8x÷pņÚÃû-LäaùóEØEüøìù}oÞ^ü^M?'ˆ‘P"—µ¸g`BŠXFf`D+9‘#ÿ?8ÇÂäOنwLy&ïÁ[-”œËȀ£8ÇQõÃùÿ0$Qjô¡]PÄ+؋ü<Fi#øêÿçWþíéb`°öô´e–þGuËÄR¬	 €èuoà_è`ÄÇëk­ßÞÄðûóu`¢eFƕk_^y¬0þ1ȱéA#”%r™ÿ£ýÈÕZ$£È3ÿG‘gBJDÿ½bxôë|^eRZzþQ{)Üÿ¨AŒžþcæ|F”%ãHrÌìÀºÞЁÑ4˜ì€ÅÝÄú‹áÿ…Uÿ/.b`–JZ2¨‰…
§q–1DÏ{a%Áÿû§þòvT¸S£‚ Œç+`ÏåúÓòÇß10ý…äd&èYäÿQRë?¤À)ÿÃØŒÐ®ãh¡ÚeðºÌ
43
¬rô¸ä€žwæë6i>uø¤®Æ >x­Å ÉÿZï3"âŒ9¢ÑöB —È9íœÈD0â%€ØXsó0€¶Â‚‹ûŸþ?½ÄðÿþQ>v†HÐv¨—Xa´<	Ÿ"
@ô¾8Þ0¼tm÷] ÎÉO]ž ª`^ÄÌËÌ}÷Éw±‚*ö
44
Ï¿¿føüûÊyà_F`¸þgøÇ„šq`7™0Bs"hO #<A@#ü4qAïЪ¹óóç¯x°6೅ÀD
45
ìZ*oÇZ|ÿǚëÿcÖÿÿq4$™ÙÅtE
À9?´â1Ãÿ—þ?»	=`·ÞTåJ䬎d/òß¸@
ÄÍ¡°D/˜8;rNQúª¿*
46
æ
ÿù>efxþöCšÃ…÷×.1x-0™`9žñ?bŠõ?R€2ý‡çzh䣨ù÷^Zœû¶ÁŽ3GwQ*Ü£…¥(gDÄ-®CQ†èõ#¿
47
0ò9ž]%߀ýø÷÷þ½¸d„¸]Q’ÁJ’ëá‡Püǒá·}|úÂG° º;¶®”Åßõ͛}õæþBШ¡º0°7ðD„aë£Ý)J1œ"àúŸ	VÿËtXƒ¥î‡·˜	®µ=ÁÀˆÚH¼öó0E~‡ëXf
48
‘1<0 EÂ,£¸°©€ÿH=ø˜T€-{Is†ÿÀýÿ§Çþ]^ÄðÿÊR†ÿëý?ºÊ1n ©^N¤HFºÖ‹¨üô™`	@yy4lÄò¦.HXyðÄ¢$N6†/JœŠ/¼`à6„z
šydáÌÄĀÖòGoþƒ4öºLL˜	†	©¡ø‹á+ÃùïÛ6!¥€&ö.ü–
,ÕïôêHpK·Wý{|€áßu`„?ØÅðÿõe ƒv:10D¸s½è.Ôºžûÿ£tC‘Äþ€V]sôóÓk<×õÐ`¸=ü/¬›¸fKÓá/ï.QúdÁ lpŸút‚‰¡N»”A›_)gCJ&hä21ÁÖ_þGlÑgBJh½&¤î!TìÆ¯8G‘ÛÏ?*à)Uñ¤€ÿhâ_ž}ýЁtB©ž6ƒ»c„£¿3$ñ#]Ûö[*BMh‰á?´
49
øþãÓ+´ca@
–ÛÃaÝD†§/®o4öÌàý.Ìð@à*ӛöâªl©*ñEg«À
Àÿ † Óð~?ø”(xãÅxcœ#˜ uÿ¤† øäSh܀VŸ
Á¿1¨2[ãm¾ø©ÅÀháÅðÿí3`=
Ì\?€]˜O°7Àa$"	~ÍÊÆÀÀ/Œx`ƒ[‚ÙŒ(9ü?j䣋ÿÇL\ŒHwüýþ™öÿ¬~ýyñßt0@
¦ëãÁÃy+rOö7\*üZCúÏOÞïàŽBü"œ‚o¾¿ƒ÷½˜ +ò¦FpAА.ºü?x"€w
‰áôÏUjÜÖx‚Þs3üøÇÇÀ!ÍÅð_Fuà30!ÀÎÇ>X€ÖP7ÿ£Õ呏+a`¯
50
`ò¯ßŠ1¼z{v•/ÖË:ˆ‰ap#}ûöa§ÄSc†ÿÀzì‰è`—ï#Ç#yVvX±ýe A”A!¤F"Ò(!bÙ>ļ/ÿ_1ܖ„‚ÏŸ
51
@sÝ?h΅ޭËÌՂ¢Àâ[*†Œa‘öNƒô2þ#”óÿ£561Ős?ˆøýó/˜ýó'Ë·wž3 m	G4ظwðøùÕeâόØ~q1œüp„áïÿ?@ü›Á@X‹AX=‚ÚlìðV?¤qˆ Á‘_B­ëÁEý?¤6Äx¹÷pî×*Ìeâh
ÁçOùQ"‰ŒðbüZä!0ã?h¤ƒ"#âÿ¡ÕíØr9f[€ñ?f{àß_`Æy.æÞxpø)Òr0Œ@ƒ-€K‹SÎýýóë©Ì†»_n0¼ûóœTX58ÿ³3ð
52
þgÑùÏ ©þŸG)òA‘,åÀ‘
nàAØ0>LQrüƒÏ
p»ÌÒFŒª±o>(Bš$bÀhþþ͎¸N-÷BÃ?Lüïö–<,Á0`K<˜
AŒ¶f{àÏï¿àâÿË×7è‡B`T4¸-ðõûǝÒmÀÕÀ¹ÏÇÁ%«8'š“û?ƒ¸ÊYƒÿ"
53
ÀHäùOLh㐄­" ‰ˆdÿ3(9»ÛAŒÒ†,¬ÿ^.døÇö
£
54
QlÌ/^H1ÀO7„Eâ?¤HÁud,\-âQrý?>,%
55
6qPøL¢?~}Áz(2 Á˜ÀÕÀµ[¦ó|”gà{/ÇpþýIhøÃ Ä¢ÎÀ„œË€‰•í¿$°TÐÿÏ oúŸALýƒ 0b¹€¥×”-zœÿø¤ÿ3HÕjz30(Ù«mix}2ûˆ÷ê;Pv
Á‚œ¬¼üì(u9jbø¨÷ÿ¡ñá‘ô5Çc”Hzˆ‰|DûýrÙå+`	ðáóKئPœ7±Ãà—oª¾c¨ãuCþ®»Æ5¾™·¾_fPb×`P`UeàgägøôïÖV6°—Å:Mi€>Nþ>qÄm<Áih¢'.Ðð¤ÖÞ;ÀÁG”R€ùìÐÛµ±¤]FF,#@ÈBØZìh#‹èãh¥#¶žÀXñig¼–¯ßï¿C(Ó Màjàíû'sDž3°þäd8õæ¤ø÷›AEQø0¬…kp1ýûÏá 6\Ý?H)'¨ØÓé¨F€_´y¥Hÿ‡ÆF¯Ë‘Ψè2°´ðD0¾ÈῘž¾†W<·à¡* €kWÓ}2ýbû,ùȆáѧ;OÞ'-v#x$ájp#õï?x„3þý‡ñHE>R+‘`þ3ü½ÊðEmJCP@ˆ²æ#ÿ£ÖñÈþC+‘ÛÿЬÑ3÷ÈGê€OSfU`¸}_Ø|{
ù?ñ•4X|tðÃÇWó¥ïy€f¿úþ0<3p1r1ȳ(A"ô/"RÁl”ˆFbƒÆ}þ!ºbuÿ «‘þýG)! 	á³æ†?‚À¥°›ÏÁðùãOŒ>=F$£÷Ü0º…ÿÐzÿðæzœ‘¤4ÈÄ©Äðè‰Ã‹wwOAGWñ^Â
@ƒ9€«ýÇçNeý*ôYü‘-õ·ç>ýyëßêìúX"­*€Eúä¢)òÿ£ËAéÿ…$ >°AøÑºØ°øÎ g*ÎÀÆÎÂÀÁúŒá맟h]7ôD€c ¥ŠÀրd@i<2¨K†¿Œ’ï_}fxõNŒáÁ³s{ÿâ
56
d€Ì	<©uôÌò?¾X w+˜á?°{øåfp;@˜E‚‡‘©èF°êá/rU€T*üǬ 	¹$€>(ô¸_3¼rªd¸öy/͋onސ`8qچáýFÔÜˀmäï?ŽVý?´*µ{ˆÈõhUZ‚@ä2e¸q㿾½9{cÓ
b@
ö^FvàÄü),_…?‹?¶cxüöËïÀU‡"÷#c`@2ÿC*â‘ê~&hA­"@‰R÷Ã1Z‰ù‹ý5ÃEñf†û7?2¼y'Îpõš8¼~:•å?îǙ Г†‡Q‡šYÈÕÂ_A ‹áÒ59†7Ÿ‚Fþ¤Å7X@
ö)ήxññ°¸ÇÀìœ}¹œdؔ¸¹Ñ"¹ÞE2RΆ6ÿ""6¨Ä/þ10â
57
/h¼mÚ×Qûæ-ëëÄ.^1expO˜þá©ÿ±4Ñæ`ÃÉðR׀<¡üCiüV‰OïKªw¢'¯®Þ]ló_ý4À_H)°`
58
ã/ŽÏÒ·C^|ÎpçÓyp"PåЇDð´n R˟¥qËí¨ÝBF¤"ÿä?ùë[oÌ[Ÿ“ùä×½+WÕ.\6AKÿ°—ÿ‘ψ2lŒÞü½kËùècŒ¼Ù4.œccøþãóÃۏŽƒ¶…6ÿâó@
….Ž[ñâᓋeb=¸>È1\~~œáëï÷lò‚L¢ðúÞ§‡åò¿ˆH‡×ÿ(­o‰pÓ.Ø:ûï/ÞÜ~´jgmâ›w,·oݖcøú™™áÃëoýAT#ÿ‘ª”.+,§ÿÃ2À€¥Q	a3b‹|PñÏiÊðõÝcpñÿàù¹-Ó¾1à8ÐPIà.áô¥‰küø|FîJÃÏïßÎ=ß,~1(rhë|Fð(]<Æ¿ˆ^<@‰ìŸäa…)xßãý§çlØ×ùéËßÛ[vû3ܽ¯ÌðéÝ`wì7¢Aˆ:€Ò疈‡çúØ'ƒX¥þ²j1\»øƒáë¦o'¯®=Íýß¡îÄëA€*	€Z—};uiC>ûG™/R7ãõ݆‡¯0ð22ˆ³É!rÛ_hDÃ"­$ %Òá)ðï?äáÝ¿°Dpãþ‘ûó¼½^½ý°mëž@†k7µ‰à'ÃÏo¿±OÿCýû‡eL¥¡÷-×£6ÿqšKO‰0¼z{ïàë÷÷_AK€„Š ¡”À=‚­ûû®=xr¡\ø‘ß+†ËN0|øþŒAX
59
°þg†G4rI@jNÇjù_Háÿíû§‡Ðèƒ%Pn{3iYdÎۏOVì>äɰûÃ—?¾|ø‰6:ˆm²mBèß?Ùc`àÐ`øÃ$Ãpþäw†_øN][»”(¡	€`ñ4”,ç}Ÿµ2mÍç/o6J]Ëfàø$Çpîцï¿?1(p끍‘È]1¤6 ]þþB¿yë74ÀßN[Wñàù…Æk·tÖn`øô‰áãÛïÐÆ!–áôHÿp?Fë­;ÉÈÆðÛ|Hô¼o><8tûññûÐký4Ôl?Á—¶9¿¾ü;+{®‘á÷wV†+OO1p±ð1ˆpÈÓ¦þù
,M~ÃïÞý‹V¹Ã÷8,ÙR<çʝ=©ŸJ}Yº!žáÙs!†w¯¾Â§i‘G‘r:#úH ®µPq~W`bä`8{ìÇlG..[
60
Ôù	š~“ûA €†Z€ƒ<»qogÒ﯌·åÎ60|ùü›áâ“c"ìrÌ<ÔOyÀ@gù&Ìðî㓫ØWÙÂö8¼ßx cë3sƒ_¿g½³v[$ÃUp»à;Ã÷Ï?Q#œá?–q‚Xfÿ¡¬fäÔdøË¢ÌðíËO†íÛx½¼¼öΓ ÅŸ¡	ñ±E @
Åì‹7v>Z»«1üÿ;±Û²çê>üÍpåÙ)).
V&vªYöû$3±|eøõû¾eÖ ¹ïÉ˫/l:Ðõò݇í»{3lÚÄðþ-#ÃûWß ‹6‘«h=€X8á°+0üçsaø´iïÖwÀ–?Ë·ýg笅Fþ'b0@C5À{WoïxùæîRV`Ï@æl°ñõ‡á֋KbJLà£Á¨Pä@{ìoÕ^¼½
[fkоÑåö£w§­ŠË¹õðhÙ­Š_ç¬Îd8}Ɉáã›oï_~eøÌÁÿ@Pcë	üCŒ‚#ž‘•×ЁAЛt‡õÝ«/Nœa¸|gçÔ×<%:h[ä7	
 €bmŒŒŒC5€Ú]Áëï\nk¤å³ø7ߞ'&\üLr"Н~܆ï_Š,ùúùß7Ò{{æ¬K}ñöh®ý94Çý%à6Ð.@)#y«Ü~nqv¶Ú*—´•	Uðx!;;3x¦õhhÁ.ŽüL‚¿33<¹÷†aÞ<^†§/_Z¸=¿
¨”^@K_¤Tk4Ô¬4Ÿ¯C‰­±ŽßBp"0mbà6dEåÞü|@‘ßþ`à¸oÅÀ{:úu×ß(Ða¦ÿB ·ÁŽgÒj˜ðª{k™jfós‰Z32±p‹	½dÐVºÈ "w‹Ÿû;¯‡#Ð[,ÿ™€‰˜…áï?V†{7Þ1,[ÆÏðáó÷Ֆsÿ=hb|GJã–h8$X"2ŸC±‰¶ßÂ_üOx^ô20óaeøüç5ٍ¿w¯¾3_Haø}Uùôԕ±%ÐðÚà"Ö},ÐҔ@§9ñ;5‹
61
ÈÙór‹Y€Ò‘˜àKYñ‡àRA€ÿ#+3§8
½xÁÊpã&Ãç⾼8³épG/0òA)tð[¤ÆI~ á’¯š‚•bˆ[ýR.•g¦ÍøŸ0ˆ‹ŠËÆ/ KXI2ôç÷?Ÿ?ýbÞÓÃpëò¥)ë÷·º[ þ“ÄêŠ	©ZàbP¿’[ZTSÜL;ØULPі›CH—‰‰™Öëýtòėoï®Ý}rjóž33öz ((ý•”–?r á”º¢Bkí2VÎÿªo43|‘9ÂÀÇÏÉÀÂNZøÍ{%Í y°‘aíÞ¦ä÷Ÿ
62
?…6ºþáFF¤–`	œ($…U…5ì4þþûË=å‹áЅ… õûwh_ÖêÿNNäÃ@
·€Ü&å"¡‚ØUùyŽ>Êï`x¯²Ž…ç'?+Q~
ÿ¾{
*þ“þÝи>yyd4÷ÃêÿTp+,1°¡aÄáŽÿ‘F aŒK HMÄÄ0ül <F?aqX΃'ç›ø¸3Hž¬ÖÜÒï_ÿí„À`ëŸå›÷#k†GÏ/îƒÖ³ßð,³&í°±ƒ/ÐRTµ¼‚ÖíÏ¡-üçÐD÷
63
ÚØƒõ÷ÿ0P8æ
@ñ@.jY Å*¿›U–•¡†W++·ò'ÅT×Þï\ܬìœ,Øëþ¿DOå›|Êû—„d2€®2‚DÈ'h" µû±…Sm’÷4œ€b—ÚòL™]".¤œôõ+Ã'Å]@¼“á?Ûw`œ|P%lä´ÄZø|2÷ck†Ç&—œ½¾ù8´î­wÿ
õ€Å=@„€Ü8µºùM´ýµÍuCry¥ÜAê«Ä9†ß|~ß+fý(ËÀ{ϕå«Ã•»{§m:عšó_A`¿‡C €â €FJ@®8 
D~#M
-%wqaew6¥ÿH§w€¶V_¼½kùÁ³ŽBûü¯¡-˜k @#)À3R÷‹:0Jœ–ú:ÿ]¯—Wßa@Lñ~„6ÎHšf*	 €Fb€•ÌHÝ/v(fƒŠ3@[Ø?¡‰ç¥KC=ÐHMè-m´{Æà]´¿xÎ×	 € Ä( Ôý–÷Ä8šF60‘"‡ÇSíŽIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_away.png (-4 lines)
Lines 1-4 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsd_‘gAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFIDATxÚbøÿÿ?.Ìpõ‚ÕÍ÷³nýþßyóç×Õïþó¤Þ^Ï"q̦ €pj–¸ñÿì7ÿÿûûïÿ¿ÿþß»wïÿ—oßÿ/¸öþ¿xúõÿ,Œû@ê«fîkÿû¾ýÿÿÏ?ˆæŸ?þŸ4iÒÿOŸ>ýÿþýÿ£Þýg
4
¾2Ä €˜Ðã5s†‚pÿ É?þ0üýû,4ÌVãþËPY(Éð_š- €0‡@®ÿlŒ`× ¢Aø×¯_ЬªÄ‚¡ýç?þÿ¾|ùÎt2úuëàR0>|øÀÀÇó‡AZ” €0
øøçÃw!fnnn666†øøx°&K`˜ƒƒƒ•“›áûŸ„¯Øñä7Ã? ›‰‰	îo¿ü‘‘áýù¯Ã€¡¼ö|àð«¿`…ŒŒŒ`ß¾}ƒ»€™“¡få†?[ 2|:÷©0«õñ‡O3°rÅ«W¯ .`çehÞõ›á|çÓ¿ÿ9, FpbÀXY°Ë²÷¤J:¨p2HIüg8yñޞíþ0á÷;›B:€ÂiÜ ¦ ¨b ~Ä ›À䈠„@11PˆbˆbyéL5òQ[IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_blocked.png (-4 lines)
Lines 1-4 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsÒÝ~ügAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFšIDATxÚbüÿÿ?% €X9mPLë¨
4
`0»¼u=†ˆ &týÜ
Áøò¹}ÄÈ6gmÚyLÃlÇ&ÄÄ@! Š
 Š
 Š
 Š
 Š
 Š
 Š
 Š
 &B)@¡d&ôôÊ©°äŒ-o€@1RšLF&œ;ì®IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_brb.png (-3 lines)
Lines 1-3 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsÒÝ~ügAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF7IDATxÚbüÿÿ?>pðð±ÿß¿ý`øþˆ¿ÿÒß~ÙÙIŒ y€bb ¾~ûÎðíû†o@C¢"’¢ÀÁ@±àÓ¼mÇÞÿß¿gôAÿ4¯¾}ÃÔüï߆ï?^€lGÿücøÄ?"¼@x
øu*ÈÖ¿ÿ1üþõ—á×o þõ® €¸àØÖß@üë×°æŸ?A4€ÂkÀP”5‚lþ	2àĀ?¿ÿÀÕãýÛ°í?þbA¿QÔ~üðl;ÈæþÉ]j¯¿~ý&¤_=:Àü93úÑÕAú&uaÕÄH(/ÄÄ@! Š
 Š
0‘ô¯r"žM2IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_busy.png (-5 lines)
Lines 1-5 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsd_‘gAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFÂIDATxÚbüÿÿ?.ðÿx|Ãoˆú—§ƒùoΟax{ó×׾¾ýÇp÷Á€baÀì;pÿðáøWÿ*üùõáï/&†?¿þüüÏðãφïÿßn F|.`dddØ9wW0ߟ~.®ÿ ¸Üã‡?>}c ü.‚_?ox÷¡_TN„KPWB,~îì–
1µQˆ‰¾YÞ^½þÚøâÉ7°‹@.>¾é܇ϟ4‚ä,€#ƒóçß<rùÿ’¶•ÿ{r¦9ÀĈ(¦–Î5¸vðÊû¿>þyýÚÿçkb;@rDÐ  m¨<_ÃVK€áÓ-ѳ¡!Šó~þü[’ ‚î c­eÀðÿ×GÌÌò/$8çƒäo,LÓe°ó6çb}Ïðþðj†Ÿ··3üÿ-LaÂJÜZ¬5
4
¯šž!
5
Š;8870|fd`—?Éðp÷W†Ç~2<½÷hC?@áMH¥bŒ €*À—V¯Ä€bb ÅŌծ=¶bÎIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_connecting.mng (-28 lines)
Lines 1-28 Link Here
1
ŠMNG
2
3
MHDRd,ô\¯
4
TERMÿÿÿϗ“	pHYsHHFÉk>BACKÿÿÿÿÿÿ¡)bKGDÿÿÿÿÿÿ	X÷Ü
5
FRAM1Pó
IHDROc#")IDATxÚݕ]L“g†MÌÐy ¥Ãœ'lè„ETHšiLLf$ˆH„”*Õ¶+á§©l¨±ü&¶¥H‹s T$2Ó ¨H¬!®tÙVX€ÆDÁ¶ëGïõɗ¦]4™f­'Wú}é{_ïû<ïÓU«þ¯ŸŸÓ̜¡T`h©)·a°Û;:nÝÆjêÑÀdߏ‚'à­ºrœ½8||c}õ§Àü|ÿ͛€ÇÓÔ$ùümۈǎ…†­ø)éyoQ Orc½Ú,/?xPVFA
6
ÅΝD±˜=žŒ–¬ÀÝ»\îöí^úúÆF—ø©à±p%ø!äá‡î	`”;Êe\ÿn86Ô¯èéfg
™Œjj"#‰r9˜“óOÔTbwwllHˆw}£ÑdZYd2æùs@,–˹\¥"ê¢[ƜïÖ6ëçîO^êl¬Z-ü†Öë‰j5äÈÏg™•(`·óx»v\¿ÞÕåtR©ZM"|þ¹s@R77"±ÛйùéÀ“ǏޱUKmml,-ÜЬ¬TTlÚD”ˉLÆá–"-89)‘p¹^?¿~š_€†½ža€¢¢ÆÆ/€¼<¥òÙ3€Ç“JIäðáôô	oiŽ­¯§¶¶ÎσƒÅÅqq€Û]YD,/gyáš5ÄìlúÎ0|þºu~ÁÁÌ̄„€5õ+¨æW¯êõÔ>‘S§ÊË­V ,L$Ú³NI¡æ‰¤Ò{÷€ââ3g¨ÛÝîkר@VÄå*-]»–(“Ñs—K$bß?NÏGª«~+v¼¢Ç¾íÕõ-ujõ;í¼¶öòe€Ã)*ŠöÞߍ%’Ý»ýûÅâÂB   +ËlöïÈ鬫£‡C¥":……¬+À0—.ÑïmfãxזWøîsmìWçÿˆ’“µÚÊJ:êjð‰„…	…ûöù®\9{6?Ÿ‚ÚÚ¨æþ“()	¦`†z…a::ÒӁá“íʲìטßm6-23F
7
W©vì ©”®[r²P¨T¹¹©©:_ÀǙƒaï^ˆ'›øh¦kKÙÖ×°åýš0»ÐjíöÒR &¦§‡Ht´N8ÐÜåï	·{jêàAâôô¡CdŸ3ŒÅB'gk7s:ßdV˜B+ځӧGF¨†II}}tí22îßßêÝɉ
õ@³BÅQFPí­ÖÀû‚†‡àwý”túË7pÄ-»™¼]ß«çKzýÁ>
8
Þo‹ïòŽbóRÌ_«sÚíÁ‹sþ¸\Õ~ü‹ïãÿá?Àpqîö»Bï	9ÒÖFGki™ÐZ^^xÎ1»¸TF“ô!oö3¿ ïýßH-›b&¨ºIEND®B`‚FRAMÝØ
IHDROc#"2IDATxÚŔmL“g†IÌÐùC1J™†9ÿ°øƒÄXD%‚¤™ÆÄdF‚ˆDH©R¥]	MeCå3±-EZDؘ£BE"3
JŠ¤ÀàJ'ȶÂ,0&
9
¶]Kï½gïšvÑd’¸¬®ôýxîëyÎyOþúü_üÏþ1ÙÌéOúë³ë›­µõÎ`¤ª&N	Lt/xj`ž|[Î,G.½»n­«ü˜›ëé¹}ðxêë…B"Ÿ¿mñĉ i=?1%ç-
10
t‹o­S™€¥¥GJJ(H.ß¹“(Q Ç“šÊ’¸ŸËݾy³¶V«u:òžd,‡ß}膹Ã\·ø·à‘þyg'03c0H¥PUN”ÉØÀ¬¬
11
$%;:¢£ƒƒ™ŒF“iyJÕê/‘H&[Xd2¥’¨‹lq¼X›­Ÿº>zU¨M[±*ã+ZX¯‹#ªTlW 7—ezº¿€ÍÆãíÞí'póf{»ÃH$*‰ðù.ÌÏññ<Þì, …ÄCÛ¦gOŸ<~g´°Xª«££iẺÐP`y¹¬lãF¢LFôx¤RÇ¿ÉÉĉ	±˜Ëe~ÿòY*~êêôz·((Ðj_¾rrŠçÏO"!‘£GSRƙÒÄÆ?^[K5ljš›úú
12
\®òòÀ@bi)ËK—V¯&ffÒ·›Ï_»Ö'Ðח–ëׄ¦À9Õüúu½žzÂ+ræLi©Õ
13
lÞ,îÝ%&Rs	…Ƀ@aá¹sÔí.׍l +ât¯YC”JéºÓ)²÷Ož¤ëƒ•¿Ú_ó|Ý¥ë^lTª{÷ìvÚyuõÕ«‡SPÉ|¿6ˆÅ{öŠDùù@^^zºÙìۑÃQSCv»RIt8òóYVÀí¾r…Þ5ÇÚ·¼FÀ1d‡‡	¬Žþââo@B‚FS^N'PYI^ï‰x®];>7—‚𛩿¾“(*
14
15
¢`µšzÅínmMIN·(J2ß`|³Étz¸HK3) 4T©Ü±ƒ$úÜ22
16
 ;;)I§ó	x9=m0ìÛGB½½11$0:J|<ݾ¥dëŒæü;³Ðhl¶âb *ª³“Hd¤N:ÔÐáë	—kròðaâÔԑ#þd¯»ÝËþýL	Z̜¶•LÂÊ<SHYpöìà Õ0>¾»›>»Ôԇ·2;9uJ­¦h+9Š0ª½Õê¿coðüüÀ€@üªŸ”L}¾%óbÔ«˜®ïÒóÅ]¾`/ï7ŽÄ´3£øïçÌÉwû.ÏúJàtZ,Tû±Ï¾3Žùڊg¾7àòìÝw3˜8v¬¹™ŽÆÒ8®±¼:)gí3‹%4I‡x3Ÿø½÷ÿ ‘Ï䑧IEND®B`‚
IHDROc#"åIDATxÚ­•mLSgÇë>,d[¶˜A¥ÓYQB&ˆÆ8̌ÌÄı,XµB•Tފl”¬b¦)FLX5ØÙØ´ÕveÄÎ
17
Ò°àt
18
Z;e«
umxëKÖV*°ÿž»¤Þ}éûÜç>çwþçœç0ðÏÃ`DkƒÁ'µslÀ»ÜÉvƓ¶ûúa%à¼mÚõ½
˜Ú5ê~ÂÅa5‘ÿíеݝ4ÿxæ8mì°]C;œœ?óŽÐøS«5o~¹-ú©8†Y4@$CÃál<`þ’9›
19
Üx`°ô6Éù7÷_ææjjÖ­£l~>‹Üù̖ÚL. ùō—9!-Ð(Tí	¼N€>Ôqîô’§$’­[)Çååññ”årãâ»dûÃå€±ãºÆÖú(†ÿ	͵
/Y‰Nžôû™¬­-:;e2˜ž
20
ÓÓ)ð¥í	%^$ëïkÕM¯EpÃrKõÔHuu> +•¡pîœVët÷îÕÖr¹ŸO<‰)8ÿžƒ°U4܉àú§×­3@IIUÖd.PT$y<´'N¨ÕÔ{{»D"—¡Ÿ¿l)V|Îxw	0záÛã_ýÀ@ñ€y¦`³ËÊÚ=:4ðù
21
EG ‘;f0GiéÚµt-Ø4Ê·ZÔQŒªøƒ·ˆô+ªçû‰ÔéKxŒBò•Ū®ÎÌÒÒ¤Ò¼<€Ë=uêÈ ¿¿®nçN҉¢Øà’ö2;xô}ðÒþžÐÛ¡›¤ètÍLÛ#`éR`ýz€É¬¯§lv¶^Ïá§OUU€*—ì³÷èdùÀÌÙ@ØÓò~Y`Ëì,é[×xÂL
22
É]ÖXlð0ðëýÝþnÀ‚~§Û
T¾úuYÛ!`͚ŠŠÂBZ‰ÄÄææR+{÷îØH¥&D>²Âò‰˜\XÁ/½ÞÇãϸjýù‡©NÀ(îK™/l
WÌ£®ßi%øÆÊšd$9Y*]½šRÂl^µŠê–¾¾M›€GL&Qðg±gßxç¿"9YÈáB`—÷÷fº“€³ß´h¯‘šàeU&Iǀ͛Š
€œ³9!ª‰îî•+¹½ëQ	iWŸÅ3ïÛö"R¿,ˆ6NŸoý´¡üPî¥7H›2šåäÔ¼¼®.ê*ŽØƒöŠÜTz†¼pºÝüèn©Ïüâ”<³zZíd4í–?•T”i¾Óg0AŽR¹'í+ƒœ¦-ÿÃ0Štƒ»Ç{fBI¿GÀ'RÜþ)2Ü!730
±¬5Ã^z_伿5°—%&WÜIEND®B`‚
IHDROc#"åIDATxÚ­•mLSgÇë>,d[¶˜A¥ÓYQB&ˆÆ8̌ÌÄı,XµB•Tފl”¬b¦)FLX5ØÙØ´ÕveÄÎ
23
Ò°àt
24
Z;e«
umxëKÖV*°ÿž»¤Þ}éûÜç>çwþçœç0ðÏÃ`DkƒÁ'µslÀ»ÜÉvƓ¶ûúa%à¼mÚõ½
˜Ú5ê~ÂÅa5‘ÿíеݝ4ÿxæ8mì°]C;œœ?óŽÐøS«5o~¹-ú©8†Y4@$CÃál<`þ’9›
25
Üx`°ô6Éù7÷_ææjjÖ­£l~>‹Üù̖ÚL. ùō—9!-Ð(Tí	¼N€>Ôqîô’§$’­[)Çååññ”årãâ»dûÃå€±ãºÆÖú(†ÿ	͵
/Y‰Nžôû™¬­-:;e2˜ž
26
ÓÓ)ð¥í	%^$ëïkÕM¯EpÃrKõÔHuu> +•¡pîœVët÷îÕÖr¹ŸO<‰)8ÿžƒ°U4܉àú§×­3@IIUÖd.PT$y<´'N¨ÕÔ{{»D"—¡Ÿ¿l)V|Îxw	0záÛã_ýÀ@ñ€y¦`³ËÊÚ=:4ðù
27
EG ‘;f0GiéÚµt-Ø4Ê·ZÔQŒªøƒ·ˆô+ªçû‰ÔéKxŒBò•Ū®ÎÌÒÒ¤Ò¼<€Ë=uêÈ ¿¿®nçN҉¢Øà’ö2;xô}ðÒþžÐÛ¡›¤ètÍLÛ#`éR`ýz€É¬¯§lv¶^Ïá§OUU€*—ì³÷èdùÀÌÙ@ØÓò~Y`Ëì,é[×xÂL
28
É]ÖXlð0ðëýÝþnÀ‚~§Û
T¾úuYÛ!`͚ŠŠÂBZ‰ÄÄææR+{÷îØH¥&D>²Âò‰˜\XÁ/½ÞÇãϸjýù‡©NÀ(îK™/l
WÌ£®ßi%øÆÊšd$9Y*]½šRÂl^µŠê–¾¾M›€GL&Qðg±gßxç¿"9YÈáB`—÷÷fº“€³ß´h¯‘šàeU&Iǀ͛Š
€œ³9!ª‰îî•+¹½ëQ	iWŸÅ3ïÛö"R¿,ˆ6NŸoý´¡üPî¥7H›2šåäÔ¼¼®.ê*ŽØƒöŠÜTz†¼pºÝüèn©Ïüâ”<³zZíd4í–?•T”i¾Óg0AŽR¹'í+ƒœ¦-ÿÃ0Štƒ»Ç{fBI¿GÀ'RÜþ)2Ü!730
±¬5Ã^z_伿5°—%&WÜIEND®B`‚MEND! ÷Õ
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_invisible.png (-4 lines)
Lines 1-4 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsd_‘gAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF%IDATxÚbüÿÿ?:`ddÓÆÆÆ@\¯ªªêðêÕ+†—/_2\½zõPªðìÙ³@jˆd:†jNX¶lÙÿ_¿~ýþüùÿ{÷îýðàÁÿ3gÎü

ý’© ¬€lž9sæÿß¿ÿñâXóÇÿ?yòäÿ³gÏþß½{fˆ@11`ÂÂÂùIIIoß¾eøúõ+333³²²20”••”ÖVŒŒŒ@šŸ>}ÊpàÀ†sç΁
yôèâE‹€®`ÐÐÐ`ÐÓÓs ¬üùó‡áãǏììì+W®dèëëc`bbb8tèCOOÃîÝ»Á.QRRb ¬ý
‹‹/2ýË ¯¯Ž™#GŽ0(++ƒ5‚¼#$$Ä@,؀¦¹¹9C~~>ÈK`ñŠŠ
4
†'N0xzz2üøñƒ €°ÿþc___666°jjjšššŸ>}{‘——— €pðýûwpX€ür.È07@â0xxx« T7oÞ<°mmmtttÀšé‚˜¨ÀÎñ¹¹¹«@';£ñ0.\¸0hˆˆÃ·oß@†\^#0­0Åâˆ_^ðóó'5Ùý| ÕVHÄÄ@! Š
0ñڏû«IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_lunch.png (-5 lines)
Lines 1-5 Link Here
1
‰PNG
2
3
IHDRóÿabKGDùC»	pHYsd_‘tIMEÕ	.ÎU5Ë~IDATÓ¥“1‹QFÏ,‰F¬¦Ú…h¶¶pš4w
4
IHa¹­Ø¥vÿ‚ –Icagçgd-R¤›W‚Dt±Ð™›"버Ýqa¼â}\÷Ý˳T•§°,ée³Ùët:í„aär¹ÛÉdòYD~4
oµZqAÅbñ‹mÛN¡PpÇù$"WžçyÝn—r¹ü¼@Dœv»ý^Ué÷ûÔëu€ŸÕj•L&CE‰|u]—8Ž‚f³	€ëº‡DA`00›Í°mû¡àx<&
5
~ÇcŒ1c˜N§l6›?§‚8ŽAUŸ<§9ˆHOUUD¾‰È•ˆôF£‘ªª‡CM܂ïûÁ£«ñ}ÿæóy°\.“×ø—÷ÒïÆ˜_ð¯û—>äóyçþY—À€Ýnw^P«ÕޔJ¥S´©Tê¼ C¶Û-ûýþ4—;àmET*Rç‹Åâ¦ÕjÜ<ŠNçãz½¬ç>ÓK¹à•¼ZðD>¤ßÇ_IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_na.png (-4 lines)
Lines 1-4 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsÒÝ~ügAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFùIDATxÚbüÿÿ?% €˜(D±D±ÄcTÎ;Dt`<|õ‰aY…#ˆ
@,ÈíIvDձΠtIFFƳ×_~føù烁4?Ãá{ïl•„àò«Ï?QÆ0>@a
Mq^†ß!>úý÷˜Þ|å
4
«'¾g0•³ýhðՑÓ?ÿ @X
øóï?Á;oPl\~ö	Ё0@ð¬	ä…-W_‚miiœsìÃ4/rÔ@Cט”t@Œ”怢8%ÅŞ\		áüIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_newmsg.png (-5 lines)
Lines 1-5 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsšœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF&IDATxÚbüÿÿ?% €˜(IJðøŸÿrBÿþ1Ð5ÿþAñ4Ìf@;ÿ;@±È128¨3£˜
4
óÈwÿÑőÄ~þþÇ@,w^ýaЗabäfÛðI#2ÿ’ø¯¿o¾þc8u÷@±¼zaÊKQ#5QKU6VF°Â¿PüDuÿÒ?þ00|âí§Þ3\¼ö˜á×÷ĸóÊÏÿªÇ¯¾`؛…ÁJG˜A_‘á7HÿÑ@.ÞûưóøsU‰_úºÒÇ®þb mlllö†rÆê?¶ž}ÍÐrì'ƒ¹®ƒ¨Ø€×ÿ0œ¾úЁèÍ0g>a†_`ƒß0(4AdË?f6uñ?†ª"÷ß30<yý‹áû¯?<6ڌ¬ì¬pÍ?áðèG€bE	Ȗ@âÙËWBb’ÿYؔ8¤% 
5
A~ýdøðñëW/8øEa´ô?@±üšòˆß~øÄÀ# Ìð—‰Ê?ÿABûŒbf.>VFv AX¸À. –_@âË÷_l@É?L(š~"i†‰ýcfg`ædaøúíØ€b¹ñèÏß,@Îo°È@
rˆýY̆øýÐËb FJ3@Qœ™ˆbk>ˆq^ÐIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_offline.png (-7 lines)
Lines 1-7 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsšœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF©IDATxÚbd ”””$ÕÿúõKáüùóΞ=k@,ÄjnnnžŸðþý{†gϞ1033+<yò¤ €ˆ2 µµµ?:::áŋ¯_¿føóç'''—@1Ҝ””ä`ggWðáÆϟ?3üþýŽyyy
ˆåÑ£GÿA
4
_½zõ¨`Ã&&&&>€ ¨¨˜/!!’kún€¨¨(@1]¾|™„¿}û¦ ((X ££s¿»»»fPQÀׯ_ÁAä|f
TÏ@̦¦¦
5
bbb?~ükúd«Åÿÿÿ€þŽ ÒððáC†û÷ï3ܹs‡á˗/¬¬¬`õĬ¢¢rHg°±±qÀleddd‘`bbR¸wï???Û7oàèM8@1Ÿ>}úЏ7yxx"@¦‚4ƒlÑoß¾e¸uë777Ãß¿Á²ä%K1ñ €˜A6^¸páЩŒ@W8üû÷¬Èfààà;ûÝ»wŸ>}k===†ëׯ33Ìٗ.]:t#0´€4ÄÌÌ À' pÅ?(V@iÈç fä8¿qãÆyyù‹Zªvï?=‡6HÃãǏ

AáŠ{°0Á^ fô„sóæÍ9yIJJJ
6
?þdû_QAAZZ¬ä*P”
º@ÌØRйuuu@ár(vm?t…™“ƒ‹›•äaaa·gV€1óhúC`ú'"Pèß¾suæ‡O¯3ÞQ&"	`
7
~qäȑD€b$€þžt®0¦8p]
@€Ë>Jc7i½ÆIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_online.png (-7 lines)
Lines 1-7 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsšœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF%IDATxÚbüÿÿ?% €X‰V¼¬¸2AAM¶^Z^TáÓÝ[vì}@,ÄhœÞó]@ü}Á|;oƒ¡‡Öla`øü]àè;å~€"Êá÷óÝ]58·30<xÎÀð".ÇòÎ €˜æ/ùùÿêµ?ïwìþ¹¾­í{ºæIé¡	vv’œ7—mjf
4
21Ðçl?Þ2“œ<Ãâýß¶žøð—ó×üÙó¾Ý{ã3@N–±^ì×)†¯!Aän&U5Y€b¹y›a¦kÂÕk¿¾øÍpñò/>†ý¾nWCŽ3¨
5
/P`øð€áÿˆ»™&03‚
`äb ¦çO™~°0ˆ±(Ÿ3ÃÓϟ>óžš/¢0ÿË+&†¿ï_1üûù™áߟ/|`ø÷ë3ЀϿüa ¦æZ¦oýmâfbca`~Ép†7†áëD†m§N3ìy’ÍÀÀÁÈð‹‰áˆâÿÌþþ¢dò €˜@Ϊ*fox}ãû^^F†B[þJüf`gg¸úýÃ×JGŸ›2üggjf`øÏ
6
4ŒšúRêˆ	X\_¾8ýþço6 +€á$üŸáÆ¿}lì—_ZBüœ̚¦f_þ x:(nø¤»—ï]Ï+æ°óÇ.†¿_¾1\ûº›Aöƒ1£0Р9ºZÿ¹€É_ô1Ócþ„‘îßz<ÑØJ(à*ÓO†?’>þ_Ê u®•Á؈‰è„¿ÿ~ÿfø÷ã÷ß*ˆÝ€Ó6<дÓpz§ÀÎùށ›ëÃûß7¾Ÿqú ¥xƒùïÆŸ¿¾üÔbر« €˜°¦ÝMáÌÅ/ðüdb`ÚøóɃc'5î?ðúþo†¿*w›o(ŸÑq €pfÅ܈/­×ÿ–½åÀvÂeÁÊΕ‰ ñ%
7
ÿÿýUø÷ïÿ…Å{>!"\PÞ!ŸIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-action-msn_phone.png (-5 lines)
Lines 1-5 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsd_‘gAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFIDATxÚbüÿÿ?© 0{¯‚‰…Üý#o1±šJòüý÷×àϟ?¿ÿ6àd‹#1.(Ë?dðùëçóØäˆ(€4w÷»2üùÇÀÀÂÊÆðëÐ
å[ˆh/\}ð˜áÍï7/}cøùíãw°8@mÀ¾w÷ÙN3lgÙÎðäç§³å@Q~€"ڀó,'šž×3|ÿóáßÿ.|Œ`q€"Úý—ÎIçù™~óe0`r`8ÆpŽ €ˆ6ÀHUAœK’á?#ƒ ?ÕۿÁâD´Þ}aøúõÃËW>
4
r0|øIÄD¬¿ÿ213Ã÷ï¿þüF'3X €ˆv77ƒ$+3P£Œ$'Ãós/ÑüÿÏÄp÷þg†¿™nÝyÉÀ%  ¢’rhèâ~¡õèâo>¾[@ŒääFd@L€¿#€C“
5
†«IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr16-app-msn_protocol.png (-4 lines)
Lines 1-4 Link Here
1
‰PNG
2
3
IHDRóÿa	pHYsšœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF%IDATxÚbd ,+®LPP“­—–Uøt÷և{ß1§÷|_0ßÎÛ @èÁa†5[>8úN¹ €ˆ2@ø}Æ|wWÍÎãíž30üˆË±¼3 ¦ùK~þ¿zíÏû»®okûž€®yRzh‚dçÍ%@[šY‚Ì@ÌÈÀÀöã-@1Éɳ0,Þÿ]`ë‰9͟=ïÛýø¸70ädëÅ~b`øñ¢„Aîfb`PU“e –›·hª±&\½ö›áá‹ß/ÿRácØïëv51Ôé8ƒªð†þÿ‡¸›‘h3#ØF^!€bzþ”±‘郀8‹²0ð‰03<ýü‰á3ï©ù"*ó¿¼bbøûþÿŸŸþýùÂð÷dž¿>
øÇðüˀbj®ezðøÖßF!n&1fá—gxc.°NdØvê4Þ'ٌÿ¸˜þh þÏü—áïo !J&ˆ	䬪bö†×7¾àåedx!´•á¯ÄoFqv†«ß1|ý§Äpô¹)Ãv f†ÿ¬@C€É¨©ÏÀ ¥~ €˜`ÅõõGà‹ÓïpþfºNÂÿnüÛÇÀÆÎÁpù¥%ÄÏ ÌÉÁÀ¬iÊÀ`¦ÁðåïQ€‚§ƒâ‰@ʱ{ùÞõ¼bŽ;ìbøûåõ¯»d?30
4
ómš£«ÅðŸë?ƒèc¦Çü#!Ý¿õx¢±•PÀU¦Ÿ$ÿ2|ü¿”Aë\+ƒ±Ð	ÿ10üþÍðïÇ?†o¿U.3º§lx i§á  õNó7×'†÷¿o0|?ãôAKñ:óß?Œ?1|ù©Å°cW!@1aM»›Â™/Š_àùÉÄÀ´ñ;ç“ÇNj*Ü#~àõýßTî<6ßP>£ã@1âJÿ¹;^Z5®ÿ-{ˁí„Ë‚•+Aâ	Kþÿû«ðïßÿ‹÷$| Æÿÿÿ3Pš4"Vå'IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr32-app-msn_protocol.png (-7 lines)
Lines 1-7 Link Here
1
‰PNG
2
3
IHDR  szzô	pHYsšœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFÕIDATxÚbüÿÿ?Ã@€b¤µSs&ü{´5^BQÉAJüë7ÿî=ü¿à¿fQaI³Ô€b¡•ÅÓ*¶9°¾XÕ¯­pÉÀ ¸žƒ››áú1†›§i‹$¬Ü6U¨, €hÓ²Ûûe¸.8§1p2þe`8ºŒáȆOß 1¾ô;Ãc»†ÄLU‹»¿	x©s·6ÿ`ËÀzÿú& ¯Ï20üúÃÀtÌÿÿüa¸õúŀ¢š¦v~`xÜ·ßÊø“¾-ãÁ>†“k¾}ý;#ÃÑ÷ü?ˆjiàßã–~S­—ú&6;+^¿```J0C“:CPœçÿ€b)*ù¹_@è¿Óÿ¿ýððþÿ‹Ö†œRó˜kù¤šýbßëÌl£®.a`øµÙbF$^V€b•bpÈLee¸÷äŸÃ¯Ÿÿþýf`xüðgÿ„	ß/<yÀ0±gçBøÿ¼»ß%Ú¨qÃË«¨¾Fvªþ¿»É@LŒŒLßþgXµïÃò?lüÎpäòO†?ì¿
4ÿ͟:õÛý¬´¯¸,ŸP:'AM ÷†g§Q-eÆá(åc ¦_/°332pr3ó*31ü&؋7~3ì<üáò½ï
4
’ŠÖ§&¿]?­ç»FÜ:˜oh¤ÀÀðö"ÐK¿0}‹'ˆJŠ3“ãÄó—þ3ÈË03pò03ppÁÅÄÀÎÅÌÀÎÉÄðæÃ?†“0ü`øpæêÇó™I/`ô6¼Pf½b &4ýóC„™pDr:vN€b*(a^pçãyq …Ü `††#˜r¿ûÂÀðþû…ÏŸ>íO‹l0òë¦ï{ú•¤€Aÿý)0çíÿ¿~2üÿùáÿo þ÷’ï°¥ ø" Ë@àlÈÃÄØøàÃ|q&†ÿþ1üýÏ̪¤þƒé¿@Ìγ~|ýÏðñ+§€*Ççýb’|ÂÂ&’¯VÜ?ÇðÿûoHAó	ÿ:îˆfb`úÇÆÀÈÈt#Äìܯ>±38Fò‹™<¾ÃpA˜99i€“‡è†($þq¾`xÁ±€áЇ	·ßexù‚“a×ý4 Ï–³È;,@uH˜d!0wýýÁð÷ûG Gþ@  ÊÀÌÎú €àIB‚‹!ñʉ¿ÂLà„È	ŽXt03<a_Æpš9žá9û†çL'v]ßÉðùãoV·?ª€ãÿ+ÈR¨c€Cù qˆCþ3üûñ5À`‘V`xüì݀‚; -Ÿù×Ï¿…Ïoüaà:‚áˆì§n²ÏÆÐn0¾ùù$Ãß?ÌÌ̬ïf@‚–bñ:â?˜
v347€Ø¿¾1¼“ÐaxûêóA€bBÎRE•\¾<ü¹àÓý_\¼ÌpGÜáX
±œ—îˆ7ÿ1üdøÎÀÄÌÌðò»6Í÷Š`_þg††<Jñ¥Å%î>zÃðI2ë@1¡çk>Ö¿…on|»ðûР´tĎ+L@‡0£†èF`š`挳Ÿ¶3°°°C™áÀ=””f´	„Ù€‰Ñ*€UR˜.~? Ôfûãøääû¯n|aàúäç7 ¥@—sþg`âüÄÿÁøì—MÌ`°2\{eËðý7R6ûLõHù$Î/ÀÀä›ÏðÿÇ9í œf@L؊גFI #þ:þ¸ûqÁ‹SoD¸„X8þ10-gfÿ¡üo̯ý¾ÀÀÄŒ
5
†sOu …<ÐÎó˜x˜
<˜L‚€åÄq†ÿ激!ÌæÀ,@L¸ÊøŠ6ù”™>}+Œ—IfpT²d`ZÂÌl€ùÆ'¿/‡È·_i=ô9ÈPÌ,
6
,¦¥åþ³?dø'y–á¿)0>ؘþüúËðïß_€"Øh¨6!ɾ,?Ú(Jáè“C@À¬Åt=Û? þËðúçU†gÿ.2ð3Ë1<ÿ¥ÏÀ`¬
ßæs~pÁôOˆB@Kÿ9e°´düû—áÎ}IP< &bê{ŽËZo0ïgp´Va×ùÍÀ/ý‡Gò/¯Ì_Ió헃â/F5&A&%&! -
7
Ä ”ÿû7Ôr#@®úÇðî-ë‡9›ÃQ|©·àê¹Z¬*BBdõÿ0(YÿfPqþË cð—Qá:ÃgÍ
’²À‚æ7ÄBüŒŽ`:âÏov†¯@fQhfôà×eñ¿>|aýÍÍÀþí;°ìc …l?ÿ0|5]Îp›uÁ‡s">¿gDu(Øÿ@hP(ügÕa8u‚i#Èl€b"¶Ù%vß»ðÖîï”ÿ+ðŒÙ€˜h90HA•×S†k^¿ú›xö¤È‡ß_~20þúÍÀø‚Á!Â|ÇÏ*}xõ^dÈ\€"Ú]s­>žKp|tˆéƒ(°"ù,ºu€Å;ë')†–9©Ölrܺ]ýÁ—·ß€UóoˆÅ ßÿebøð߉áІ‰wÆ}é ’šåÇ/.xa'4yçGƬâï9þ2ü†Ëýþñý†ÙÂK§N8{cå~Îʅ7nKüüðæ—ãW.^q†/,›·‰_(èI„é ²zF¹Û
ÞkÏ_ÿ]w¿/$¿>äbÛØk8kcÐtõ	QÂíŽß€,@dwͲB6|=ÞÿMúTÂ?Þwì7­6,›6%Tsˆq »ç¼ˆ_ømdrúIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr48-app-msn_protocol.png (-19 lines)
Lines 1-19 Link Here
1
‰PNG
2
3
IHDR00Wù‡gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<(IDATxÚbøÿÿ?Ã`Åb:‚Ña½Z<|2b¸Ô#ˆL@^ÞXQ_JÖÑBIÙCYJÜFDOðçÏ_oÞ¶gë͛ˏ^ضY=@
ð
4
ȳÇ{e”Ù	¾+R~' ìæÍÀ§nÈÀÈÌÄÀðãóÓGÎÇ0óÜó¢Í»úûaúhPx Ü·4ÖIä}‰•©´žŒ±!ƒ ®-Ãß?g·10Ü9ôÀvv†/^0¬»%ù¶rÏÇϯ\é –t¸²’™lˆ¥Cm®5_ª¢
5
ƒ´{
6
ßßç710_ÃÀpïÃo`31Uÿgàge`°e{+ìmXÁÌ‘ø÷Ϗ_4`000¨‹Xf*}QSÕۃEJáÆ~†C3žÜÆ0épp2003"4…Äÿ?d°àþºELµ(r €ÄÁÍ.•îJ,^J˹”30|ÿÊÀ°­šáæ!†o߀Ʌò@‡ÿ%rpàCÀ?.v©÷§X%x
A &z;ÞÄÐW?ڈkµ%Ðñ/®C½ƒáúf Céž
èxFFphÃ1r©ÃÂÄ Êÿ‡A•Q…ˆ®1 ©í'\ä¶ØDñˆ€¤M	Ãã3G)áÇ`rᦠ¢¿HŽf„bdŒ)®?’Üìr@…ìD×´±n3?¡+gùWW®,:è+±Lh4†'¸™¾1(‹ËÉ0²òð8b"'…ih†z?|xäÃóç—n¾~ýøØù›îüúýîµïâ˜m[áò)QÛ\˜T€®»<áó#NHÈ3¡9ÙCLИI=-ÌÅ!ÉÄÂÎ@,¾že‘þ]K54ECþÿ
eøò™áç¯çæ¿õèÁُíÛxþâºSä:^RJO¤1!f¾®Þ
V61
`z†ü÷§À‡:ž‘Æÿ¸~ð¥8ˆ…‰×ˆƒÑÜô?Ãçÿž¿ùÇÀÊÎÈ®i(ª¢¤!¦ò깥׏/99Yë—>¼bõÃGû}øøê;)p0uòÖØ¥,ªèÌÀð˜iß^†*¤tÁæ`äŒÍÀLÎÎðCØb fÆï8ÄÇÏÏýfxôÄ`åñ÷Ï`Týg`Ú#!̘ln˜|íÒíêªY7o8OŒã9¸¤X'eëëßf9`F}¼êHFH²@O÷L8’¬8ýñ¨Á@LŸ??>ü÷ÃÿÀr—ƒ‰‡‡‘“èCFpRý,¢/ÝøÅ°zëG†»Ï¿0Ë(Zo;œ·~®‚œ¾!DÕ¤©‹^1å•V†<ÐÏ_+'VLÇa‹I	¨Ÿ•˜þþb ¦§W¾}óîяøù€yŠ
èvfV†À\ô#°6úâÃå[Ÿî=ÿË­¬˜äç·xƒ®–·=.Ç	«r›*qæˆòÞÌÀðå.Ð!ÿ1É@dR ~ffFVv`
7
úÇ@L_¿}úyøÐüµW¯30ðñ2ƒÒ?3=fƒh6&°g¸¸˜‹‘áÕ»?7¼eøÃªlèé½aŸ¯Gk=6H‰Éêòÿ^§¡¬ÀÍÀð˜F½ƒ¤}&ì1À€%)aõ,à€>` °ð£‡‡Ž¿zÂð¨Šèx`CÂÀÀc‡Ò¬Œ`b……•‰áã×/?~e’Í¨p°-+dgcgEö€¬˜¨–šôv~Q`á9°ðøIû°<ÀÅp14Ï`‹!høÇt°& p=p÷Þ©3Ÿ_]Ýþ÷‡¶·‚õ{À’¨œg€á?(ÚA4¨5Ô
8
ÿ´á׏¿ß2r¨ªÔô› É>g»T3VA;=}gé{@‡]òýj2ø÷—áÿ¿ÿàš•œª˜¡Ž„yì?öØ&P­ýó'700þ °~]¡©fS) µÇZӌ]€›‡‰áû·ÿP@,üÿŸÚc„8ŠAcZöñû-ü– ïѼÌÎhI!Ùçç&þâãf®÷7þzÆðÿ°ØâÿþBšÉ RÖ|úÔýˤ˜‘Ôð:þjRy€[áëÛoÿýÿÿ
 €à‘tý֑Ë×Îíßöþ%#ƒ¨8ù°±!230	AòDŒ=p°1|ü)Ì©©’VÎÅÅ)ËÂú‹á?»&Ûï?^_cø÷í3°xþ´ÿ¨*fDP;‹o oþÿýÎðïÏ'`j{ôègHã–Ä`1È'Âðþ'Ãk †/„ÒÚ³«©åíÃooyY˜xõ3̑Ќ
ÁHb@‡s²s=øƒõÃ=慻_Nf<uýç·¿î¾Ðf8ü ̌,@ہ-I0µñø?‹ƒå™Ážù÷ë#Ð㯁ځ©Ôµy”…•®ß½øˆáÿ·„Ò½~ûøu/·ÒÚ0Þîi"ê@Gqü'GDb€Óÿ€Qdßþ»™áÁï}ïo1übýÄðó÷/†m÷^2(‹¶0p²ýe8÷6œAŠ÷2ƒ®Äf†¿¹àlÈÁ°Ê‰	”ÿƒiFpº‡8ø?0þþü䁨Ÿ‹›áÃ³W/€m‘ÿ?£5züÔÂå.]8ñûƒ ?#¸ä£ÐäPÈ?aÞÃp–©—á
ëE†ÿœÿX€mv.†—1¼V,ÌÀ¨ÿÏÈÎpéµÐÁ¬‡1CÚrX`@Ðé?T8é0C’Ï¿ŸŸÀIAX‚áы÷/>|}ŠZ€ÂðÀû¯>,Zœsç쇷??33pñ@«@E*'0C|b½Ípy3'#¨å6­8X~²üfx÷ë;;Û/†GŸÒf`bý‰p<(ÄA€œŒþŸ	­‰’ÿ¬Gø„®Þ~Îðúó·{ÀBå@aíÜ{xáî™Ã3§}zt0ØAå>$ùcƒ™á.ó†¯lo˜9€
9
;¨ÿʦø7Ë/†÷_1°2³“4#Ãï¼Ç…0üýÏM X¥whϋV\b©˜ j€%¨7öƒMáÆ3¶wŸþü~r+@áìЬßRÛxl碹/o€2*¨mªAI	hû`²¹v<#PŽ‘âF0fføÇþáÞ÷«@ǂš ÌÀXøÍpëµÃËOÊÌÀ؅<ÌÑÿáI
10
–¼žAnJüùÁÀ¨dÄðIÀ€áøý~ü|äN€ÂÙ¥üõû×_AñI]-CKaÍ`‹™€ðÛ¿/_؞3°«;…Œ°ZT÷±ýeg¸öýÃãŸnÂ,â?™~0üÆÂ£R"׀ŽaCj6À’ÓH­ql´1ð10èø0pÿ{Çðá°húîlÞ.åû/_Ì_qóÈÞýïïc€ÒRýÎúŠá7Û7& ;D3ƒéÿ`̌¥ÏLï®~=ÆÀ”`ÌÀRåê3k†?¿¹%ʄðufþƒCžW„É6ØáÿÊÀ&~†ÁTO¨ ¶9@ì?|zíѼEqÑw9õêÚ_pôŸèyÖ?`G3ÂÎúHÿƒÐ¬ÿÁIíџ«ÀÒü730ßüa¸ÿVŸáÞk] ‡~"5qþC1R3ÄùÌðÿö‰©30YæÅ€58ÿfÉß2¢L
11
À4+R
@DJ¼}ÿô¹¿„OÀ«¶~£·±ÑÊÜàÒèïÿ?ÀdĤÁcü,·A͹¿ cfxñóó¿w$™•~0ffn†Û/õÔ$Oƒ›`gÿg€·‡À"!~×g`2Êq›!çþ+~a`”äa`ú󇁝õ;(͂r
@=¬òîã‹×¬Ì,Éß={¤mY¦c¯Ã|‡ù&ç/¿€u0ã‚j|VP
˜Wþþ'«Ÿ¿?3œü¾ŽÁ‡½˜„X€Ið°ø“cøû›
èÐÐÜˀ¨Ù@™ŒU€‘G†‘_èW@a`a£)ÎÀ &j´ÍR?YÿÃF»ˆ¤q¡ßÿ€â¾*(¨þŸw€]µ3CÏåÀ°€q ‡3²CÈÿÏòX_°3Üù~Œá£ƒ
12
‹0?üdx÷]œl@¤!ÆÀeö¸½*a`SBü=°Gä³kCbèx&`Cî0f?|b¦á¿ q;€"k`ëÔÑ5³ž±eù˜X*
13
‰2<|û
14
X˜°€”‘ÒPû¦2ýf¸ûóƒ23ÈÀnÁ?Q†jnìŒÀýúê Ì¬øø4'0³£òï_È@ïï6¸íñ(ÄÉððُ—!k€"Ë/_Ý{tÿô£Ë,¹íÜtÖ=ÞÈðý¨¥Ìð—Ôz¶¡€¡ÅÈô—X38Ïðý떯‚ß~°3¼ü"Ç  ¬C~³BÛþ |é#0“ (´ÁÍfû?ƒ@-Öo_y®Ý½ì£‚›ªD–~ÿÿþß×§ôØ;F;]%9a^†¯¼ßþ|vp@‘ûí¸½Ï
15
Œ	n`{Š‹ÿÃËgÓD7—2°üáëÀÐþy¨†Q”B31¼£ÊTÿ ŽÇˆý—á5°xõöÙE˜€"{hñڙ£‹Þœf~õç÷5
`±ÇËó‡ADòƒ¤ò_)õ¿Š]Ô¿l¿˜~
16
Ÿgø&{”A€[دþI ‡Áð¿¿|F†ËýÛûè9÷Ç;O._‚y €ÈöÀÝÇ®ŸÛxfúÙç'¤Y$؁±Îüó°gÆô
ˆ¿Bh30m±ë£Ï†sþ¨exñP”áÿOP'¨éÌÑP<Àr0Èáà˜–jÀb`”b8wõÁßߟþ‡N-Eƒ»·_Yýñ€ü¯Ÿî0H1‰10ýüÉÀúû³€ð/Íì.2ñ~b¸Î:ÿ[Mç¹%;¶[ýùòã/¸ãa!ÎvøH¨ƒÅþ€„OÕö~s˜öžÂÜ@yàþ‹3Wï®üÞòíŠä_)VIn`QÈúó7ë/~ƒÎr¤óLîÀ,÷›õÿÞSó¦µO¹Ò¶¿Ú—ÿ¿~ƒcœTþÀõ{è?Г,"‡N~>síèz`àÿ†¹ €(^ß°§¹ùÊ¢_ó^?ýÀ ÄlçüþÉÀüâÿ Gª«@Éö'Û6&ö¿‡ÎÍ©Ïm8µi“ÃÏOŒÀö°µùïR‚&Ÿ?ÐiV/†UÛNlýðåæd3ˆ*ó‡voî}½ÉàÚÿ¯\ é!̙Oð€ÐC¾3gúÏÁë÷·-n˜r<}Æ"ýoŸ	Õ|Ö' 
17
ë/Ô3À˜a¦}nm†ƒ‡xþ=sd;PÛGdsˆ*34¯>Þº)#h¶‡Óë£3Ûkh=‰êƒÀõëë¿oÿüÿwÄù›‹gñpÊì9{9}b´”—¥á&>~`Yô##°GÇ àÀðô¡1Cs÷º/Þ]ÛúÔÂCDµ)¦'ïÏßV’°szï<Q0äˆ9ï#Æ?¬àAèŒ4°òäaøyWôņ/o‘õ~ùþä##kÈî:N:*r¶Ž&Úª
18
¢:ìÜ",ï>³Ü¸sÕ¦}g·‚šdèöUçÈî½8qRœ_+ÅãKÐa¿‹Ö¥¯‚û ^Ê`;ˆõ©1Û[¿ÏÓÆ't½À|	jg’ÈvFFž)<
19
ê\ì|Ïß^yþŸáó}PDÿÇ2+@4™©geäáö°ËîT÷eKÿc¼“…™XŠüâbx9×âʪ…³£~ýû|™Zv͖0221ˉÚI*H8óˆ±*ÿøü÷Ǎ—W¼ýôðÐΟԲ €è²V‚<Ð	.ˆ~ gBJ@€;L„;qÞÍïIEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/cr64-app-msn_protocol.png (-27 lines)
Lines 1-27 Link Here
1
‰PNG
2
3
IHDR@@ªiqÞgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<‚IDATxÚbüÿÿ?Ãp\üRLL¼þîùbg/nýýôŝ·_?>ùŒO@1‡°¶NÐQ—ó5ubþpS—‡‰çïß¿ÿ¾0ð¾zÉ©¸Óém3.^Øx›^€Ò`c“hí¡o™­ÎðÈ_ð÷u.!	>Av>! ì†ÏŸ3<º|á9£Ñ»
ßWnØÖ1݀’`a§îcá^¦ñçR¬ðߋ¬
4
æfÒ¶~lÒ*~00üúÆÀð÷ï×O®¬[Æpã±Ìïi§ÏÇ9¶p%²Y4¤@LB›Õ×9)ÛC–¹JàÓ6Qe3#y×hf	e gþxû”áÆQ†Û§žÞd`øù•“‡ANƒáÔé»yÜkß8ÅãÝë;·afËPñ¼¹y´ZElE¿æ¯½^’‚ß4+Øåõ)‘áÐ?·30œÛÊÀðò!Ãï̬Œ@¹¯€bw4þexü•WÉÁ48ž‘‘±ñAæÐ€à€Ÿ2_Ïéü¯gÊè¸y3HØF=ÈÉÀðáõ]§×20¼¸ §Ù8€rŒ "ðòücÿpÁXÜ,|¯Ä< Ð=8@
úˆìIÒb˜$ùs6›QZ	‡¼10ÿd`¸»ŸáÔb†G—þ1“:70æþâ2‰‰A‘ç+ƒôïG*JV° A-Õ{*ƒ”_·ÉócЏhb`ä—Æús†ËÀ¿¸žáûwV`ŒÿÆøP‰†„Ñ‹6 _›AüõuiaM`6XÌ¿hÐ@MÉöB¶mª’w´‚€æåëÀä>ëg€*€gã„Äø4Ï3b1¨†‰•™A˜á%ƒš°½+·Pô@1
Ê<ï_¦Çv¨[IôƒV`!0OsKõÓGڀN>ô80¹33czš‰@ 021³|fàÿ÷Q‘‰…C$@ƒ.<=*õ"-ä¦)pïdÖóËzèÙgÀjíôD†ÏO!±Ž-¶	¥X6`ÿÇ Àô]DBX^$@ƒ*Ä%tx‚l,f	}ž,läl܋10¼ºÈÀpa&°NÇÀÀÂAØÓ²#/Ãg6)i`9À@à2ÀÜÄOÍÍ¥Òåӗoœ·ïzõäÉéçŒ>yýÁ«×Ó+R"ÊÄ¿Ì47´3f`ÓxÀªíú"ˆçYÙ1:\'°031ðþÿÈÄÆÂ*˜ˆÅÙ>^-.qӞGodՀ
*-Cg†ŸÀ–äß߯_<}ð8-yßé§OºwoßÉë·Ý¥YCÇ,V¿È× HUè5ƒ v4°„ÏÀpXÒ}ô<'vσÑjf&&ρ´˜(ˆEHX5äÕWÙА?ÆÚÌÿ€¨oÀfô§Ï¢>)ˆ¾~©`ôø‘Sú˵¯2ӎxôh÷ꋗ–ízòìæ+jy^PH±<­«^äO·ª™ÐÑlÀ†Í`Óö$ÙÿūĦ„ÿ¨Y€‘‰‘“é0@¿°ƒ €X~ýúÃËÃÇÀ $ÇÄðØ¾¸z÷/Ãý§˜ÿ3ðr22
5
01˜J3†IìÃ[+¿»w¬üLnfދ
6
[²üÜùéóoÜ>JqªpsÌtU㹨¦ÀÆÀ"¢,ì€ÍÙç‡ MY/ð%qRËP6`úÏÀÂð\0@~«G†?Þ|úÏpèÂo†@úÿŸÿ~ýgøÄ –¥ #ƒ¸(ƒœ<ƒ¼’¨’®ALµ¶^Pr\ôªG޶M»÷àÂcrÀTK'Sà
ƒŒ–#È!o€UÞïÀôʆhÙ12Œ8„lÌÿÿ3+N€bbfþ{—h	ÈÓ_yŸè[n`µËÉÅÈÀÁÅÄÀ¤AUî«wÿÎ^þðfë†mû?3¼ûö•AˀEÂÅ#¬"6fÏa_ϖLA6R=ofm(Á|ÎSI‘‘O
7
˜ç;0×!õ<	#‘…!°÷ËÍÍÁÀø÷˜@,Ϟ]=ûÿ×ßož2q©«ýg`c'wp†w•ÿC:@‚…X7übbøôåÉs%êo9©ïÒÊ|òÂ5ÓTTý}´5í*®^?t™Øpµòe™Á.£¬
8
Œ} EŸnéÏ@‡³azä¬$$¬UáV.n Ô70 €˜Î]Ü~ûח''=fzˆ˜ÔA=IVF8f†³Àl6PÊ`gÑ[À2ãø¹/ï¿d”×òòõ^»Ëݹ4¸z_W–ÿs¤Ð3)Hu÷Xõ11“ŸçÑ[†Lèíaf&N^xá@L?~~ÿ}ãÆ¦Íß>10¼{ÏÈ !ÂÎÈH Àø¬ÀF8 €Ùé΃?·~døËÆ)alÚ17*tv7;¨Ù†ë¹Û‹²]V”•á:X(#>r&~2Ùy»œ< ô
 pøìÝ?mýŸ/_ßÞ¹ÏÈ %ÊÈÀΎš
9
X¡1‚Õ4æädbø	¬]ž¾úÉðâÃG&‰ø’¨°ó$ÅåDq€Ž²–7?ÓI1`ìÿ@?žùRúSšç±Âcþ0±2üÿiß8>¾þàù£ƒ«Ÿ#€˜ÿE€U"ɳ°¡Æ<<;° Øà€b‡ð¿ÿþÏðâãG†ÏßÝ"¼Ýç-“ǨûU8„ÿ»J¾e`äÖÿ1ÿû"ùƒ]Ç
(fBŒŒ¤ÕÐüê>ÿc¦&N°(@Á»ÃNŸ“¤áÿ#§¬#û/ŒàòT2BpyíwBØP9„Ü?¨:XÏë÷ïoÿyzÏ[ÀÏ/ûñã»7Q!ml¬\‘­¯¹ÿŸfÔÀŽÎ¿ï›´ý°zúû\%ƒ«C(füÕÃÈ	pÁøŸp`üÿš<`øñëÃï?ÿÀó€“g7Ÿ­«<¸ê»}¼¤#?#ÃG`¤°@Sοÿ`BìT¤ÛöÊæbaøòã/›‰‡§skŒ”fÇ´¾Ósåyo\zþûߝ™,ÀbâûsHõ÷ûÃ`>úÿ˜<ÿzü/d°óJ€ñ?f Ÿ˜
Ürd×Ðjg€Ü$leÿbøóû(þʀȦ-½™
10
{ïÝeä“Uddøúš
11
-J¸Gÿ#<úʆ‡ÊDõï?óO?$|ãSc̕¸¸ÿò²qü`–`cýûQžõ÷5†ÿ/_0ü–pÃÌcbD³‰
Lÿÿþb`óõ/(²1'0 8!…è_,)”¸¾>ÿÃð“íȀB©$.\Þwù©ù3ßû‚ÿ31ò3@Ë,eJ¡È/!#¸ìJp²±3°s1<ÿ,åÿJÚþûËÆòûç_†7/ÿ1<þÏðá5°Nþñèù?0öÖÀMOfhAȌ–÷a¬ª–	ä·_ÿ~k!YÀ¬/7Ëfð`ʇ¯þ|ûõí5(Hc<`ãÖ։>¼¿wû:°é+ªêP
12
>”BƇ’Ђ“Ø àdåb`dýÅðžé4æé—þ÷1ì|6…áÌÍ?¾›¢1¼þ®ÄpôE*Ø¡Œ°‚
VwC=ùŸ‰/Ƙÿ¿þýüÄï!y…	–þÿSþqð3¼x÷õû‹·÷ŸcLðً»Oƒý*›\|Û¼}ÁÈ Š{ê< „Ð$þ”¤Ê3;0‡1Üÿ·•áîÿMî3üa
^þÆøOþGÌZÒz@•L¬ß®¾ó`ÐÞ  x
13
XÞAG{þAc–Ü™ÐzuLñÿÿaå!#¤ d‚ꦂÀTÅÈ*”cÃOv~†ç/ß<ÿþû(ü ¬#Bë7w,}uÿèú'·™€‘ì0"U‡äi0¡¤
14
6`rùËú‘á4CÃy††,w€-Zfv^`¿†—Øyõû!Ãû?~|¥”ÿ¿ÿó0œ|t0ˆ™þÁSÁ&äÖ#ެ€Hސ8Aê9Ëp¶øô'hYÂÒÀäÿ—áåWÆÇŒŒÌ€å׀Âÿþÿÿ³`iFåïwïž?¸ÎÌ Ìõ<#Fv`fƒ+00@ø"Ãl†GLû€âœÌìÀ^0ôAÝMv`”áÃß·¿ºXhÉÎò“áÎ{+†ï€5à/„g`ž‡eFTš	©Í6ˆ, ??B’Œ”2ÃË·?n¾|vóÿ¿@~ œc‚÷^¾yp_wõ÷—ÀBúáA` 0ÁbÞ$f€
15
æ#÷˜öË
`éÉ*p€®‡™•áÃ'†‡_oÅ jÿÏ.†“O‚À58 —Èmz”†4 @FF<c ”ðû+h€ADžáþ£÷ÿ_ÿüìqs*ÞAÑu[:Þ»²zΫ;Ì??ÿcàáa¤ÌlÈ©RèýgùÁpƒq=°JþNö@y†° ²ÿ²üc¸÷õ*0›ÿº
èa`,±±üb¸ó֜áéGMx*€g¸G`µjàü'ÔׯÀv…Ã7&n†k¿xöñÅØ@á
`ù·tuIå÷×N<¸ÈÌÀ,qع ÊÿÌÐ@`Æì;æÛ¯Xn³
16
'8æÁ˜	’
17
XlVvv†{߯0|ûû),À@`wýýãa8ÿÔZ!çkhUȌ4îÏ
f´FÔ¡3œšÃƒ'_n¾úwåë÷· Ápg €‹¿|ýðíìùQ™^=}~ïÜ_`É
ô;¬ðc‚v–ž1ŸaøÃú˜M€½CXìÃà2ƒ…áÝ¿—¾ß‚f`Ö:˜•åõWV¾I«÷?H±‰ˆixõ‡Ûÿ±dX ü6”ÄUdõ~¾þÂpõå“SÀ<ñæ?t]@5/p÷ᅛ·–§1½ýýõÎùŸ@ÿ@? ͬâ^3߄x󐚡feDbÝTÿ‡ù'õ¯'Áɘ”
€©€…ùç7^˜10²üÂޔÅRúÃÙØ:FÀ¶ “u°¹ý™A\õ#/¸‡þæ7€"zbäà±¥[vî¨Ìúÿü÷ϗ€
IHïX¸üeýÎðƒù#0 €fF(
ö4°Ã¬îàd³²±1ÜþqŽáӟwÀä©
@)T\}al§sB
18
CBœØFŒ`>yØña´Ïöÿ=ò?§x”_2¨¨¨A¦›  €HšÚ²{Ңㇻ«þ=þóçî¹oàT&üeùÆð‡å°l`§F(yԁЈ€`V‹ïÿ?g¸6fNp9Âl¬¿×`xóYÈÿƒâiFä#Ž€õøþ^üRLvyŒ|Šÿ_lb`Pùtß71aN`ú僙@$O­ÚÔÜ·{geæÿÇ_¿Þ:ò•áÇÛߐé:hLC<éÕB<þîy&pê€Æ?†+ß1€º%°Úԇùþ‡áö+`
19
øèùüLJ÷îàc'!±2KޒÉ&Ѽÿ,gø¯ýá?7°HúÅÀÇý‹²ºˆ¬¹Á­{§ÌÙ¼¹ éåó§÷}aøö€‰‡›áÐ&`^ffzŽÿA0Ôãö?`l³2<þs…áٟÛÀTm@‡(¾Õ6cÙ@mÔ@@ÆP9FP­ªæ@—6¦LÒ5þ?»ÉðïÐófÀPw¯AjÿþGC€"{rôà‰ekf-
20
õýóéêÉ·—™€ÉV’OˆáÓO`åJ`0ÃÊõ 3}a¸üc?40ƒ”
½SgøòXx1ýEíÿPßC"AÉXØ0Šh10©‡20Š›10¼ºÍðïò\†ÿ|çä€Y4ÚôÒVÿ2¡”&DÑìðýG—ÎÏYšýëõ…½Lo¹|¥\TùeÁy¤À€°©ƒ
XÜþuœáÍß'ÀÖ2;´MðŸáóO†dÿýçiPw>ࡊºÏÀŽ#/°Šcácø÷æ,Ãÿ»þ‹=b`ðPe`0׆äÅßá#L !ý¯ßØþ@†p  €(žúâöÝJ³„ˆ>gbÿÃP®RÈ Å)¬›=ÆLÿ ))K€SÃ7ÆW76ŠØ Ù4/ÁÊðô—!0öø!íù¿Ðá±ÐIBv`Öí’ÿ¥Á£¬AlÜL, ±UMtÂSÎ? 3ç/ßC
21
 ª,‘¹óìÔ­”œIGïØ>
22
ñQ`0“ÔaØxg03«¥à0æ€ØœdøÏjíýÒAóÕ×~íaPgu``gâf‹Ÿà‚ü“ƒÑÆ/!Cd¿~€ªh3ØÞ66Ø KáÁô¼0<Á	Š`°ç!ݲÿ–;/€½†ß_`n ª-xzþÞú?/¸n1ža0•Ó`VafàøŽ}& ˜¡l&
nõþgføÎý„á±àFvp*6¿ÃÉðû7#°Ï 	ÌÏBÀXçÖï\¶0`AþšíÒß¿ÐÊ𲂠ÔóáƒÃý§wÍàÿ_aî ªÀåk»r^Syqþý)iV)y	µ_ÒÚÿ„åþ2póK~vP@€Jã¿ÀFÔ?^±¿òfÿôýXþ»í`øÁû„ù;¤€ü͌t 'ÿB<ÈÇ@Oÿ†y˰,ò!†Äfgƒ?OŸó³À—‡Õ`@T[%öäýÕ§)ñÓvþ2ÿÿEàƒ"ƒ
23
û?G€=HF^ {e@KxÿûæÿÁs€,ÀlÀÁ	ž§zؘb|ÎðNk=ƒð«4pÀ/Œ}PñöÄ_HƒŸiPV†£à1ÿžÀ±ÎþÌ&ŸsüxõîéäՄDÕ5B§oYÀ|KñïåOÇÔXµ8ÿ[†?UÐO`Œ=ÁÅþ—ï/Ðsxxÿ1°ÝÁøˆÿc`ùÁÊðUa7Ã7ùclÿù€½W`4K‹iè¢@üù…åبÏ_tσj‘Ÿ?~É1\¿Çöøý盐 €¨wž;òï„Øž;2p223H3Icû'˟¿ÌÀêˆùг?úñ0L 1 g˜ò, ¶Ì¿_õç0pi>ö:Y>½ªeüƒ”¼ÿb²ÿÃÄ Gö<,ÊwUÎ_­±ûó
24
¶Nˆªðíׇ?çœÈ|UûÿµÇTÙ´žÿö 2’8ˆÏôÄgføÏÿ’á®fÁ¿íÜîÆðæ9/°Ûÿ5#³¡)€(ÆK	05àüÔË*Âpõ¦Ã•Û'ù	ÙÍDõergnlØý÷˜â¶Gw?€æl$˜¤©˜œYþ‚<ýŒál ÍôÒûcüaùÉpúÚæCSmïܶݏáÍn`ÍñâAxò‡y‚Q)P€µÏ¯_ڇN|¸ÿôÍ¥c°¡0 ªÀw`*رuN=×Y×ÏןŸaPdWa¶ þ
ÁÈ©€éÚ2.`ÝÈòKTNÿ=qmQ÷œU»ªvï±ýóé5¨‘ìÂ<Kúðÿ?< Ùà?¤½Ã!Íp÷¡
25
Ãþã§wÿûÿý0ù£,û š,”¼ùäÀÙë[7ÿ½`ÈðöËi69`AL dŠu˜þcY˄¿YA#ö %¿ÖÞ6c[æòµ_^<öï¿@RË_¨§Á#Èã ÿ‡hz˜ÿ˜ÍvïùýùÒí}ۀæal  š­Ýz¸gÒóMbËÞ]–×Á|¬‚@wý%¬˜d¾srÍX]¾³vNÏü%‘³—º?¸yU	¼„†	X.À³(¯#zÿ@µhL@Ÿáöe†
;öoýòã	°Vh €h¶Zü÷ßï?ù9%s#y›„€éރSíxð7°aÈc	hXï/(iåaøùõçsäêêö£[$„õŸ>y‘Úá%é`ntœ‹ïd˜é°ðWy°lŒ}^5†ßÖkV?}}âÊúE@#Þ!—þ0@4].ÿñûów’Bšiálµ«þÿÿgÁ¬zl埿p®cûÊ&ïž?¿|}û˷ϳ±ò‡]¿ëcç›acøDTEá&ƒ¨ðFvP¿ƒ´ÌØd5fغ’™añ†¥3¾ÿzuT<a³ €h¾_àù»ë%5£‚~—-æô`±þ§zØddÀšÀs›lž‹¾{õáÞcä&+üúýñ5##cÃå»*”v™ZèXxiüÕÒPúÆ)
26
ì2°p‰3üø-ÁpâÔ¿_³–-_xóñž¥@mïÿÿ‡V3h €è²aâùûë÷ù8%‚>U̒ðôûª¹‰•ØúÇÆ€¼ií?(¿
27
2|¸ÃpãûŸw ‹â°ÎW©sÀ€¸xîÆªéâBú†"¦Ò"Šòl¿¸^¼=øîÁókÇ_}¸r”p€êâr@ÑmÇȧï/^²2sÅy½+jÐôÊÊÿ¬·Œ‘Qô+h8ì?d]Џ_Øï¹1ܹzóàßÿ?_ÿ'°§š§AÓÜπ±ãê=`7?~Ã0PÍ|f]·Ìüþûí#С¥žúŸµqL­a7½ªþCá(φÀ&/ëSs†¯]¼½x#òØ=1ŸIu@
ØÆIAYUcuÿX%-UvéOj qÏ7¹¯ïØ?«óқ{€J>ü§ƒãh@wŽS3#‡”—¬°ÑÂñöËݧÿ€E (Ç`«²hhÐlm_A*àèñÛ)û©!b	IEND®B`‚
(-)tdenetwork.ori/kopete/protocols/msn/icons/Makefile.am (-2 lines)
Lines 1-2 Link Here
1
kopeteicondir = $(kde_datadir)/kopete/icons
2
kopeteicon_ICON = AUTO
(-)tdenetwork.ori/kopete/protocols/msn/incomingtransfer.cpp (-384 lines)
Lines 1-384 Link Here
1
/*
2
    incomingtransfer.cpp - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include "incomingtransfer.h"
18
using P2P::TransferContext;
19
using P2P::IncomingTransfer;
20
using P2P::Message;
21
22
// Kde includes
23
#include <kbufferedsocket.h>
24
#include <kdebug.h>
25
#include <tdelocale.h>
26
#include <kserversocket.h>
27
#include <kstandarddirs.h>
28
#include <tdetempfile.h>
29
using namespace KNetwork;
30
31
// TQt includes
32
#include <tqfile.h>
33
#include <tqregexp.h>
34
35
// Kopete includes
36
#include <kopetetransfermanager.h>
37
38
IncomingTransfer::IncomingTransfer(const TQString& from, P2P::Dispatcher *dispatcher, TQ_UINT32 sessionId)
39
: TransferContext(from,dispatcher,sessionId)
40
{
41
	m_direction = P2P::Incoming;
42
	m_listener  = 0l;
43
}
44
45
IncomingTransfer::~IncomingTransfer()
46
{
47
	kdDebug(14140) << k_funcinfo << endl;
48
	if(m_listener)
49
	{
50
		delete m_listener;
51
		m_listener = 0l;
52
	}
53
54
	if(m_socket)
55
	{
56
		delete m_socket;
57
		m_socket = 0l;
58
	}
59
}
60
61
62
void IncomingTransfer::slotTransferAccepted(Kopete::Transfer* transfer, const TQString& /*fileName*/)
63
{
64
	TQ_UINT32 sessionId = transfer->info().internalId().toUInt();
65
	if(sessionId!=m_sessionId)
66
		return;
67
	
68
	TQObject::connect(transfer , TQT_SIGNAL(transferCanceled()), this, TQT_SLOT(abort()));
69
	m_transfer = transfer;
70
		
71
	TQString content = TQString("SessionID: %1\r\n\r\n").arg(sessionId);
72
	sendMessage(OK, content);
73
	
74
	TQObject::disconnect(Kopete::TransferManager::transferManager(), 0l, this, 0l);
75
}
76
77
void IncomingTransfer::slotTransferRefused(const Kopete::FileTransferInfo& info)
78
{
79
	TQ_UINT32 sessionId = info.internalId().toUInt();
80
	if(sessionId!=m_sessionId)
81
		return;
82
	
83
	TQString content = TQString("SessionID: %1\r\n\r\n").arg(sessionId);
84
	// Send the sending client a cancelation message.
85
	sendMessage(DECLINE, content);
86
	m_state=Finished;
87
	
88
	TQObject::disconnect(Kopete::TransferManager::transferManager(), 0l, this, 0l);
89
}
90
91
92
93
void IncomingTransfer::acknowledged()
94
{
95
	kdDebug(14140) << k_funcinfo << endl;
96
	
97
	switch(m_state)
98
	{
99
		case Invitation:
100
				// NOTE UDI: base identifier acknowledge message, ignore.
101
				//      UDI: 200 OK message should follow.
102
				if(m_type == File)
103
				{
104
					// FT: 200 OK acknowledged message.
105
					// If this is the first connection between the two clients, a direct connection invitation
106
					// should follow. Otherwise, the file transfer may start right away.
107
					if(m_transfer)
108
					{
109
						TQFile *destination = new TQFile(m_transfer->destinationURL().path());
110
						if(!destination->open(IO_WriteOnly))
111
						{
112
							m_transfer->slotError(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, i18n("Cannot open file for writing"));
113
							m_transfer = 0l;
114
							
115
							error();
116
							return;
117
						}
118
						m_file = destination;
119
					}
120
					m_state = Negotiation;
121
				}
122
			break;
123
124
		case Negotiation:
125
				// 200 OK acknowledge message.
126
			break;
127
128
		case DataTransfer:
129
			break;
130
			
131
		case Finished:
132
			// UDI: Bye acknowledge message.
133
			m_dispatcher->detach(this);
134
			break;
135
	}
136
}
137
138
void IncomingTransfer::processMessage(const Message& message)
139
{
140
	if(m_file && (message.header.flag == 0x20 || message.header.flag == 0x01000030))
141
	{
142
		// UserDisplayIcon data or File data is in this message.
143
		// Write the recieved data to the file.
144
		kdDebug(14140) << k_funcinfo << TQString("Received, %1 bytes").arg(message.header.dataSize) << endl;
145
		
146
		m_file->writeBlock(message.body.data(), message.header.dataSize);
147
		if(m_transfer){
148
			m_transfer->slotProcessed(message.header.dataOffset + message.header.dataSize);
149
		}
150
		
151
		if((message.header.dataOffset + message.header.dataSize) == message.header.totalDataSize)
152
		{
153
			// Transfer is complete.
154
			if(m_type == UserDisplayIcon){
155
				m_tempFile->close();
156
				m_dispatcher->displayIconReceived(m_tempFile, m_object);
157
				m_tempFile = 0l;
158
				m_file = 0l;
159
			}
160
			else
161
			{
162
				m_file->close();
163
			}
164
165
			m_isComplete = true;
166
			// Send data acknowledge message.
167
			acknowledge(message);
168
169
			if(m_type == UserDisplayIcon)
170
			{
171
				m_state = Finished;
172
				// Send BYE message.
173
				sendMessage(BYE, "\r\n");
174
			}
175
		}
176
	}
177
	else if(message.header.dataSize == 4 && message.applicationIdentifier == 1)
178
	{
179
		// Data preparation message.
180
		//if (m_tempFile->name().isEmpty() == false) {
181
		//	TQFile::remove(m_tempFile->name());
182
		//}
183
		m_tempFile = new KTempFile(locateLocal("tmp", "msnpicture--"), ".png");
184
		m_tempFile->setAutoDelete(true);
185
		m_file = m_tempFile->file();
186
		m_state = DataTransfer;
187
		// Send data preparation acknowledge message.
188
		acknowledge(message);
189
	}
190
	else
191
	{
192
		TQString body =
193
			TQCString(message.body.data(), message.header.dataSize);
194
//		kdDebug(14140) << k_funcinfo << "received, " << body << endl;
195
196
		if(body.startsWith("INVITE"))
197
		{
198
			// Retrieve some MSNSLP headers used when
199
			// replying to this INVITE message.
200
			TQRegExp regex(";branch=\\{([0-9A-F\\-]*)\\}\r\n");
201
			regex.search(body);
202
			m_branch = regex.cap(1);
203
			// NOTE Call-ID never changes.
204
			regex = TQRegExp("Call-ID: \\{([0-9A-F\\-]*)\\}\r\n");
205
			regex.search(body);
206
			m_callId = regex.cap(1);
207
			regex = TQRegExp("Bridges: ([^\r\n]*)\r\n");
208
			regex.search(body);
209
			TQString bridges = regex.cap(1);
210
			// The NetID field is 0 if the Conn-Type is
211
			// Direct-Connect or Firewall, otherwise, it is
212
			// a randomly generated number.
213
			regex = TQRegExp("NetID: (\\-?\\d+)\r\n");
214
			regex.search(body);
215
			TQString netId = regex.cap(1);
216
			kdDebug(14140) << "net id, " << netId << endl;
217
			// Connection Types
218
			// - Direct-Connect
219
			// - Port-Restrict-NAT
220
			// - IP-Restrict-NAT
221
			// - Symmetric-NAT
222
			// - Firewall
223
			regex = TQRegExp("Conn-Type: ([^\r\n]+)\r\n");
224
			regex.search(body);
225
			TQString connType = regex.cap(1);
226
227
			bool wouldListen = false;
228
			if(netId.toUInt() == 0 && connType == "Direct-Connect"){
229
				wouldListen = true;
230
231
			}
232
			else if(connType == "IP-Restrict-NAT"){
233
				wouldListen = true;
234
			}
235
#if 1
236
			wouldListen = false; // TODO Direct connection support
237
#endif			
238
			TQString content;
239
			
240
			if(wouldListen)
241
			{
242
				// Create a listening socket for direct file transfer.
243
				m_listener = new TDEServerSocket("", "");
244
				m_listener->setResolutionEnabled(true);
245
				// Create the callback that will try to accept incoming connections.
246
				TQObject::connect(m_listener, TQT_SIGNAL(readyAccept()), TQT_SLOT(slotAccept()));
247
				TQObject::connect(m_listener, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotListenError(int)));
248
				// Listen for incoming connections.
249
				bool isListening = m_listener->listen(1);
250
				kdDebug(14140) << k_funcinfo << (isListening ? "listening" : "not listening") << endl;
251
				kdDebug(14140) << k_funcinfo
252
					<< "local endpoint, " << m_listener->localAddress().nodeName()
253
					<< endl;
254
				
255
				content = "Bridge: TCPv1\r\n"
256
					"Listening: true\r\n" +
257
					TQString("Hashed-Nonce: {%1}\r\n").arg(P2P::Uid::createUid()) +
258
					TQString("IPv4Internal-Addrs: %1\r\n").arg(m_listener->localAddress().nodeName())   +
259
					TQString("IPv4Internal-Port: %1\r\n").arg(m_listener->localAddress().serviceName()) +
260
					"\r\n";
261
			}
262
			else
263
			{
264
				content =
265
					"Bridge: TCPv1\r\n"
266
					"Listening: false\r\n"
267
					"Hashed-Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
268
					"\r\n";
269
			}
270
			
271
			m_state = DataTransfer;
272
			
273
			if (m_type != File)
274
			{
275
				// NOTE For file transfers, the connection invite *must not* be acknowledged in any way
276
				//      as this trips MSN 7.5
277
				
278
				acknowledge(message);
279
				// Send 200 OK message to the sending client.
280
				sendMessage(OK, content);
281
			}
282
		}
283
		else if(body.startsWith("BYE"))
284
		{
285
			m_state = Finished;
286
			// Send the sending client an acknowledge message.
287
			acknowledge(message);
288
289
			if(m_file && m_transfer)
290
			{
291
				if(m_isComplete){
292
					// The transfer is complete.
293
					m_transfer->slotComplete();
294
				}
295
				else
296
				{
297
					// The transfer has been canceled remotely.
298
					if(m_transfer){
299
						// Inform the user of the file transfer cancelation.
300
						m_transfer->slotError(TDEIO::ERR_ABORTED, i18n("File transfer canceled."));
301
					}
302
					// Remove the partially received file.
303
					m_file->remove();
304
				}
305
			}
306
307
			// Dispose of this transfer context.
308
			m_dispatcher->detach(this);
309
		}
310
		else if(body.startsWith("MSNSLP/1.0 200 OK"))
311
		{
312
			if(m_type == UserDisplayIcon){
313
				m_state = Negotiation;
314
				// Acknowledge the 200 OK message.
315
				acknowledge(message);
316
			}
317
		}
318
	}
319
}
320
321
void IncomingTransfer::slotListenError(int /*errorCode*/)
322
{
323
	kdDebug(14140) << k_funcinfo << m_listener->errorString() << endl;
324
}
325
326
void IncomingTransfer::slotAccept()
327
{
328
	// Try to accept an incoming connection from the sending client.
329
	m_socket = static_cast<TDEBufferedSocket*>(m_listener->accept());
330
	if(!m_socket)
331
	{
332
		// NOTE If direct connection fails, the sending
333
		// client wil transfer the file data through the
334
		// existing session.
335
		kdDebug(14140) << k_funcinfo << "Direct connection failed." << endl;
336
		// Close the listening endpoint.
337
		m_listener->close();
338
		return;
339
	}
340
341
	kdDebug(14140) << k_funcinfo << "Direct connection established." << endl;
342
343
	// Set the socket to non blocking,
344
	// enable the ready read signal and disable
345
	// ready write signal.
346
	// NOTE readyWrite consumes too much cpu usage.
347
	m_socket->setBlocking(false);
348
	m_socket->enableRead(true);
349
	m_socket->enableWrite(false);
350
351
	// Create the callback that will try to read bytes from the accepted socket.
352
	TQObject::connect(m_socket, TQT_SIGNAL(readyRead()),   this, TQT_SLOT(slotSocketRead()));
353
	// Create the callback that will try to handle the socket close event.
354
	TQObject::connect(m_socket, TQT_SIGNAL(closed()),      this, TQT_SLOT(slotSocketClosed()));
355
	// Create the callback that will try to handle the socket error event.
356
	TQObject::connect(m_socket, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int)));
357
}
358
359
void IncomingTransfer::slotSocketRead()
360
{
361
	int available = m_socket->bytesAvailable();
362
	kdDebug(14140) << k_funcinfo << available << ", bytes available." << endl;
363
	if(available > 0)
364
	{
365
		TQByteArray buffer(available);
366
		m_socket->readBlock(buffer.data(), buffer.size());
367
368
		if(TQString(buffer) == "foo"){
369
			kdDebug(14140) << "Connection Check." << endl;
370
		}
371
	}
372
}
373
374
void IncomingTransfer::slotSocketClosed()
375
{
376
	kdDebug(14140) << k_funcinfo << endl;
377
}
378
379
void IncomingTransfer::slotSocketError(int errorCode)
380
{
381
	kdDebug(14140) << k_funcinfo << errorCode << endl;
382
}
383
384
#include "incomingtransfer.moc"
(-)tdenetwork.ori/kopete/protocols/msn/incomingtransfer.h (-58 lines)
Lines 1-58 Link Here
1
/*
2
    incomingtransfer.h - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#ifndef INCOMINGTRANSFER_H
18
#define INCOMINGTRANSFER_H
19
20
#include "p2p.h"
21
#include "dispatcher.h"
22
23
namespace KNetwork{
24
	class TDEServerSocket;
25
}
26
27
/**
28
@author Kopete Developers
29
*/
30
namespace P2P{
31
	class IncomingTransfer : public P2P::TransferContext
32
	{	Q_OBJECT
33
  
34
		public:
35
			IncomingTransfer(const TQString& from, P2P::Dispatcher *dispatcher, TQ_UINT32 sessionId);
36
			virtual ~IncomingTransfer();
37
38
		private slots:
39
			void slotListenError(int errorCode);
40
			void slotAccept();
41
			void slotSocketRead();
42
			void slotSocketClosed();
43
			void slotSocketError(int errorCode);
44
			
45
			void slotTransferAccepted(Kopete::Transfer* transfer, const TQString& fileName);
46
			void slotTransferRefused(const Kopete::FileTransferInfo& info);
47
48
			
49
		private:
50
			virtual void acknowledged();
51
			virtual void processMessage(const Message& message);
52
53
			KTempFile *m_tempFile;
54
			KNetwork::TDEServerSocket   *m_listener;
55
	};
56
}
57
58
#endif
(-)tdenetwork.ori/kopete/protocols/msn/kopete_msn.desktop (-99 lines)
Lines 1-99 Link Here
1
[Desktop Entry]
2
Type=Service
3
Icon=msn_protocol
4
ServiceTypes=Kopete/Protocol
5
X-TDE-Library=kopete_msn
6
X-Kopete-Version=1000900
7
X-Kopete-Messaging-Protocol=messaging/msn
8
X-TDE-PluginInfo-Author=Kopete Developers
9
X-TDE-PluginInfo-Email=kopete-devel@kde.org
10
X-TDE-PluginInfo-Name=kopete_msn
11
X-TDE-PluginInfo-Version=0.8.0
12
X-TDE-PluginInfo-Website=http://kopete.kde.org
13
X-TDE-PluginInfo-Category=Protocols
14
X-TDE-PluginInfo-Depends=
15
X-TDE-PluginInfo-License=GPL
16
X-TDE-PluginInfo-EnabledByDefault=false
17
Name=MSN Messenger
18
Name[ar]=مرسال MSN
19
Name[bn]=এমএসএন বার্তাবাহক
20
Name[cy]=Negesydd MSN
21
Name[da]=MSN-Messenger
22
Name[de]=MSN-Messenger
23
Name[eo]=MSN-mesaĝilo
24
Name[fa]=پیام‌رسان ام‌اس‌ان
25
Name[gl]=MSN Messanger
26
Name[hi]=एमएसएन मैसेंजर
27
Name[ja]=MSN メッセンジャー
28
Name[km]=កម្មវិធី​ផ្ញើសារ MSN
29
Name[lt]=MSN žinučių klientas
30
Name[mk]=Гласник за MSN 
31
Name[nds]=MSN-Kortnarichtendeenst
32
Name[ne]=एमएसएन मेसेन्जर
33
Name[pa]=MSN ਸੁਨੇਹੇਦਾਰ
34
Name[pl]=Komunikator MSN Messenger
35
Name[pt_BR]=Mensageiro MSN
36
Name[ro]=Mesaje instantanee MSN
37
Name[tg]=MSN Пайёмбар
38
Name[uk]=Кур'єр MSN
39
Name[uz]=MSN mesenjer
40
Name[uz@cyrillic]=MSN месенжер
41
Comment=Protocol to connect to MSN Messenger
42
Comment[ar]=البرتوكول سيتصل بمرسال MSN
43
Comment[be]=Пратакол MSN Messenger
44
Comment[bg]=Протокол за връзка с MSN Messenger
45
Comment[bn]=এমএসএন বার্তাবাহকে সংযোগ করতে প্রোটোকল
46
Comment[br]=Komenad kevreañ ouzh MSN Messenger
47
Comment[bs]=MSN Messenger protokol
48
Comment[ca]=Protocol per a connectar-se a MSN Messenger
49
Comment[cs]=Protokol k připojení k MSN Messengeru
50
Comment[cy]=Protocol i gysylltu â Negesydd MSN
51
Comment[da]=Protokol til at forbinde til MSN-Messenger
52
Comment[de]=Protokoll zur Verbindung mit dem MSN-Messenger
53
Comment[el]=Πρωτόκολλο για σύνδεση στο MSN Messenger
54
Comment[es]=Protocolo para conectar con MSN Messenger
55
Comment[et]=Protokoll ühendumiseks MSN Messengeriga
56
Comment[eu]=MSN Messenger-era konektatzeko protokoloa
57
Comment[fa]=قرارداد برای اتصال به پیام‌رسان ام‌اس‌ان
58
Comment[fi]=Yhteyskäytäntö MSN Messanger -verkkoon kytkeytymiseen
59
Comment[fr]=Protocole pour se connecter sur MSN Messenger
60
Comment[ga]=Prótacal chun ceangal le MSN Messenger
61
Comment[gl]=Protocolo para se conectar ó MSN Messanger
62
Comment[he]=פרוטוקול התחברות ל- MSN Messenger
63
Comment[hi]=एमएसएन मैसेंजर से जुड़ने का प्रोटोकॉल
64
Comment[hr]=Protokol za povezivanje na MSN Messenger
65
Comment[hu]=Protokoll az MSN Messenger használatához
66
Comment[is]=Samskiptamáti til að tengjast MSN Messenger
67
Comment[it]=Protocollo per connessione a MSN Messenger
68
Comment[ja]=MSN メッセンジャーに接続するプロトコル
69
Comment[ka]=MSN Messenger დაკავშირების ოქმი
70
Comment[kk]=MSN Messenger-ге қосылу протоколы
71
Comment[km]=ពិធីការ​ដើម្បី​ភ្ជាប់​ទៅ​កម្មវិធី​ផ្ញើសារ MSN
72
Comment[lt]=Protokolas prisijungimui prie MSN žinučių kliento
73
Comment[mk]=Протокол за поврзување на Гласникот на MSN
74
Comment[nb]=Protokoll for å koble til MSN Messenger
75
Comment[nds]=Protokoll för't Tokoppeln na den MSN-Kortnarichtendeenst
76
Comment[ne]=एमएसएन मेसेन्जरमा जडान गर्नुपर्ने प्रोटोकल
77
Comment[nl]=Protocol voor MSN Messenger
78
Comment[nn]=Protokoll for å kopla til MSN Messenger
79
Comment[pl]=Protokół połączenia z serwerem MSN Messenger
80
Comment[pt]=Um protocolo para ser ligar ao MSN Messenger
81
Comment[pt_BR]=Protocolo para conexão ao MSN Messenger
82
Comment[ro]=Protocol de conectare la MSN Messenger
83
Comment[ru]=Протокол для подключения к MSN Messenger
84
Comment[sk]=Protokol pre pripojenie k MSN Messenger
85
Comment[sl]=Protokol za povezavo na MSN Messenger
86
Comment[sr]=Протокол за повезивање на MSN Messenger
87
Comment[sr@Latn]=Protokol za povezivanje na MSN Messenger
88
Comment[sv]=Protokoll för att ansluta till MSN-meddelandeklient
89
Comment[ta]= MSN Messenger யுடன் இணைக்க விதிமுறை
90
Comment[tg]=Қарордоди пайвастшавӣ ба MSN Пайёмбар
91
Comment[tr]=MSN Messenger'a bağlantı iletişim kuralı
92
Comment[uk]=Протокол для з'єднання з MSN Messenger
93
Comment[uz]=MSN mesenjer bilan aloqa oʻrnatish uchun protokol
94
Comment[uz@cyrillic]=MSN месенжер билан алоқа ўрнатиш учун протокол
95
Comment[wa]=Protocole po s' raloyî a MSN
96
Comment[zh_CN]=连接到 MSN Messenger 协议
97
Comment[zh_HK]=用來連接至 MSN Messenger 的通訊協定
98
Comment[zh_TW]=連線到 MSN 的協定
99
(-)tdenetwork.ori/kopete/protocols/msn/Makefile.am (-47 lines)
Lines 1-47 Link Here
1
if include_msn_webcam
2
WEBCAM = webcam
3
WEBCAM_LIBMINICWRAPPER = webcam/libmimicwrapper.la
4
endif
5
6
KDE_OPTIONS = nofinal
7
METASOURCES = AUTO
8
SUBDIRS = ui $(WEBCAM) . icons config
9
AM_CPPFLAGS = -Iui \
10
	-I$(srcdir)/webcam \
11
	-I$(srcdir)/ui \
12
	$(KOPETE_INCLUDES) \
13
	-I$(top_srcdir)/kopete/libkopete/private \
14
	$(all_includes)
15
16
kde_module_LTLIBRARIES = kopete_msn.la
17
lib_LTLIBRARIES = libkopete_msn_shared.la
18
19
CLEANFILES = dummy.cpp
20
21
libkopete_msn_shared_la_SOURCES = msnprotocol.cpp msnaccount.cpp \
22
	msnaddcontactpage.cpp msncontact.cpp msnsocket.cpp msnchatsession.cpp msndebugrawcmddlg.cpp \
23
	msnnotifysocket.cpp msnswitchboardsocket.cpp msnfiletransfersocket.cpp msninvitation.cpp \
24
	sha1.cpp msnsecureloginhandler.cpp msnchallengehandler.cpp dispatcher.cpp \
25
	p2p.cpp messageformatter.cpp incomingtransfer.cpp outgoingtransfer.cpp \
26
	webcam.cpp
27
28
libkopete_msn_shared_la_LIBADD  = ./ui/libkopetemsnui.la ../../libkopete/libkopete.la $(WEBCAM_LIBMINICWRAPPER) ../../libkopete/avdevice/libkopete_videodevice.la   $(LIB_TDEIO)
29
libkopete_msn_shared_la_LDFLAGS = -version-info 0:0:0 -no-undefined $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor -lkopete_videodevice -L../../libkopete/avdevice/
30
31
kopete_msn_la_SOURCES = dummy.cpp webcam.cpp
32
kopete_msn_la_LIBADD = libkopete_msn_shared.la
33
34
kopete_msn_la_LDFLAGS = -no-undefined -module $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor -lkopete_videodevice -L../../libkopete/avdevice/
35
36
dummy.cpp: $(srcdir)/Makefile.am
37
	echo '#include "kdemacros.h"' > $@
38
	echo 'extern "C" KDE_EXPORT void *init_libkopete_msn_shared();' >> $@
39
	echo 'extern "C" KDE_EXPORT void *init_kopete_msn() { return init_libkopete_msn_shared(); }' >> $@
40
41
service_DATA = kopete_msn.desktop
42
servicedir = $(kde_servicesdir)
43
44
mydatadir = $(kde_datadir)/kopete_msn
45
mydata_DATA = msnchatui.rc
46
noinst_HEADERS = p2p.h dispatcher.h messageformatter.h incomingtransfer.h \
47
	outgoingtransfer.h webcam.h
(-)tdenetwork.ori/kopete/protocols/msn/messageformatter.cpp (-192 lines)
Lines 1-192 Link Here
1
/*
2
    messageformatter.cpp - msn p2p protocol
3
4
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
5
6
    *************************************************************************
7
    *                                                                       *
8
    * This program is free software; you can redistribute it and/or modify  *
9
    * it under the terms of the GNU General Public License as published by  *
10
    * the Free Software Foundation; either version 2 of the License, or     *
11
    * (at your option) any later version.                                   *
12
    *                                                                       *
13
    *************************************************************************
14
*/
15
16
#include "messageformatter.h"
17
#include "p2p.h"
18
19
// TQt includes
20
#include <tqdatastream.h>
21
#include <tqregexp.h>
22
23
// Kde includes
24
#include <kdebug.h>
25
26
using P2P::MessageFormatter;
27
using P2P::Message;
28
29
MessageFormatter::MessageFormatter(TQObject *parent, const char *name) : TQObject(parent, name)
30
{}
31
32
MessageFormatter::~MessageFormatter()
33
{}
34
35
Message MessageFormatter::readMessage(const TQByteArray& stream, bool compact)
36
{
37
	Message inbound;
38
	
39
	TQ_UINT32 index = 0;
40
	if(compact == false)
41
	{
42
		// Determine the end position of the message header.
43
		while(index < stream.size())
44
		{
45
			if(stream[index++] == '\n'){
46
				if(stream[index - 3] == '\n')
47
					break;
48
			}
49
		}
50
51
		// Retrieve the message header.
52
		TQString messageHeader = TQCString(stream.data(), index);
53
54
		// Retrieve the message mime version, content type,
55
		// and p2p destination.
56
		TQRegExp regex("Content-Type: ([A-Za-z0-9$!*/\\-]*)");
57
		regex.search(messageHeader);
58
		TQString contentType = regex.cap(1);
59
60
		if(contentType != "application/x-msnmsgrp2p")
61
			return inbound;
62
63
//		kdDebug(14140) << k_funcinfo << endl;
64
	
65
		regex = TQRegExp("MIME-Version: (\\d.\\d)");
66
		regex.search(messageHeader);
67
		inbound.mimeVersion = regex.cap(1);
68
		inbound.contentType = contentType;
69
		regex = TQRegExp("P2P-Dest: ([^\r\n]*)");
70
		regex.search(messageHeader);
71
		TQString destination = regex.cap(1);
72
	}
73
	
74
	TQDataStream reader(stream, IO_ReadOnly);
75
	reader.setByteOrder(TQDataStream::LittleEndian);
76
	// Seek to the start position of the message
77
	// transport header.
78
	reader.device()->at(index);
79
80
	// Read the message transport headers from the stream.
81
	reader >> inbound.header.sessionId;
82
	reader >> inbound.header.identifier;
83
	reader >> inbound.header.dataOffset;
84
	reader >> inbound.header.totalDataSize;
85
	reader >> inbound.header.dataSize;
86
	reader >> inbound.header.flag;
87
	reader >> inbound.header.ackSessionIdentifier;
88
	reader >> inbound.header.ackUniqueIdentifier;
89
	reader >> inbound.header.ackDataSize;
90
91
	/*kdDebug(14140)
92
		<< "session id, "             << inbound.header.sessionId << endl
93
		<< "identifier, "             << inbound.header.identifier << endl
94
		<< "data offset, "            << inbound.header.dataOffset << endl
95
		<< "total size, "             << inbound.header.totalDataSize << endl
96
		<< "data size, "              << inbound.header.dataSize << endl
97
		<< "flag, "                   << inbound.header.flag << endl
98
		<< "ack session identifier, " << inbound.header.ackSessionIdentifier << endl
99
		<< "ack unique identifier, "  << inbound.header.ackUniqueIdentifier << endl
100
		<< "ack data size, "          << inbound.header.ackDataSize
101
	<< endl;*/
102
103
	// Read the message body from the stream.
104
	if(inbound.header.dataSize > 0){
105
		inbound.body.resize(inbound.header.dataSize);
106
		reader.readRawBytes(inbound.body.data(), inbound.header.dataSize);
107
	}
108
109
	if(compact == false)
110
	{
111
		reader.setByteOrder(TQDataStream::BigEndian);
112
		// Read the message application identifier from the stream.
113
		reader >> inbound.applicationIdentifier;
114
115
/*		kdDebug(14140)
116
			<< "application identifier, " << inbound.applicationIdentifier
117
		<< endl;*/
118
	}
119
		
120
	return inbound;
121
}
122
123
void MessageFormatter::writeMessage(const Message& message, TQByteArray& stream, bool compact)
124
{
125
//	kdDebug(14140) << k_funcinfo << endl;
126
127
	TQDataStream writer(stream, IO_WriteOnly);
128
	writer.setByteOrder(TQDataStream::LittleEndian);
129
130
	if(compact == false)
131
	{
132
		const TQCString messageHeader = TQString("MIME-Version: 1.0\r\n"
133
			"Content-Type: application/x-msnmsgrp2p\r\n"
134
			"P2P-Dest: " + message.destination + "\r\n"
135
			"\r\n").utf8();
136
		// Set the capacity of the message buffer.
137
		stream.resize(messageHeader.length() + 48 + message.body.size() + 4);
138
		// Write the message header to the stream
139
		writer.writeRawBytes(messageHeader.data(), messageHeader.length());
140
	}
141
	else
142
	{
143
		// Set the capacity of the message buffer.
144
		stream.resize(4 + 48 + message.body.size());
145
		// Write the message size to the stream.
146
		writer << (TQ_INT32)(48+message.body.size());
147
	}
148
149
	
150
	// Write the transport headers to the stream.
151
	writer << message.header.sessionId;
152
	writer << message.header.identifier;
153
	writer << message.header.dataOffset;
154
	writer << message.header.totalDataSize;
155
	writer << message.header.dataSize;
156
	writer << message.header.flag;
157
	writer << message.header.ackSessionIdentifier;
158
	writer << message.header.ackUniqueIdentifier;
159
	writer << message.header.ackDataSize;
160
161
/*	kdDebug(14140)
162
		<< "session id, "             << message.header.sessionId << endl
163
		<< "identifier, "             << message.header.identifier << endl
164
		<< "data offset, "            << message.header.dataOffset << endl
165
		<< "total size, "             << message.header.totalDataSize << endl
166
		<< "data size, "              << message.header.dataSize << endl
167
		<< "flag, "                   << message.header.flag << endl
168
		<< "ack session identifier, " << message.header.ackSessionIdentifier << endl
169
		<< "ack unique identifier, "  << message.header.ackUniqueIdentifier << endl
170
		<< "ack data size, "          << message.header.ackDataSize
171
		<< endl;
172
*/
173
	if(message.body.size() > 0){
174
		// Write the messge body to the stream.
175
		writer.writeRawBytes(message.body.data(), message.body.size());
176
	}
177
178
	if(compact == false)
179
	{
180
		// Seek to the message application identifier section.
181
		writer.setByteOrder(TQDataStream::BigEndian);
182
		// Write the message application identifier to the stream.
183
		writer << message.applicationIdentifier;
184
185
/*		kdDebug(14140)
186
			<< "application identifier, " << message.applicationIdentifier
187
			<< endl;
188
		*/
189
	}
190
}
191
192
#include "messageformatter.moc"
(-)tdenetwork.ori/kopete/protocols/msn/messageformatter.h (-41 lines)
Lines 1-41 Link Here
1
/*
2
    messageformatter.h - msn p2p protocol
3
4
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
5
6
    *************************************************************************
7
    *                                                                       *
8
    * This program is free software; you can redistribute it and/or modify  *
9
    * it under the terms of the GNU General Public License as published by  *
10
    * the Free Software Foundation; either version 2 of the License, or     *
11
    * (at your option) any later version.                                   *
12
    *                                                                       *
13
    *************************************************************************
14
*/
15
16
#ifndef MESSAGEFORMATTER_H
17
#define MESSAGEFORMATTER_H
18
19
#include <tqobject.h>
20
21
namespace P2P{
22
	class Message;
23
}
24
25
/**
26
@author Kopete Developers
27
*/
28
namespace P2P{
29
	class MessageFormatter : public TQObject
30
	{	Q_OBJECT
31
  
32
		public:
33
			MessageFormatter(TQObject *parent = 0, const char *name = 0);
34
			~MessageFormatter();
35
36
			Message readMessage(const TQByteArray& stream, bool compact=false);
37
			void writeMessage(const Message& message, TQByteArray& stream, bool compact=false);
38
	};
39
}
40
41
#endif
(-)tdenetwork.ori/kopete/protocols/msn/msnaccount.cpp (-1499 lines)
Lines 1-1499 Link Here
1
/*
2
    msnaccount.h - Manages a single MSN account
3
4
    Copyright (c) 2003-2005 by Olivier Goffart       <ogoffart@ kde.org>
5
    Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>
6
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
7
8
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#include "msnaccount.h"
21
22
#include <config.h>
23
24
#include <tdeaction.h>
25
#include <tdeconfig.h>
26
#include <kdebug.h>
27
#include <kinputdialog.h>
28
#include <tdemessagebox.h>
29
#include <tdepopupmenu.h>
30
#include <kstandarddirs.h>
31
#include <kmdcodec.h>
32
#include <tdelocale.h>
33
34
#include <tqfile.h>
35
#include <tqregexp.h>
36
#include <tqvalidator.h>
37
#include <tqimage.h>
38
39
#include "msncontact.h"
40
#include "msnnotifysocket.h"
41
#include "msnchatsession.h"
42
#include "kopetecontactlist.h"
43
#include "kopetegroup.h"
44
#include "kopetemetacontact.h"
45
#include "kopetepassword.h"
46
#include "kopeteuiglobal.h"
47
#include "kopeteglobal.h"
48
#include "kopetechatsessionmanager.h"
49
#include "contactaddednotifydialog.h"
50
#include "kopeteutils.h"
51
52
#include "sha1.h"
53
54
55
#if !defined NDEBUG
56
#include "msndebugrawcmddlg.h"
57
#include <tdeglobal.h>
58
#endif
59
60
#if MSN_WEBCAM
61
#include "avdevice/videodevicepool.h"
62
#endif
63
64
MSNAccount::MSNAccount( MSNProtocol *parent, const TQString& AccountID, const char *name )
65
	: Kopete::PasswordedAccount ( parent, AccountID.lower(), 0, name )
66
{
67
	m_notifySocket = 0L;
68
	m_connectstatus = MSNProtocol::protocol()->NLN;
69
	m_addWizard_metaContact = 0L;
70
	m_newContactList=false;
71
72
	// Init the myself contact
73
	setMyself( new MSNContact( this, accountId(), Kopete::ContactList::self()->myself() ) );
74
	//myself()->setOnlineStatus( MSNProtocol::protocol()->FLN );
75
76
	TQObject::connect( Kopete::ContactList::self(), TQT_SIGNAL( groupRenamed( Kopete::Group *, const TQString & ) ),
77
		TQT_SLOT( slotKopeteGroupRenamed( Kopete::Group * ) ) );
78
	TQObject::connect( Kopete::ContactList::self(), TQT_SIGNAL( groupRemoved( Kopete::Group * ) ),
79
		TQT_SLOT( slotKopeteGroupRemoved( Kopete::Group * ) ) );
80
81
	TQObject::connect( Kopete::ContactList::self(), TQT_SIGNAL( globalIdentityChanged(const TQString&, const TQVariant& ) ), TQT_SLOT( slotGlobalIdentityChanged(const TQString&, const TQVariant& ) ));
82
83
	m_openInboxAction = new TDEAction( i18n( "Open Inbo&x..." ), "mail_generic", 0, this, TQT_SLOT( slotOpenInbox() ), this, "m_openInboxAction" );
84
	m_changeDNAction = new TDEAction( i18n( "&Change Display Name..." ), TQString(), 0, this, TQT_SLOT( slotChangePublicName() ), this, "renameAction" );
85
	m_startChatAction = new TDEAction( i18n( "&Start Chat..." ), "mail_generic", 0, this, TQT_SLOT( slotStartChat() ), this, "startChatAction" );
86
87
88
	TDEConfigGroup *config=configGroup();
89
90
	m_blockList   = config->readListEntry(  "blockList" ) ;
91
	m_allowList   = config->readListEntry(  "allowList" ) ;
92
	m_reverseList = config->readListEntry(  "reverseList"  ) ;
93
94
	// Load the avatar
95
	m_pictureFilename = locateLocal( "appdata", "msnpicture-"+ accountId().lower().replace(TQRegExp("[./~]"),"-")  +".png"  );
96
	resetPictureObject(true);
97
98
	static_cast<MSNContact *>( myself() )->setInfo( "PHH", config->readEntry("PHH") );
99
	static_cast<MSNContact *>( myself() )->setInfo( "PHM", config->readEntry("PHM") );
100
	static_cast<MSNContact *>( myself() )->setInfo( "PHW", config->readEntry("PHW") );
101
	//this is the display name
102
	static_cast<MSNContact *>( myself() )->setInfo( "MFN", config->readEntry("MFN") );
103
104
	//construct the group list
105
	//Before 2003-11-14 the MSN server allowed us to download the group list without downloading the whole contactlist, but it's not possible anymore
106
	TQPtrList<Kopete::Group> groupList = Kopete::ContactList::self()->groups();
107
	for ( Kopete::Group *g = groupList.first(); g; g = groupList.next() )
108
	{
109
		TQString groupGuid=g->pluginData( protocol(), accountId() + " id" );
110
		if ( !groupGuid.isEmpty() )
111
			m_groupList.insert( groupGuid , g );
112
	}
113
114
	// Set the client Id for the myself contact.  It sets what MSN feature we support.
115
	m_clientId = MSNProtocol::MSNC4 | MSNProtocol::InkFormatGIF | MSNProtocol::SupportMultiPacketMessaging;
116
117
#if MSN_WEBCAM
118
	Kopete::AV::VideoDevicePool::self()->scanDevices();
119
	if( Kopete::AV::VideoDevicePool::self()->hasDevices() )
120
	{
121
		m_clientId |= MSNProtocol::SupportWebcam;
122
	}
123
#endif
124
}
125
126
127
TQString MSNAccount::serverName()
128
{
129
	return configGroup()->readEntry(  "serverName" , "messenger.hotmail.com" );
130
}
131
132
uint MSNAccount::serverPort()
133
{
134
	return configGroup()->readNumEntry(  "serverPort" , 1863 );
135
}
136
137
bool MSNAccount::useHttpMethod() const
138
{
139
	return configGroup()->readBoolEntry(  "useHttpMethod" , false );
140
}
141
142
TQString MSNAccount::myselfClientId() const
143
{
144
	return TQString::number(m_clientId, 10);
145
}
146
147
void MSNAccount::connectWithPassword( const TQString &passwd )
148
{
149
	m_newContactList=false;
150
	if ( isConnected() )
151
	{
152
		kdDebug( 14140 ) << k_funcinfo <<"Ignoring Connect request "
153
			<< "(Already Connected)" << endl;
154
		return;
155
	}
156
157
	if ( m_notifySocket )
158
	{
159
		kdDebug( 14140 ) << k_funcinfo <<"Ignoring Connect request (Already connecting)"  << endl;
160
		return;
161
	}
162
163
	m_password = passwd;
164
165
	if ( m_password.isNull() )
166
	{
167
		kdDebug( 14140 ) << k_funcinfo <<"Abort connection (null password)"  << endl;
168
		return;
169
	}
170
171
172
	if ( contacts().count() <= 1 )
173
	{
174
		// Maybe the contactlist.xml has been removed, and the serial number not updated
175
		// ( the 1 is for the myself contact )
176
		configGroup()->writeEntry( "serial", 0 );
177
	}
178
179
	m_openInboxAction->setEnabled( false );
180
181
	createNotificationServer(serverName(), serverPort());
182
}
183
184
void MSNAccount::createNotificationServer( const TQString &host, uint port )
185
{
186
	if(m_notifySocket) //we are switching from one to another notifysocket.
187
	{
188
		//remove every slots to that socket, so we won't delete receive signals
189
		// from the old socket thinking they are from the new one
190
		TQObject::disconnect( m_notifySocket , 0, this, 0 );
191
		m_notifySocket->deleteLater(); //be sure it will be deleted
192
		m_notifySocket=0L;
193
	}
194
195
	m_msgHandle.clear();
196
197
	myself()->setOnlineStatus( MSNProtocol::protocol()->CNT );
198
199
200
	m_notifySocket = new MSNNotifySocket( this, accountId() , m_password);
201
	m_notifySocket->setUseHttpMethod( useHttpMethod() );
202
203
	TQObject::connect( m_notifySocket, TQT_SIGNAL( groupAdded( const TQString&, const TQString& ) ),
204
		TQT_SLOT( slotGroupAdded( const TQString&, const TQString& ) ) );
205
	TQObject::connect( m_notifySocket, TQT_SIGNAL( groupRenamed( const TQString&, const TQString& ) ),
206
		TQT_SLOT( slotGroupRenamed( const TQString&, const TQString& ) ) );
207
	TQObject::connect( m_notifySocket, TQT_SIGNAL( groupListed( const TQString&, const TQString& ) ),
208
		TQT_SLOT( slotGroupAdded( const TQString&, const TQString& ) ) );
209
	TQObject::connect( m_notifySocket, TQT_SIGNAL( groupRemoved( const TQString& ) ),
210
		TQT_SLOT( slotGroupRemoved( const TQString& ) ) );
211
	TQObject::connect( m_notifySocket, TQT_SIGNAL( contactList(const TQString&, const TQString&, const TQString&, uint, const TQString& ) ),
212
		TQT_SLOT( slotContactListed(const TQString&, const TQString&, const TQString&, uint, const TQString& ) ) );
213
	TQObject::connect( m_notifySocket, TQT_SIGNAL(contactAdded(const TQString&, const TQString&, const TQString&, const TQString&, const TQString& ) ),
214
		TQT_SLOT( slotContactAdded(const TQString&, const TQString&, const TQString&, const TQString&, const TQString& ) ) );
215
	TQObject::connect( m_notifySocket, TQT_SIGNAL( contactRemoved(const TQString&, const TQString&, const TQString&, const TQString& ) ),
216
		TQT_SLOT( slotContactRemoved(const TQString&, const TQString&, const TQString&, const TQString& ) ) );
217
	TQObject::connect( m_notifySocket, TQT_SIGNAL( statusChanged( const Kopete::OnlineStatus & ) ),
218
		TQT_SLOT( slotStatusChanged( const Kopete::OnlineStatus & ) ) );
219
	TQObject::connect( m_notifySocket, TQT_SIGNAL( invitedToChat( const TQString&, const TQString&, const TQString&, const TQString&, const TQString& ) ),
220
		TQT_SLOT( slotCreateChat( const TQString&, const TQString&, const TQString&, const TQString&, const TQString& ) ) );
221
	TQObject::connect( m_notifySocket, TQT_SIGNAL( startChat( const TQString&, const TQString& ) ),
222
		TQT_SLOT( slotCreateChat( const TQString&, const TQString& ) ) );
223
	TQObject::connect( m_notifySocket, TQT_SIGNAL( socketClosed() ),
224
		TQT_SLOT( slotNotifySocketClosed() ) );
225
	TQObject::connect( m_notifySocket, TQT_SIGNAL( newContactList() ),
226
		TQT_SLOT( slotNewContactList() ) );
227
	TQObject::connect( m_notifySocket, TQT_SIGNAL( receivedNotificationServer(const TQString&, uint )  ),
228
		TQT_SLOT(createNotificationServer(const TQString&, uint ) ) );
229
	TQObject::connect( m_notifySocket, TQT_SIGNAL( hotmailSeted( bool ) ),
230
		m_openInboxAction, TQT_SLOT( setEnabled( bool ) ) );
231
	TQObject::connect( m_notifySocket, TQT_SIGNAL( errorMessage(int, const TQString& ) ), 
232
		TQT_SLOT( slotErrorMessageReceived(int, const TQString& ) ) );
233
234
	m_notifySocket->setStatus( m_connectstatus );
235
	m_notifySocket->connect(host, port);
236
}
237
238
void MSNAccount::disconnect()
239
{
240
	if ( m_notifySocket )
241
		m_notifySocket->disconnect();
242
}
243
244
TDEActionMenu * MSNAccount::actionMenu()
245
{
246
	TDEActionMenu *m_actionMenu=Kopete::Account::actionMenu();
247
	if ( isConnected() )
248
	{
249
		m_openInboxAction->setEnabled( true );
250
		m_startChatAction->setEnabled( true );
251
		m_changeDNAction->setEnabled( true );
252
	}
253
	else
254
	{
255
		m_openInboxAction->setEnabled( false );
256
		m_startChatAction->setEnabled( false );
257
		m_changeDNAction->setEnabled( false );
258
	}
259
260
	m_actionMenu->popupMenu()->insertSeparator();
261
262
	m_actionMenu->insert( m_changeDNAction );
263
	m_actionMenu->insert( m_startChatAction );
264
265
//	m_actionMenu->popupMenu()->insertSeparator();
266
267
	m_actionMenu->insert( m_openInboxAction );
268
269
#if !defined NDEBUG
270
	TDEActionMenu *debugMenu = new TDEActionMenu( "Debug", m_actionMenu );
271
	debugMenu->insert( new TDEAction( i18n( "Send Raw C&ommand..." ), 0,
272
		this, TQT_SLOT( slotDebugRawCommand() ), debugMenu, "m_debugRawCommand" ) );
273
	m_actionMenu->popupMenu()->insertSeparator();
274
	m_actionMenu->insert( debugMenu );
275
#endif
276
277
	return m_actionMenu;
278
}
279
280
MSNNotifySocket *MSNAccount::notifySocket()
281
{
282
	return m_notifySocket;
283
}
284
285
286
void MSNAccount::setOnlineStatus( const Kopete::OnlineStatus &status , const TQString &reason)
287
{
288
	kdDebug( 14140 ) << k_funcinfo << status.description() << endl;
289
290
	// HACK: When changing song, do don't anything while connected
291
	if( reason.contains("[Music]") && ( status == MSNProtocol::protocol()->UNK || status == MSNProtocol::protocol()->CNT ) )
292
		return;
293
294
	// Only send personal message when logged.
295
	if( m_notifySocket && m_notifySocket->isLogged() )
296
	{
297
		// Only update the personal/status message, don't change the online status
298
		// since it's the same.
299
		if( reason.contains("[Music]") )
300
		{
301
			TQString personalMessage = reason.section("[Music]", 1);
302
			setPersonalMessage( MSNProtocol::PersonalMessageMusic, personalMessage );
303
304
			// Don't send un-needed status change.
305
			return;
306
		}
307
		else
308
		{
309
			setPersonalMessage( MSNProtocol::PersonalMessageNormal, reason );
310
		}
311
	}
312
313
	if(status.status()== Kopete::OnlineStatus::Offline)
314
		disconnect();
315
	else if ( m_notifySocket )
316
	{
317
		m_notifySocket->setStatus( status );
318
	}
319
	else
320
	{
321
		m_connectstatus = status;
322
		connect();
323
	}
324
325
	
326
}
327
328
void MSNAccount::slotStartChat()
329
{
330
331
	bool ok;
332
	TQString handle = KInputDialog::getText( i18n( "Start Chat - MSN Plugin" ),
333
		i18n( "Please enter the email address of the person with whom you want to chat:" ), TQString(), &ok ).lower();
334
	if ( ok )
335
	{
336
		if ( MSNProtocol::validContactId( handle ) )
337
		{
338
			if ( !contacts()[ handle ] )
339
				addContact( handle, handle, 0L, Kopete::Account::Temporary );
340
341
			contacts()[ handle ]->execute();
342
		}
343
		else
344
		{
345
			KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry,
346
				i18n( "<qt>You must enter a valid email address.</qt>" ), i18n( "MSN Plugin" ) );
347
		}
348
	}
349
}
350
351
void MSNAccount::slotDebugRawCommand()
352
{
353
#if !defined NDEBUG
354
	if ( !isConnected() )
355
		return;
356
357
	MSNDebugRawCmdDlg *dlg = new MSNDebugRawCmdDlg( 0L );
358
	int result = dlg->exec();
359
	if ( result == TQDialog::Accepted && m_notifySocket )
360
	{
361
		m_notifySocket->sendCommand( dlg->command(), dlg->params(),
362
					dlg->addId(), dlg->msg().replace( "\n", "\r\n" ).utf8() );
363
	}
364
	delete dlg;
365
#endif
366
}
367
368
void MSNAccount::slotChangePublicName()
369
{
370
	if ( !isConnected() )
371
	{
372
		return;
373
		//TODO:  change it anyway, and sync at the next connection
374
	}
375
		
376
	bool ok;
377
	TQString name = KInputDialog::getText( i18n( "Change Display Name - MSN Plugin" ),
378
		i18n( "Enter the new display name by which you want to be visible to your friends on MSN:" ),
379
		myself()->property( Kopete::Global::Properties::self()->nickName()).value().toString(), &ok );
380
381
	if ( ok )
382
	{
383
		if ( name.length() > 387 )
384
		{
385
			KMessageBox::error( Kopete::UI::Global::mainWidget(),
386
				i18n( "<qt>The display name you entered is too long. Please use a shorter name.\n"
387
					"Your display name has <b>not</b> been changed.</qt>" ),
388
				i18n( "Change Display Name - MSN Plugin" ) );
389
			return;
390
		}
391
392
		setPublicName( name );
393
	}
394
}
395
396
397
void MSNAccount::slotOpenInbox()
398
{
399
	if ( m_notifySocket )
400
		m_notifySocket->slotOpenInbox();
401
}
402
403
404
void MSNAccount::slotNotifySocketClosed()
405
{
406
	kdDebug( 14140 ) << k_funcinfo << endl;
407
408
	Kopete::Account::DisconnectReason reason=(Kopete::Account::DisconnectReason)(m_notifySocket->disconnectReason());
409
	m_notifySocket->deleteLater();
410
	m_notifySocket = 0l;
411
	myself()->setOnlineStatus( MSNProtocol::protocol()->FLN );
412
	setAllContactsStatus( MSNProtocol::protocol()->FLN );
413
	disconnected(reason);
414
415
	
416
	if(reason == Kopete::Account::OtherClient)
417
	{ //close all chat sessions,   so new message will arive to the other client.
418
		
419
		TQValueList<Kopete::ChatSession*> sessions = Kopete::ChatSessionManager::self()->sessions();
420
		TQValueList<Kopete::ChatSession*>::Iterator it;
421
		for (it=sessions.begin() ; it != sessions.end() ; it++ )
422
		{
423
			MSNChatSession *msnCS = dynamic_cast<MSNChatSession *>( *it );
424
			if ( msnCS && msnCS->account() == this )
425
			{
426
				msnCS->slotCloseSession();
427
			}
428
		}
429
	}
430
	
431
#if 0
432
	else if ( state == 0x10 ) // connection died unexpectedly
433
	{
434
		KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Error , i18n( "The connection with the MSN server was lost unexpectedly.\n"
435
			"If you cannot reconnect now, the server might be down. In that case, please try again later." ),
436
			i18n( "Connection Lost - MSN Plugin" ), KMessageBox::Notify );
437
	}
438
#endif
439
	m_msgHandle.clear();
440
	// kdDebug( 14140 ) << "MSNAccount::slotNotifySocketClosed - done" << endl;
441
}
442
443
void MSNAccount::slotStatusChanged( const Kopete::OnlineStatus &status )
444
{
445
//	kdDebug( 14140 ) << k_funcinfo  << status.internalStatus() <<  endl;
446
	myself()->setOnlineStatus( status );
447
448
	if(m_newContactList)
449
	{
450
		m_newContactList=false;
451
452
		TQDictIterator<Kopete::Contact> it( contacts() );
453
		for ( ; it.current(); ++it )
454
		{
455
			MSNContact *c = static_cast<MSNContact *>( *it );
456
			if(c && c->isDeleted() && c->metaContact() && !c->metaContact()->isTemporary() && c!=myself())
457
			{
458
				if(c->serverGroups().isEmpty())
459
				{ //the contact is new, add it on the server
460
					c->setOnlineStatus( MSNProtocol::protocol()->FLN );
461
					addContactServerside( c->contactId() , c->metaContact()->groups() );
462
				}
463
				else //the contact had been deleted, remove it.
464
				{
465
					c->deleteLater();
466
				}
467
			}
468
		}
469
	}
470
}
471
472
473
void MSNAccount::slotPersonalMessageChanged( const TQString& personalMessage )
474
{
475
	TQString oldPersonalMessage=myself()->property(MSNProtocol::protocol()->propPersonalMessage).value().toString() ;
476
	if ( personalMessage != oldPersonalMessage )
477
	{
478
		myself()->setProperty( MSNProtocol::protocol()->propPersonalMessage, personalMessage );
479
		configGroup()->writeEntry( "personalMessage" , personalMessage );
480
	}
481
}
482
483
void MSNAccount::setPublicName( const TQString &publicName )
484
{
485
	if ( m_notifySocket )
486
	{
487
		m_notifySocket->changePublicName( publicName, TQString() );
488
	}
489
}
490
491
void MSNAccount::setPersonalMessage( MSNProtocol::PersonalMessageType type, const TQString &personalMessage )
492
{
493
	if ( m_notifySocket )
494
	{
495
		m_notifySocket->changePersonalMessage( type, personalMessage );
496
	}
497
	/*  Eh,  if we can't change the display name, don't let make the user think it has changed
498
	else if(type == MSNProtocol::PersonalMessageNormal) // Normal personalMessage, not a dynamic one that need formatting.
499
	{
500
		slotPersonalMessageChanged( personalMessage );
501
	}*/
502
}
503
504
void MSNAccount::slotGroupAdded( const TQString& groupName, const TQString &groupGuid )
505
{
506
	if ( m_groupList.contains( groupGuid ) )
507
	{
508
		// Group can already be in the list since the idle timer does a 'List Groups'
509
		// command. Simply return, don't issue a warning.
510
		// kdDebug( 14140 ) << k_funcinfo << "Group " << groupName << " already in list, skipped." << endl;
511
		return;
512
	}
513
514
	//--------- Find the appropriate Kopete::Group, or create one ---------//
515
	TQPtrList<Kopete::Group> groupList = Kopete::ContactList::self()->groups();
516
	Kopete::Group *fallBack = 0L;
517
518
	//check if we have one in the old group list. if yes, update the id translate map.
519
	for(TQMap<TQString, Kopete::Group*>::Iterator it=m_oldGroupList.begin() ; it != m_oldGroupList.end() ; ++it )
520
	{
521
		Kopete::Group *g=it.data();
522
		if (g && g->pluginData( protocol(), accountId() + " displayName" ) == groupName  &&
523
				g->pluginData( protocol(), accountId() + " id" ).isEmpty() )
524
		{ //it has the same name! we got it.    (and it is not yet an msn group)
525
			fallBack=g;
526
			/*if ( g->displayName() != groupName )
527
			{
528
				// The displayName was changed in Kopete while we were offline
529
				// FIXME: update the server right now
530
			}*/
531
			break;
532
		}
533
	}
534
535
	if(!fallBack)
536
	{
537
		//it's certenly a new group !  search if one already exist with the same displayname.
538
		for ( Kopete::Group *g = groupList.first(); g; g = groupList.next() )
539
		{
540
			/*   --This has been replaced by the loop right before.
541
			if ( !g->pluginData( protocol(), accountId() +  " id" ).isEmpty() )
542
			{
543
				if ( g->pluginData( protocol(), accountId() + " id" ).toUInt() == groupNumber )
544
				{
545
					m_groupList.insert( groupNumber, g );
546
					TQString oldGroupName;
547
					if ( g->pluginData( protocol(), accountId() + " displayName" ) != groupName )
548
					{
549
						// The displayName of the group has been modified by another client
550
						slotGroupRenamed( groupName, groupNumber );
551
					}
552
					return;
553
				}
554
			}
555
			else {*/
556
			if ( g->displayName() == groupName && (groupGuid.isEmpty()|| g->type()==Kopete::Group::Normal)  &&
557
					g->pluginData( protocol(), accountId() + " id" ).isEmpty()  )
558
			{
559
				fallBack = g;
560
				kdDebug( 14140 ) << k_funcinfo << "We didn't found the group " << groupName <<" in the old MSN group.  But kopete has already one with the same name." <<  endl;
561
				break;
562
			}
563
		}
564
	}
565
566
	if ( !fallBack )
567
	{
568
		if( groupGuid.isEmpty()  )
569
		{	// The group #0 is an unremovable group. his default name is "~" ,
570
			// but the official client rename it i18n("others contact") at the first
571
			// connection.
572
			// In many case, the users don't use that group as a real group, or just as
573
			// a group to put all contact that are not sorted.
574
			fallBack = Kopete::Group::topLevel();
575
		}
576
		else
577
		{
578
			fallBack = new Kopete::Group( groupName );
579
			Kopete::ContactList::self()->addGroup( fallBack );
580
			kdDebug( 14140 ) << k_funcinfo << "We didn't found the group " << groupName <<" So we're creating a new one." <<  endl;
581
582
		}
583
	}
584
585
	fallBack->setPluginData( protocol(), accountId() + " id", groupGuid );
586
	fallBack->setPluginData( protocol(), accountId() + " displayName", groupName );
587
	m_groupList.insert( groupGuid, fallBack );
588
589
	// We have pending groups that we need add a contact to
590
	if ( tmp_addToNewGroup.contains(groupName) )
591
	{
592
		TQStringList list=tmp_addToNewGroup[groupName];
593
		for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
594
		{
595
			TQString contactId = *it;
596
			kdDebug( 14140 ) << k_funcinfo << "Adding to new group: " << contactId <<  endl;
597
			MSNContact *c = static_cast<MSNContact *>(contacts()[contactId]);
598
			if(c && c->hasProperty(MSNProtocol::protocol()->propGuid.key()) )
599
				notifySocket()->addContact( contactId, MSNProtocol::FL, TQString(), c->guid(), groupGuid );
600
			else
601
			{
602
				// If we get to here, we're currently adding a new contact, add the groupGUID to the groupList
603
				// to add when contact will be added to contactlist.
604
				if( tmp_addNewContactToGroup.contains( contactId ) )
605
					tmp_addNewContactToGroup[contactId].append(groupGuid);
606
				else
607
					tmp_addNewContactToGroup.insert(contactId, TQStringList(groupGuid) );
608
			}
609
		}
610
		tmp_addToNewGroup.remove(groupName);
611
	}
612
}
613
614
void MSNAccount::slotGroupRenamed( const TQString &groupGuid, const TQString& groupName )
615
{
616
	if ( m_groupList.contains( groupGuid ) )
617
	{
618
		m_groupList[ groupGuid ]->setPluginData( protocol(), accountId() + " id", groupGuid );
619
		m_groupList[ groupGuid ]->setPluginData( protocol(), accountId() + " displayName", groupName );
620
		m_groupList[ groupGuid ]->setDisplayName( groupName );
621
	}
622
	else
623
	{
624
		slotGroupAdded( groupName, groupGuid );
625
	}
626
}
627
628
void MSNAccount::slotGroupRemoved( const TQString& groupGuid )
629
{
630
	if ( m_groupList.contains( groupGuid ) )
631
	{
632
		m_groupList[ groupGuid ]->setPluginData( protocol(), TQMap<TQString,TQString>() );
633
		m_groupList.remove( groupGuid );
634
	}
635
}
636
637
void MSNAccount::addGroup( const TQString &groupName, const TQString& contactToAdd )
638
{
639
	if ( !contactToAdd.isNull()  )
640
	{
641
		if( tmp_addToNewGroup.contains(groupName) )
642
		{
643
			tmp_addToNewGroup[groupName].append(contactToAdd);
644
			//A group with the same name is about to be added,
645
			// we don't need to add a second group with the same name
646
			kdDebug( 14140 ) << k_funcinfo << "no need to re-add " << groupName << " for " << contactToAdd  <<  endl;
647
			return;
648
		}
649
		else
650
		{
651
			tmp_addToNewGroup.insert(groupName,TQStringList(contactToAdd));
652
			kdDebug( 14140 ) << k_funcinfo << "preparing to add " << groupName << " for " << contactToAdd  <<  endl;
653
		}
654
	}
655
656
	if ( m_notifySocket )
657
		m_notifySocket->addGroup( groupName );
658
659
}
660
661
void MSNAccount::slotKopeteGroupRenamed( Kopete::Group *g )
662
{
663
	if ( notifySocket() && g->type() == Kopete::Group::Normal )
664
	{
665
		if ( !g->pluginData( protocol(), accountId() + " id" ).isEmpty() &&
666
			g->displayName() != g->pluginData( protocol(), accountId() + " displayName" ) &&
667
			m_groupList.contains( g->pluginData( protocol(), accountId() + " id" ) ) )
668
		{
669
			notifySocket()->renameGroup( g->displayName(), g->pluginData( protocol(), accountId() + " id" ) );
670
		}
671
	}
672
}
673
674
void MSNAccount::slotKopeteGroupRemoved( Kopete::Group *g )
675
{
676
	//The old gorup list is only used whe syncing the contactlist.
677
	//We can assume the contactlist is already fully synced at this time.
678
	//The group g is maybe in the oldGroupList.  We remove everithing since
679
	//we don't need it anymore, no need to search it
680
	m_oldGroupList.clear();
681
682
	
683
	if ( !g->pluginData( protocol(), accountId() + " id" ).isEmpty() )
684
	{
685
		TQString groupGuid = g->pluginData( protocol(), accountId() + " id" );
686
		if ( !m_groupList.contains( groupGuid ) )
687
		{
688
			// the group is maybe already removed in the server
689
			slotGroupRemoved( groupGuid );
690
			return;
691
		}
692
693
		//this is also done later, but he have to do it now!
694
		// (in slotGroupRemoved)
695
		m_groupList.remove(groupGuid);
696
697
		if ( groupGuid.isEmpty() )
698
		{
699
			// the group #0 can't be deleted
700
			// then we set it as the top-level group
701
			if ( g->type() == Kopete::Group::TopLevel )
702
				return;
703
704
			Kopete::Group::topLevel()->setPluginData( protocol(), accountId() + " id", "" );
705
			Kopete::Group::topLevel()->setPluginData( protocol(), accountId() + " displayName", g->pluginData( protocol(), accountId() + " displayName" ) );
706
			g->setPluginData( protocol(), accountId() + " id", TQString() ); // the group should be soon deleted, but make sure
707
708
			return;
709
		}
710
711
		if ( m_notifySocket )
712
		{
713
			bool still_have_contact=false;
714
			// if contact are contains only in the group we are removing, abort the 
715
			TQDictIterator<Kopete::Contact> it( contacts() );
716
			for ( ; it.current(); ++it )
717
			{
718
				MSNContact *c = static_cast<MSNContact *>( it.current() );
719
				if ( c && c->serverGroups().contains( groupGuid )  )
720
				{
721
					/** don't do that becasue theses may already have been sent
722
					m_notifySocket->removeContact( c->contactId(), groupNumber, MSNProtocol::FL );
723
					*/
724
					still_have_contact=true;
725
					break;
726
				}
727
			}
728
			if(!still_have_contact)
729
				m_notifySocket->removeGroup( groupGuid );
730
		}
731
	}
732
}
733
734
void MSNAccount::slotNewContactList()
735
{
736
		m_oldGroupList=m_groupList;
737
		for(TQMap<TQString, Kopete::Group*>::Iterator it=m_oldGroupList.begin() ; it != m_oldGroupList.end() ; ++it )
738
		{	//they are about to be changed
739
			if(it.data())
740
				it.data()->setPluginData( protocol(), accountId() + " id", TQString() );
741
		}
742
743
		m_allowList.clear();
744
		m_blockList.clear();
745
		m_reverseList.clear();
746
		m_groupList.clear();
747
		TDEConfigGroup *config=configGroup();
748
		config->writeEntry( "blockList" , TQString() ) ;
749
		config->writeEntry( "allowList" , TQString() );
750
		config->writeEntry( "reverseList" , TQString() );
751
752
		// clear all date information which will be received.
753
		// if the information is not anymore on the server, it will not be received
754
		TQDictIterator<Kopete::Contact> it( contacts() );
755
		for ( ; it.current(); ++it )
756
		{
757
			MSNContact *c = static_cast<MSNContact *>( *it );
758
			c->setBlocked( false );
759
			c->setAllowed( false );
760
			c->setReversed( false );
761
			c->setDeleted( true );
762
			c->setInfo( "PHH", TQString() );
763
			c->setInfo( "PHW", TQString() );
764
			c->setInfo( "PHM", TQString() );
765
			c->removeProperty( MSNProtocol::protocol()->propGuid );
766
		}
767
		m_newContactList=true;
768
}
769
770
void MSNAccount::slotContactListed( const TQString& handle, const TQString& publicName, const TQString &contactGuid, uint lists, const TQString& groups )
771
{
772
	// On empty lists handle might be empty, ignore that
773
	// ignore also the myself contact.
774
	if ( handle.isEmpty() || handle==accountId())
775
		return;
776
777
	MSNContact *c = static_cast<MSNContact *>( contacts()[ handle ] );
778
779
	if ( lists & 1 )	// FL
780
	{
781
		TQStringList contactGroups = TQStringList::split( ",", groups, false );
782
		if ( c )
783
		{
784
			if( !c->metaContact() )
785
			{
786
				kdWarning( 14140 ) << k_funcinfo << "the contact " << c->contactId() << " has no meta contact" <<endl;
787
				Kopete::MetaContact *metaContact = new Kopete::MetaContact();
788
789
				c->setMetaContact(metaContact);
790
				Kopete::ContactList::self()->addMetaContact( metaContact );
791
			}
792
793
			// Contact exists, update data.
794
			// Merging difference between server contact list and Kopete::Contact's contact list into MetaContact's contact-list
795
			c->setOnlineStatus( MSNProtocol::protocol()->FLN );
796
			if(!publicName.isEmpty() && publicName!=handle)
797
				c->setProperty( Kopete::Global::Properties::self()->nickName() , publicName );
798
			else
799
				c->removeProperty( Kopete::Global::Properties::self()->nickName() );
800
			c->setProperty( MSNProtocol::protocol()->propGuid, contactGuid);
801
802
			const TQMap<TQString, Kopete::Group *> oldServerGroups = c->serverGroups();
803
			c->clearServerGroups();
804
			for ( TQStringList::ConstIterator it = contactGroups.begin(); it != contactGroups.end(); ++it )
805
			{
806
				TQString newServerGroupID =  *it;
807
				if(m_groupList.contains(newServerGroupID))
808
				{
809
					Kopete::Group *newServerGroup=m_groupList[ newServerGroupID ] ;
810
					c->contactAddedToGroup( newServerGroupID, newServerGroup );
811
					if( !c->metaContact()->groups().contains(newServerGroup) )
812
					{
813
						// The contact has been added in a group by another client
814
						c->metaContact()->addToGroup( newServerGroup );
815
					}
816
				}
817
			}
818
819
			for ( TQMap<TQString, Kopete::Group *>::ConstIterator it = oldServerGroups.begin(); it != oldServerGroups.end(); ++it )
820
			{
821
				Kopete::Group *old_group=m_oldGroupList[it.key()];
822
				if(old_group)
823
				{
824
					TQString oldnewID=old_group->pluginData(protocol() , accountId() +" id");
825
					if ( !oldnewID.isEmpty() && contactGroups.contains( oldnewID ) )
826
						continue; //ok, it's correctn no need to do anything.
827
828
					c->metaContact()->removeFromGroup( old_group );
829
				}
830
			}
831
832
			c->setDeleted(false);
833
			
834
			// Update server if the contact has been moved to another group while MSN was offline
835
			c->sync();
836
		}
837
		else
838
		{
839
			Kopete::MetaContact *metaContact = new Kopete::MetaContact();
840
841
			c = new MSNContact( this, handle, metaContact );
842
			c->setDeleted(true); //we don't want to sync
843
			c->setOnlineStatus( MSNProtocol::protocol()->FLN );
844
			if(!publicName.isEmpty() && publicName!=handle)
845
				c->setProperty( Kopete::Global::Properties::self()->nickName() , publicName );
846
			else
847
				c->removeProperty( Kopete::Global::Properties::self()->nickName() );
848
			c->setProperty( MSNProtocol::protocol()->propGuid, contactGuid );
849
850
			for ( TQStringList::Iterator it = contactGroups.begin();
851
				it != contactGroups.end(); ++it )
852
			{
853
				TQString groupGuid = *it;
854
				if(m_groupList.contains(groupGuid))
855
				{
856
					c->contactAddedToGroup( groupGuid, m_groupList[ groupGuid ] );
857
					metaContact->addToGroup( m_groupList[ groupGuid ] );
858
				}
859
			}
860
			Kopete::ContactList::self()->addMetaContact( metaContact );
861
			
862
			c->setDeleted(false);
863
		}
864
	}
865
	else //the contact is _not_ in the FL, it has been removed
866
	{
867
		if(c)
868
		{
869
			c->setOnlineStatus( static_cast<MSNProtocol*>(protocol())->UNK );
870
			c->clearServerGroups();
871
			//TODO: display a message and suggest to remove the contact.
872
			//  but i fear a simple messageBox  QuestionYesNo here gives a nice crash.
873
			   //delete ct;
874
		}
875
	}
876
	if ( lists & 2 )
877
		slotContactAdded( handle, "AL", publicName, TQString(), TQString() );
878
	else if(c)
879
		c->setAllowed(false);
880
	if ( lists & 4 )
881
		slotContactAdded( handle, "BL", publicName, TQString(), TQString() );
882
	else if(c)
883
		c->setBlocked(false);
884
	if ( lists & 8 )
885
		slotContactAdded( handle, "RL", publicName, TQString(), TQString() );
886
	else if(c)
887
		c->setReversed(false);
888
	if ( lists & 16 ) // This contact is on the pending list. Add to the reverse list and delete from the pending list
889
	{
890
		notifySocket()->addContact( handle, MSNProtocol::RL, TQString(), TQString(), TQString() );
891
		notifySocket()->removeContact( handle, MSNProtocol::PL, TQString(), TQString() );
892
	}
893
}
894
895
void MSNAccount::slotContactAdded( const TQString& handle, const TQString& list, const TQString& publicName, const TQString& contactGuid, const TQString &groupGuid )
896
{
897
	if ( list == "FL" )
898
	{
899
		bool new_contact = false;
900
		if ( !contacts()[ handle ] )
901
		{
902
			new_contact = true;
903
904
			Kopete::MetaContact *m= m_addWizard_metaContact ? m_addWizard_metaContact :  new Kopete::MetaContact();
905
906
			MSNContact *c = new MSNContact( this, handle, m );
907
			if(!publicName.isEmpty() && publicName!=handle)
908
				c->setProperty( Kopete::Global::Properties::self()->nickName() , publicName );
909
			else
910
				c->removeProperty( Kopete::Global::Properties::self()->nickName() );
911
			c->setProperty( MSNProtocol::protocol()->propGuid, contactGuid );
912
			// Add the new contact to the group he belongs.
913
			if ( tmp_addNewContactToGroup.contains(handle) )
914
			{
915
				TQStringList list = tmp_addNewContactToGroup[handle];
916
				for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
917
				{
918
					TQString groupGuid = *it;
919
					
920
					// If the group didn't exist yet (yay for async operations), don't add the contact to the group
921
					// Let slotGroupAdded do it.
922
					if( m_groupList.contains(groupGuid) )
923
					{
924
						kdDebug( 14140 ) << k_funcinfo << "Adding " << handle << " to group: " << groupGuid <<  endl;
925
						notifySocket()->addContact( handle, MSNProtocol::FL, TQString(), contactGuid, groupGuid );
926
						
927
						c->contactAddedToGroup( groupGuid, m_groupList[ groupGuid ] );
928
						
929
						m->addToGroup( m_groupList[ groupGuid ] );
930
						
931
					}
932
					if ( !m_addWizard_metaContact )
933
					{
934
						Kopete::ContactList::self()->addMetaContact( m );
935
					}
936
				}
937
				tmp_addNewContactToGroup.remove(handle);
938
			}
939
			
940
			c->setOnlineStatus( MSNProtocol::protocol()->FLN );
941
942
			m_addWizard_metaContact = 0L;
943
		}
944
		if ( !new_contact )
945
		{
946
			// Contact has been added to a group
947
			MSNContact *c = findContactByGuid(contactGuid);
948
			if(c != 0L)
949
			{
950
				// Make sure that the contact has always his contactGUID.
951
				if( !c->hasProperty(MSNProtocol::protocol()->propGuid.key()) )
952
					c->setProperty( MSNProtocol::protocol()->propGuid, contactGuid );
953
954
				if ( c->onlineStatus() == MSNProtocol::protocol()->UNK )
955
					c->setOnlineStatus( MSNProtocol::protocol()->FLN );
956
	
957
				if ( c->metaContact() && c->metaContact()->isTemporary() )
958
					c->metaContact()->setTemporary( false,  m_groupList.contains( groupGuid ) ?  m_groupList[ groupGuid ] : 0L );
959
				else
960
				{
961
					if(m_groupList.contains(groupGuid))
962
					{
963
						if( c->metaContact() )
964
							c->metaContact()->addToGroup( m_groupList[groupGuid] );
965
						c->contactAddedToGroup( groupGuid, m_groupList[ groupGuid ] );
966
					}
967
				}
968
			}
969
		}
970
971
		if ( !handle.isEmpty() && !m_allowList.contains( handle ) && !m_blockList.contains( handle ) )
972
		{
973
			kdDebug(14140) << k_funcinfo << "Trying to add contact to AL. " << endl;
974
			notifySocket()->addContact(handle, MSNProtocol::AL, TQString(), TQString(), TQString() );
975
		}
976
	}
977
	else if ( list == "BL" )
978
	{
979
		if ( contacts()[ handle ] )
980
			static_cast<MSNContact *>( contacts()[ handle ] )->setBlocked( true );
981
		if ( !m_blockList.contains( handle ) )
982
		{
983
			m_blockList.append( handle );
984
			configGroup()->writeEntry( "blockList" , m_blockList ) ;
985
		}
986
	}
987
	else if ( list == "AL" )
988
	{
989
		if ( contacts()[ handle ] )
990
			static_cast<MSNContact *>( contacts()[ handle ] )->setAllowed( true );
991
		if ( !m_allowList.contains( handle ) )
992
		{
993
			m_allowList.append( handle );
994
			configGroup()->writeEntry( "allowList" , m_allowList ) ;
995
		}
996
	}
997
	else if ( list == "RL" )
998
	{
999
		// search for new Contacts
1000
		Kopete::Contact *ct=contacts()[ handle ];
1001
		if ( !ct || !ct->metaContact() || ct->metaContact()->isTemporary() )
1002
		{
1003
			// Users in the allow list or block list now never trigger the
1004
			// 'new user' dialog, which makes it impossible to add those here.
1005
			// Not necessarily bad, but the usability effects need more thought
1006
			// before I declare it good :- )
1007
			if ( !m_allowList.contains( handle ) && !m_blockList.contains( handle ) )
1008
			{
1009
				TQString nick;			//in most case, the public name is not know
1010
				if(publicName!=handle)  // so we don't whos it if it is not know
1011
					nick=publicName;
1012
				Kopete::UI::ContactAddedNotifyDialog *dialog=
1013
						new Kopete::UI::ContactAddedNotifyDialog(  handle,nick,this,
1014
								Kopete::UI::ContactAddedNotifyDialog::InfoButton );
1015
				TQObject::connect(dialog,TQT_SIGNAL(applyClicked(const TQString&)),
1016
								 this,TQT_SLOT(slotContactAddedNotifyDialogClosed(const TQString& )));
1017
				dialog->show();
1018
			}
1019
		}
1020
		else
1021
		{
1022
			static_cast<MSNContact *>( ct )->setReversed( true );
1023
		}
1024
		m_reverseList.append( handle );
1025
		configGroup()->writeEntry( "reverseList" , m_reverseList ) ;
1026
	}
1027
}
1028
1029
void MSNAccount::slotContactRemoved( const TQString& handle, const TQString& list, const TQString& contactGuid, const TQString& groupGuid )
1030
{
1031
	kdDebug( 14140 ) << k_funcinfo << "handle: " << handle << " list: " << list << " contact-uid: " << contactGuid << endl;
1032
	MSNContact *c=static_cast<MSNContact *>( contacts()[ handle ] );
1033
	if ( list == "BL" )
1034
	{
1035
		m_blockList.remove( handle );
1036
		configGroup()->writeEntry( "blockList" , m_blockList ) ;
1037
		if ( !m_allowList.contains( handle ) )
1038
			notifySocket()->addContact( handle, MSNProtocol::AL, TQString(), TQString(), TQString() );
1039
1040
		if(c)
1041
			c->setBlocked( false );
1042
	}
1043
	else if ( list == "AL" )
1044
	{
1045
		m_allowList.remove( handle );
1046
		configGroup()->writeEntry( "allowList" , m_allowList ) ;
1047
		if ( !m_blockList.contains( handle ) )
1048
			notifySocket()->addContact( handle, MSNProtocol::BL, TQString(), TQString(), TQString() );
1049
1050
		if(c)
1051
			c->setAllowed( false );
1052
	}
1053
	else if ( list == "RL" )
1054
	{
1055
		m_reverseList.remove( handle );
1056
		configGroup()->writeEntry( "reverseList" , m_reverseList ) ;
1057
1058
		if ( c )
1059
		{
1060
			// Contact is removed from the reverse list
1061
			// only MSN can do this, so this is currently not supported
1062
			c->setReversed( false );
1063
		/*
1064
			InfoWidget *info = new InfoWidget( 0 );
1065
			info->title->setText( "<b>" + i18n( "Contact removed!" ) +"</b>" );
1066
			TQString dummy;
1067
			dummy = "<center><b>" + imContact->getPublicName() + "( " +imContact->getHandle()  +" )</b></center><br>";
1068
			dummy += i18n( "has removed you from his contact list!" ) + "<br>";
1069
			dummy += i18n( "This contact is now removed from your contact list" );
1070
			info->infoText->setText( dummy );
1071
			info->setCaption( "KMerlin - Info" );
1072
			info->show();
1073
		*/
1074
		}
1075
	}
1076
	else if ( list == "FL" )
1077
	{
1078
		// The FL list only use the contact GUID, use the contact referenced by the GUID.
1079
		MSNContact *contactRemoved = findContactByGuid(contactGuid);
1080
		TQStringList groupGuidList;
1081
		bool deleteContact = groupGuid.isEmpty() ? true : false; // Delete the contact when the group GUID is empty.
1082
		// Remove the contact from the contact list for all the group he is a member.
1083
		if( groupGuid.isEmpty() )
1084
		{
1085
			if(contactRemoved)
1086
			{
1087
				TQPtrList<Kopete::Group> groupList = contactRemoved->metaContact()->groups();
1088
				for( TQPtrList<Kopete::Group>::Iterator it = groupList.begin(); it != groupList.end(); ++it )
1089
				{
1090
					Kopete::Group *group = *it;
1091
					if ( !group->pluginData( protocol(), accountId() + " id" ).isEmpty() )
1092
					{
1093
						groupGuidList.append( group->pluginData( protocol(), accountId() + " id" ) );
1094
					}
1095
				}
1096
			}
1097
		}
1098
		else
1099
		{
1100
			groupGuidList.append( groupGuid );
1101
		}
1102
		
1103
		if( !groupGuidList.isEmpty() )
1104
		{
1105
			TQStringList::const_iterator stringIt;
1106
			for( stringIt = groupGuidList.begin(); stringIt != groupGuidList.end(); ++stringIt )
1107
			{
1108
				// Contact is removed from the FL list, remove it from the group
1109
				if(contactRemoved != 0L)
1110
						contactRemoved->contactRemovedFromGroup( *stringIt );
1111
					
1112
				//check if the group is now empty to remove it
1113
				if ( m_notifySocket )
1114
				{
1115
					bool still_have_contact=false;
1116
					// if contact are contains only in the group we are removing, abort the 
1117
					TQDictIterator<Kopete::Contact> it( contacts() );
1118
					for ( ; it.current(); ++it )
1119
					{
1120
						MSNContact *c2 = static_cast<MSNContact *>( it.current() );
1121
						if ( c2->serverGroups().contains( *stringIt ) )
1122
						{
1123
							still_have_contact=true;
1124
							break;
1125
						}
1126
					}
1127
					if(!still_have_contact)
1128
						m_notifySocket->removeGroup( *stringIt );
1129
				}
1130
			}
1131
		}
1132
		if(deleteContact && contactRemoved)
1133
		{
1134
			kdDebug(14140) << k_funcinfo << "Deleting the MSNContact " << contactRemoved->contactId() << endl;
1135
			contactRemoved->deleteLater();
1136
		}
1137
	}
1138
}
1139
1140
void MSNAccount::slotCreateChat( const TQString& address, const TQString& auth )
1141
{
1142
	slotCreateChat( 0L, address, auth, m_msgHandle.first(), m_msgHandle.first() );
1143
}
1144
1145
void MSNAccount::slotCreateChat( const TQString& ID, const TQString& address, const TQString& auth,
1146
	const TQString& handle_, const TQString&  publicName )
1147
{
1148
	TQString handle = handle_.lower();
1149
1150
	if ( handle.isEmpty() )
1151
	{
1152
		// we have lost the handle?
1153
		kdDebug(14140) << k_funcinfo << "Impossible to open a chat session, I forgot the contact to invite" <<endl;
1154
		// forget it
1155
		return;
1156
	}
1157
1158
//	kdDebug( 14140 ) << k_funcinfo <<"Creating chat for " << handle << endl;
1159
1160
	if ( !contacts()[ handle ] )
1161
		addContact( handle, publicName, 0L, Kopete::Account::Temporary );
1162
1163
	MSNContact *c = static_cast<MSNContact *>( contacts()[ handle ] );
1164
1165
	if ( c && myself() )
1166
	{
1167
		// we can't use simply c->manager(true) here to get the manager, because this will re-open
1168
		// another chat session, and then, close this new one. We have to re-create the manager manualy.
1169
		MSNChatSession *manager = dynamic_cast<MSNChatSession*>( c->manager( Kopete::Contact::CannotCreate ) );
1170
		if(!manager)
1171
		{
1172
			Kopete::ContactPtrList chatmembers;
1173
			chatmembers.append(c);
1174
			manager = new MSNChatSession( protocol(), myself(), chatmembers  );
1175
		}
1176
1177
		manager->createChat( handle, address, auth, ID );
1178
1179
		/**
1180
		 *  This code should open a chatwindow when a socket is open
1181
		 * It has been disabled because pidgin open switchboeard too often
1182
		 *
1183
		 * the solution is to open the window only when the contact start typing
1184
		 * see MSNChatSession::receivedTypingMsg
1185
		 *
1186
1187
		TDEGlobal::config()->setGroup( "MSN" );
1188
		bool notifyNewChat = TDEGlobal::config()->readBoolEntry( "NotifyNewChat", false );
1189
		if ( !ID.isEmpty() && notifyNewChat )
1190
		{
1191
			// this temporary message should open the window if they not exist
1192
			TQString body = i18n( "%1 has started a chat with you" ).arg( c->metaContact()->displayName() );
1193
			Kopete::Message tmpMsg = Kopete::Message( c, manager->members(), body, Kopete::Message::Internal, Kopete::Message::PlainText );
1194
			manager->appendMessage( tmpMsg );
1195
		}
1196
		 */
1197
	}
1198
1199
	if(!m_msgHandle.isEmpty())
1200
		m_msgHandle.pop_front();
1201
}
1202
1203
void MSNAccount::slotStartChatSession( const TQString& handle )
1204
{
1205
	// First create a message manager, because we might get an existing
1206
	// manager back, in which case we likely also have an active switchboard
1207
	// connection to reuse...
1208
1209
	MSNContact *c = static_cast<MSNContact *>( contacts()[ handle ] );
1210
	// if ( isConnected() && c && myself() && handle != m_msnId )
1211
	if ( m_notifySocket && c && myself() && handle != accountId() )
1212
	{
1213
		if ( !c->manager(Kopete::Contact::CannotCreate) || !static_cast<MSNChatSession *>( c->manager( Kopete::Contact::CanCreate ) )->service() )
1214
		{
1215
			m_msgHandle.prepend(handle);
1216
			m_notifySocket->createChatSession();
1217
		}
1218
	}
1219
}
1220
1221
void MSNAccount::slotContactAddedNotifyDialogClosed(const TQString& handle)
1222
{
1223
	const Kopete::UI::ContactAddedNotifyDialog *dialog =
1224
			dynamic_cast<const Kopete::UI::ContactAddedNotifyDialog *>(sender());
1225
	if(!dialog || !m_notifySocket)
1226
		return;
1227
1228
	if(dialog->added())
1229
	{
1230
		Kopete::MetaContact *mc=dialog->addContact();
1231
		if(mc)
1232
		{ //if the contact has been added this way, it's because the other user added us.
1233
		  // don't forgot to set the reversed flag  (Bug 114400)
1234
			MSNContact *c=dynamic_cast<MSNContact*>(mc->contacts().first());
1235
			if(c && c->contactId() == handle )
1236
			{
1237
				c->setReversed( true );
1238
			}
1239
		}
1240
	}
1241
1242
	if ( !dialog->authorized() )
1243
	{
1244
		if ( m_allowList.contains( handle ) )
1245
			m_notifySocket->removeContact( handle, MSNProtocol::AL, TQString(), TQString() );
1246
		else if ( !m_blockList.contains( handle ) )
1247
			m_notifySocket->addContact( handle, MSNProtocol::BL, TQString(), TQString(), TQString() );
1248
	}
1249
	else
1250
	{
1251
		if ( m_blockList.contains( handle ) )
1252
			m_notifySocket->removeContact( handle, MSNProtocol::BL, TQString(), TQString() );
1253
		else if ( !m_allowList.contains( handle ) )
1254
			m_notifySocket->addContact( handle, MSNProtocol::AL, TQString(), TQString(), TQString() );
1255
	}
1256
1257
	
1258
}
1259
1260
void MSNAccount::slotGlobalIdentityChanged( const TQString &key, const TQVariant &value )
1261
{
1262
	if( !configGroup()->readBoolEntry("ExcludeGlobalIdentity", false) )
1263
	{
1264
		if(key == Kopete::Global::Properties::self()->nickName().key())
1265
		{
1266
			TQString oldNick = myself()->property( Kopete::Global::Properties::self()->nickName()).value().toString();
1267
			TQString newNick = value.toString();
1268
		
1269
			if(newNick != oldNick)
1270
			{
1271
				setPublicName( value.toString() );
1272
			}
1273
		}
1274
		else if(key == Kopete::Global::Properties::self()->photo().key())
1275
		{
1276
			m_pictureFilename = value.toString();
1277
			kdDebug( 14140 ) << k_funcinfo << m_pictureFilename << endl;
1278
			resetPictureObject(false, true);
1279
		}
1280
	}
1281
}
1282
1283
void MSNAccount::slotErrorMessageReceived( int type, const TQString &msg )
1284
{
1285
	TQString caption = i18n( "MSN Plugin" );
1286
1287
	// Use different notification type based on the error context.
1288
	switch(type)
1289
	{
1290
		case MSNSocket::ErrorConnectionLost:
1291
		{
1292
			Kopete::Utils::notifyConnectionLost( this, caption, msg );
1293
			break;
1294
		}
1295
		case MSNSocket::ErrorConnectionError:
1296
		{
1297
			Kopete::Utils::notifyConnectionError( this, caption, msg );
1298
			break;
1299
		}
1300
		case MSNSocket::ErrorCannotConnect:
1301
		{
1302
			Kopete::Utils::notifyCannotConnect( this );
1303
			break;
1304
		}
1305
		case MSNSocket::ErrorInformation:
1306
		{
1307
			KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Information, msg, caption );
1308
			break;
1309
		}
1310
		case MSNSocket::ErrorServerError:
1311
		default:
1312
		{
1313
			Kopete::Utils::notifyServerError( this, caption, msg );
1314
			break;
1315
		}
1316
	}
1317
}
1318
1319
bool MSNAccount::createContact( const TQString &contactId, Kopete::MetaContact *metaContact )
1320
{
1321
	if ( !metaContact->isTemporary() && m_notifySocket)
1322
	{
1323
		m_addWizard_metaContact = metaContact;
1324
		
1325
		addContactServerside(contactId, metaContact->groups());
1326
1327
		// FIXME: Find out if this contact was really added or not!
1328
		return true;
1329
	}
1330
	else
1331
	{
1332
		// This is a temporary contact. ( a person who messaged us but is not on our conntact list.
1333
		// We don't want to create it on the server.Just create the local contact object and add it
1334
		// Or we are diconnected, and in that case, the contact will be added when connecting
1335
		MSNContact *newContact = new MSNContact( this, contactId, metaContact );
1336
		newContact->setDeleted(true);
1337
		return true;
1338
	}
1339
1340
}
1341
1342
void MSNAccount::addContactServerside(const TQString &contactId, TQPtrList<Kopete::Group> groupList)
1343
{
1344
	// First of all, fill the temporary group list. The contact will be moved to his group(s).
1345
	// When we receive back his contact GUID(required to move a contact between groups)
1346
	for( Kopete::Group *group = groupList.first(); group; group = groupList.next() )
1347
	{
1348
		// TODO: It it time that libkopete generate a unique ID that contains protocols, account and contact id.
1349
		TQString groupId  = group->pluginData( protocol(), accountId() + " id" );
1350
		// If the groupId is empty, that's mean the Kopete group is not on the MSN server.
1351
		if( !groupId.isEmpty() )
1352
		{
1353
			// Something got corrupted on contactlist.xml
1354
			if( !m_groupList.contains(groupId) )
1355
			{
1356
				// Clear the group plugin data.
1357
				group->setPluginData( protocol() , accountId() + " id" , TQString());
1358
				group->setPluginData( protocol() , accountId() + " displayName" , TQString());
1359
				kdDebug( 14140 ) << k_funcinfo << " Group " << group->displayName() << " marked with id #" << groupId << " does not seems to be anymore on the server" << endl;
1360
1361
				// Add the group on MSN server, will fix the corruption.
1362
				kdDebug(14140) << k_funcinfo << "Fixing group corruption, re-adding " << group->displayName() << "to the server." << endl;
1363
				addGroup( group->displayName(), contactId);
1364
			}
1365
			else
1366
			{
1367
				// Add the group that the contact belong to add it when we will receive the contact GUID.
1368
				if( tmp_addNewContactToGroup.contains( contactId ) )
1369
					tmp_addNewContactToGroup[contactId].append(groupId);
1370
				else
1371
					tmp_addNewContactToGroup.insert(contactId, TQStringList(groupId) );
1372
			}
1373
		}
1374
		else
1375
		{
1376
			if( !group->displayName().isEmpty() && group->type() == Kopete::Group::Normal )
1377
			{
1378
				kdDebug(14140) << k_funcinfo << "Group not on MSN server, add it" << endl;
1379
				addGroup( group->displayName(), contactId );
1380
			}
1381
		}
1382
	}
1383
1384
	// After add the contact to the top-level, it will be moved to required groups later.
1385
	kdDebug( 14140 ) << k_funcinfo << "Add the contact on the server " << endl;
1386
	m_notifySocket->addContact( contactId, MSNProtocol::FL, contactId, TQString(), TQString() );
1387
}
1388
1389
MSNContact *MSNAccount::findContactByGuid(const TQString &contactGuid)
1390
{
1391
	kdDebug(14140) << k_funcinfo << "Looking for " << contactGuid << endl;
1392
	TQDictIterator<Kopete::Contact> it( contacts() );
1393
	for ( ; it.current(); ++it )
1394
	{
1395
		MSNContact *c = dynamic_cast<MSNContact *>( it.current() );
1396
1397
		if(c && c->guid() == contactGuid )
1398
		{
1399
			kdDebug(14140) << k_funcinfo << "OK found a contact. " << endl;
1400
			// Found the contact GUID
1401
			return c;
1402
		}
1403
	}
1404
	
1405
	return 0L;
1406
}
1407
1408
bool MSNAccount::isHotmail() const
1409
{
1410
	if ( !m_openInboxAction )
1411
		return false;
1412
	return m_openInboxAction->isEnabled();
1413
}
1414
1415
TQString MSNAccount::pictureUrl()
1416
{
1417
	return m_pictureFilename;
1418
}
1419
1420
void MSNAccount::setPictureUrl(const TQString &url)
1421
{
1422
	m_pictureFilename = url;	
1423
}
1424
1425
TQString MSNAccount::pictureObject()
1426
{
1427
	if(m_pictureObj.isNull())
1428
		resetPictureObject(true); //silent=true to keep infinite loop away
1429
	return m_pictureObj;
1430
}
1431
1432
void MSNAccount::resetPictureObject(bool silent, bool force)
1433
{
1434
	TQString old=m_pictureObj;
1435
1436
	if(!configGroup()->readBoolEntry("exportCustomPicture") && !force)
1437
	{
1438
		m_pictureObj="";
1439
		myself()->removeProperty( Kopete::Global::Properties::self()->photo() );
1440
	}
1441
	else
1442
	{
1443
		// Check if the picture is a 96x96 image, if not scale, crop and save.
1444
		TQImage picture(m_pictureFilename);
1445
		if(picture.isNull())
1446
		{	
1447
			m_pictureObj="";
1448
			myself()->removeProperty( Kopete::Global::Properties::self()->photo() );
1449
		}
1450
		else
1451
		{
1452
			if(picture.width() != 96 || picture.height() != 96)
1453
			{
1454
				// Save to a new location in msnpictures.
1455
				TQString newLocation( locateLocal( "appdata", "msnpictures/"+ KURL(m_pictureFilename).fileName().lower() ) );
1456
	
1457
				// Scale and crop the picture.
1458
				picture = MSNProtocol::protocol()->scalePicture(picture);
1459
	
1460
				// Use the cropped/scaled image now.
1461
				if(!picture.save(newLocation, "PNG"))
1462
				{
1463
					m_pictureObj="";
1464
					myself()->removeProperty( Kopete::Global::Properties::self()->photo() );
1465
				}
1466
				m_pictureFilename = newLocation;
1467
			}
1468
		}
1469
1470
		TQFile pictFile( m_pictureFilename );
1471
		if(!pictFile.open(IO_ReadOnly))
1472
		{
1473
			m_pictureObj="";
1474
			myself()->removeProperty( Kopete::Global::Properties::self()->photo() );
1475
		}
1476
		else
1477
		{
1478
			TQByteArray ar=pictFile.readAll();
1479
			TQString sha1d= TQString((KCodecs::base64Encode(SHA1::hash(ar))));
1480
1481
			TQString size=TQString::number( pictFile.size() );
1482
			TQString all= "Creator"+accountId()+"Size"+size+"Type3Locationkopete.tmpFriendlyAAA=SHA1D"+ sha1d;
1483
			m_pictureObj="<msnobj Creator=\"" + accountId() + "\" Size=\"" + size  + "\" Type=\"3\" Location=\"kopete.tmp\" Friendly=\"AAA=\" SHA1D=\""+sha1d+"\" SHA1C=\""+ TQString(KCodecs::base64Encode(SHA1::hashString(all.utf8())))  +"\"/>";
1484
			myself()->setProperty( Kopete::Global::Properties::self()->photo() , m_pictureFilename );
1485
		}
1486
	}
1487
1488
	if(old!=m_pictureObj && isConnected() && m_notifySocket && !silent)
1489
	{
1490
		//update the msn pict
1491
		m_notifySocket->setStatus( myself()->onlineStatus() );
1492
	}
1493
}
1494
1495
#include "msnaccount.moc"
1496
1497
// vim: set noet ts=4 sts=4 sw=4:
1498
1499
(-)tdenetwork.ori/kopete/protocols/msn/msnaccount.h (-271 lines)
Lines 1-271 Link Here
1
/*
2
    msnaccount.h - Manages a single MSN account
3
4
    Copyright (c) 2003-2005 by Olivier Goffart       <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Michaêl Larouche       <michael.larouche@kdemail.net>
6
7
    Kopete    (c) 2003-2005 by The Kopete developers <kopete-devel@kde.org>
8
9
    *************************************************************************
10
    *                                                                       *
11
    * This program is free software; you can redistribute it and/or modify  *
12
    * it under the terms of the GNU General Public License as published by  *
13
    * the Free Software Foundation; either version 2 of the License, or     *
14
    * (at your option) any later version.                                   *
15
    *                                                                       *
16
    *************************************************************************
17
*/
18
19
#ifndef MSNACCOUNT_H
20
#define MSNACCOUNT_H
21
22
#include <tqobject.h>
23
24
#include "kopetepasswordedaccount.h"
25
26
#include "msnprotocol.h"
27
28
class TDEAction;
29
class TDEActionMenu;
30
31
class MSNNotifySocket;
32
class MSNContact;
33
34
/**
35
 * MSNAccount encapsulates everything that is account-based, as opposed to
36
 * protocol based. This basically means sockets, current status, and account
37
 * info are stored in the account, whereas the protocol is only the
38
 * 'manager' class that creates and manages accounts.
39
 */
40
class MSNAccount : public Kopete::PasswordedAccount
41
{
42
	Q_OBJECT
43
  
44
45
public:
46
	MSNAccount( MSNProtocol *parent, const TQString &accountID, const char *name = 0L );
47
48
	/*
49
	 * return the menu for this account
50
	 */
51
	virtual TDEActionMenu* actionMenu();
52
53
	//------ internal functions
54
	/**
55
	 * change the publicName to this new name
56
	 */
57
	void setPublicName( const TQString &name );
58
	void setPersonalMessage(MSNProtocol::PersonalMessageType type, const TQString &personalMessage );
59
60
	/**
61
	 * Returns the address of the MSN server
62
	 */
63
	TQString serverName();
64
65
	/**
66
	 * Returns the address of the MSN server port
67
	 */
68
	uint serverPort();
69
70
	MSNNotifySocket *notifySocket();
71
72
	/**
73
	 * return true if we are able to send mail, or to open hotmail inbox
74
	 */
75
	bool isHotmail() const;
76
77
78
	/**
79
	 * Return the picture url.
80
	 */
81
	TQString pictureUrl();
82
83
	/**
84
	 * Set the picture url.
85
	 */
86
	void setPictureUrl(const TQString &url);
87
88
	/**
89
	 * return the <msnobj> tag of the display picture
90
	 */
91
	TQString pictureObject();
92
93
	/**
94
	 * reset the <msnobj>.  This method should be called if the displayimage has changed
95
	 * If we are actualy connected, it will imediatly update the <msgobj> on the server, exepted
96
	 * if @param silent is set to true
97
	 * @param force Force the application of MSN picture
98
	 */
99
	void resetPictureObject(bool silent=false, bool force=false);
100
101
	//BEGIN Http
102
103
	bool useHttpMethod() const;
104
105
	//END
106
107
	/**
108
	 * Return the client ID for the myself contact of this account.
109
	 * It is dynamic to see if we really have a webcam or not.
110
	 */
111
	TQString myselfClientId() const;
112
113
public slots:
114
	virtual void connectWithPassword( const TQString &password ) ;
115
	virtual void disconnect() ;
116
	virtual void setOnlineStatus( const Kopete::OnlineStatus &status , const TQString &reason = TQString());
117
118
	/**
119
	 * Ask to the account to create a new chat session
120
	 */
121
	void slotStartChatSession( const TQString& handle );
122
123
	/**
124
	 * Single slot to display error message.
125
	 */
126
	void slotErrorMessageReceived( int type, const TQString &msg );
127
128
protected:
129
	virtual bool createContact( const TQString &contactId, Kopete::MetaContact *parentContact );
130
131
132
private slots:
133
	// Actions related
134
	void slotStartChat();
135
	void slotOpenInbox();
136
	void slotChangePublicName();
137
138
//#if !defined NDEBUG //(Stupid moc which don't see when he don't need to slot this slot)
139
	/**
140
	 * Show simple debugging aid
141
	 */
142
	void slotDebugRawCommand();
143
//#endif
144
145
	// notifySocket related
146
	void slotStatusChanged( const Kopete::OnlineStatus &status );
147
	void slotNotifySocketClosed();
148
	void slotPersonalMessageChanged(const TQString& personalMessage);
149
	void slotContactRemoved(const TQString& handle, const TQString& list, const TQString& contactGuid, const TQString& groupGuid );
150
	void slotContactAdded(const TQString& handle, const TQString& list, const TQString& publicName, const TQString& contactGuid, const TQString &groupGuid );
151
	void slotContactListed( const TQString& handle, const TQString& publicName, const TQString &contactGuid, uint lists, const TQString& groups );
152
	void slotNewContactList();
153
	/**
154
	 * The group has successful renamed in the server
155
	 * groupName: is new new group name
156
	 */
157
	void slotGroupRenamed(const TQString &groupGuid, const TQString& groupName );
158
	/**
159
	 * A new group was created on the server (or received durring an LSG command)
160
	 */
161
	void slotGroupAdded( const TQString& groupName, const TQString &groupGuid );
162
	/**
163
	 * Group was removed from the server
164
	 */
165
	void slotGroupRemoved( const TQString &groupGuid );
166
	/**
167
	 * Incoming RING command: connect to the Switchboard server and send
168
	 * the startChat signal
169
	 */
170
	void slotCreateChat( const TQString& sessionID, const TQString& address, const TQString& auth,
171
		const TQString& handle, const TQString& publicName );
172
	/**
173
	 * Incoming XFR command: this is an result from
174
	 * slotStartChatSession(handle)
175
	 * connect to the switchboard server and sen startChat signal
176
	 */
177
	void slotCreateChat( const TQString& address, const TQString& auth);
178
179
180
	// ui related
181
	/**
182
	 * A kopetegroup is renamed, rename group on the server
183
	 */
184
	void slotKopeteGroupRenamed( Kopete::Group *g );
185
186
	/**
187
	 * A kopetegroup is removed, remove the group in the server
188
	 **/
189
	void slotKopeteGroupRemoved( Kopete::Group* );
190
191
	/**
192
	 * add contact ui
193
	 */
194
	void slotContactAddedNotifyDialogClosed( const TQString &handle);
195
196
	/**
197
	 * When the dispatch server sends us the notification server to use.
198
	 */
199
	void createNotificationServer( const TQString &host, uint port );
200
201
	/**
202
 	 * When a global identity key get changed.
203
	 */
204
	void slotGlobalIdentityChanged( const TQString &key, const TQVariant &value );
205
206
private:
207
	MSNNotifySocket *m_notifySocket;
208
	TDEAction *m_openInboxAction;
209
	TDEAction *m_startChatAction;
210
	TDEAction *m_changeDNAction;
211
212
	// status which will be using for connecting
213
	Kopete::OnlineStatus m_connectstatus;
214
215
	TQStringList m_msgHandle;
216
217
	bool m_newContactList;
218
219
220
	/**
221
	 * Add the contact on the server in the given groups.
222
	 * this is a helper function called bu createContact and slotStatusChanged
223
	 */
224
	void addContactServerside(const TQString &contactId, TQPtrList<Kopete::Group> groupList);
225
226
	
227
228
public: //FIXME: should be private
229
	TQMap<TQString, Kopete::Group*> m_groupList;
230
231
	void addGroup( const TQString &groupName, const TQString &contactToAdd = TQString() );
232
233
	/**
234
	 * Find and retrive a MSNContact by its contactGuid. (Helper function)
235
	 */
236
	MSNContact *findContactByGuid(const TQString &contactGuid);
237
private:
238
239
	// server data
240
	TQStringList m_allowList;
241
	TQStringList m_blockList;
242
	TQStringList m_reverseList;
243
244
	Kopete::MetaContact *m_addWizard_metaContact;
245
	TQMap< TQString, TQStringList > tmp_addToNewGroup;
246
	TQMap< TQString, TQStringList > tmp_addNewContactToGroup;
247
248
	TQString m_pictureObj; //a cache of the <msnobj>
249
	TQString m_pictureFilename; // the picture filename.
250
251
	//this is the translation between old to new groups id when syncing from server.
252
	TQMap<TQString, Kopete::Group*> m_oldGroupList;
253
254
	/**
255
	 * I need the password in createNotificationServer.
256
	 * but i can't ask it there with password() because a nested loop will provoque crash
257
	 * at this place.   so i'm forced to keep it here.
258
	 * I would like an API to request the password WITHOUT askling it.
259
	 */
260
	TQString m_password;
261
262
	/**
263
	 * Cliend ID is a bitfield that contains supported features for a MSN contact.
264
	 */
265
	uint m_clientId;
266
};
267
268
#endif
269
270
// vim: set noet ts=4 sts=4 sw=4:
271
(-)tdenetwork.ori/kopete/protocols/msn/msnaddcontactpage.cpp (-85 lines)
Lines 1-85 Link Here
1
/*
2
    Copyright (c) 2002-2005 by Olivier Goffart       <ogoffart@ kde.org>
3
    Kopete    (c) 2002-2005 by The Kopete developers <kopete-devel@kde.org>
4
5
    *************************************************************************
6
    *                                                                       *
7
    * This program is free software; you can redistribute it and/or modify  *
8
    * it under the terms of the GNU General Public License as published by  *
9
    * the Free Software Foundation; either version 2 of the License, or     *
10
    * (at your option) any later version.                                   *
11
    *                                                                       *
12
    *************************************************************************
13
*/
14
15
16
#include <tqlayout.h>
17
#include <tqlineedit.h>
18
19
#include <tdelocale.h>
20
#include <tdemessagebox.h>
21
22
#include "msnadd.h"
23
#include "msnaddcontactpage.h"
24
#include "msnprotocol.h"
25
#include "kopeteaccount.h"
26
#include "kopeteuiglobal.h"
27
28
MSNAddContactPage::MSNAddContactPage(bool connected, TQWidget *parent, const char *name )
29
				  : AddContactPage(parent,name)
30
{
31
	(new TQVBoxLayout(this))->setAutoAdd(true);
32
/*	if ( connected )
33
	{*/
34
			msndata = new msnAddUI(this);
35
			/*
36
			msndata->cmbGroup->insertStringList(owner->getGroups());
37
			msndata->cmbGroup->setCurrentItem(0);
38
			*/
39
			canadd = true;
40
41
/*	}
42
	else
43
	{
44
			noaddMsg1 = new TQLabel( i18n( "You need to be connected to be able to add contacts." ), this );
45
			noaddMsg2 = new TQLabel( i18n( "Please connect to the MSN network and try again." ), this );
46
			canadd = false;
47
}*/
48
49
}
50
MSNAddContactPage::~MSNAddContactPage()
51
{
52
}
53
54
bool MSNAddContactPage::apply( Kopete::Account* i, Kopete::MetaContact*m )
55
{
56
	if ( validateData() )
57
	{
58
		TQString userid = msndata->addID->text();
59
		return i->addContact( userid , m, Kopete::Account::ChangeKABC );
60
	}
61
	return false;
62
}
63
64
65
bool MSNAddContactPage::validateData()
66
{
67
	if(!canadd)
68
		return false;
69
70
	TQString userid = msndata->addID->text();
71
72
	if(MSNProtocol::validContactId(userid))
73
		return true;
74
75
	KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry,
76
			i18n( "<qt>You must enter a valid email address.</qt>" ), i18n( "MSN Plugin" )  );
77
78
	return false;
79
80
}
81
82
#include "msnaddcontactpage.moc"
83
84
// vim: set noet ts=4 sts=4 sw=4:
85
(-)tdenetwork.ori/kopete/protocols/msn/msnaddcontactpage.h (-34 lines)
Lines 1-34 Link Here
1
2
#ifndef MSNADDCONTACTPAGE_H
3
#define MSNADDCONTACTPAGE_H
4
5
#include <tqwidget.h>
6
#include <addcontactpage.h>
7
#include <tqlabel.h>
8
9
/**
10
  *@author duncan
11
  */
12
class msnAddUI;
13
class MSNProtocol;
14
15
class MSNAddContactPage : public AddContactPage
16
{
17
   Q_OBJECT
18
  
19
public:
20
	MSNAddContactPage(bool connected, TQWidget *parent=0, const char *name=0);
21
	~MSNAddContactPage();
22
	msnAddUI *msndata;
23
	TQLabel *noaddMsg1;
24
	TQLabel *noaddMsg2;
25
	bool canadd;
26
	virtual bool validateData();
27
	virtual bool apply( Kopete::Account*, Kopete::MetaContact* );
28
29
};
30
31
#endif
32
33
// vim: set noet ts=4 sts=4 sw=4:
34
(-)tdenetwork.ori/kopete/protocols/msn/msnchallengehandler.cpp (-151 lines)
Lines 1-151 Link Here
1
/*
2
    msnchallengehandler.h - Computes a msn challenge response hash key.
3
4
    Copyright (c) 2005 by Gregg Edghill       <gregg.edghill@gmail.com>
5
    Kopete    (c) 2003-2005 by The Kopete developers <kopete-devel@kde.org>
6
7
    Portions taken from
8
    	http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#include "msnchallengehandler.h"
21
22
#include <tqdatastream.h>
23
24
#include <kdebug.h>
25
#include <kmdcodec.h>
26
27
MSNChallengeHandler::MSNChallengeHandler(const TQString& productKey, const TQString& productId)
28
{
29
	m_productKey = productKey;
30
	m_productId  = productId;
31
}
32
33
34
MSNChallengeHandler::~MSNChallengeHandler()
35
{
36
	kdDebug(14140) << k_funcinfo << endl;
37
}
38
39
TQString MSNChallengeHandler::computeHash(const TQString& challengeString)
40
{
41
  	// Step One: THe MD5 Hash.
42
43
  	// Combine the received challenge string with the product key.
44
 	KMD5 md5((challengeString + m_productKey).utf8());
45
 	TQCString digest = md5.hexDigest();
46
47
 	kdDebug(14140) << k_funcinfo << "md5: " << digest << endl;
48
49
 	TQValueVector<TQ_INT32> md5Integers(4);
50
 	for(TQ_UINT32 i=0; i < md5Integers.count(); i++)
51
 	{
52
 		md5Integers[i] = hexSwap(digest.mid(i*8, 8)).toUInt(0, 16) & 0x7FFFFFFF;
53
 		kdDebug(14140) << k_funcinfo << ("0x" + hexSwap(digest.mid(i*8, 8))) << " " << md5Integers[i] << endl;
54
 	}
55
56
	// Step Two: Create the challenge string key
57
58
	TQString challengeKey = challengeString + m_productId;
59
	// Pad to multiple of 8.
60
	challengeKey = challengeKey.leftJustify(challengeKey.length() + (8 - challengeKey.length() % 8), '0');
61
62
	kdDebug(14140) << k_funcinfo << "challenge key: " << challengeKey << endl;
63
64
	TQValueVector<TQ_INT32> challengeIntegers(challengeKey.length() / 4);
65
	for(TQ_UINT32 i=0; i < challengeIntegers.count(); i++)
66
	{
67
		TQString sNum = challengeKey.mid(i*4, 4), sNumHex;
68
69
		// Go through the number string, determining the hex equivalent of each value
70
		// and add that to our new hex string for this number.
71
		for(uint j=0; j < sNum.length(); j++) {
72
			sNumHex += TQString::number((int)sNum[j].latin1(), 16);
73
		}
74
75
		// swap because of the byte ordering issue.
76
		sNumHex = hexSwap(sNumHex);
77
		// Assign the converted number.
78
		challengeIntegers[i] = sNumHex.toInt(0, 16);
79
		kdDebug(14140) << k_funcinfo << sNum << (": 0x"+sNumHex) << " " << challengeIntegers[i] << endl;
80
	}
81
82
	// Step Three: Create the 64-bit hash key.
83
84
	// Get the hash key using the specified arrays.
85
	TQ_INT64 key = createHashKey(md5Integers, challengeIntegers);
86
	kdDebug(14140) << k_funcinfo << "key: " << key << endl;
87
88
	// Step Four: Create the final hash key.
89
90
	TQString upper = TQString::number(TQString(digest.mid(0, 16)).toULongLong(0, 16)^key, 16);
91
	if(upper.length() % 16 != 0)
92
		upper = upper.rightJustify(upper.length() + (16 - upper.length() % 16), '0');
93
94
	TQString lower = TQString::number(TQString(digest.mid(16, 16)).toULongLong(0, 16)^key, 16);
95
	if(lower.length() % 16 != 0)
96
		lower = lower.rightJustify(lower.length() + (16 - lower.length() % 16), '0');
97
98
	return (upper + lower);
99
}
100
101
TQ_INT64 MSNChallengeHandler::createHashKey(const TQValueVector<TQ_INT32>& md5Integers,
102
	const TQValueVector<TQ_INT32>& challengeIntegers)
103
{
104
	kdDebug(14140) << k_funcinfo << "Creating 64-bit key." << endl;
105
106
	TQ_INT64 magicNumber = 0x0E79A9C1L, high = 0L, low = 0L;
107
		
108
	for(uint i=0; i < challengeIntegers.count(); i += 2)
109
	{
110
		TQ_INT64 temp = ((challengeIntegers[i] * magicNumber) % 0x7FFFFFFF) + high;
111
		temp = ((temp * md5Integers[0]) + md5Integers[1]) % 0x7FFFFFFF;
112
113
		high = (challengeIntegers[i + 1] + temp) % 0x7FFFFFFF;
114
		high = ((high * md5Integers[2]) + md5Integers[3]) % 0x7FFFFFFF;
115
116
		low += high + temp;
117
	}
118
119
	high = (high + md5Integers[1]) % 0x7FFFFFFF;
120
	low  = (low  + md5Integers[3]) % 0x7FFFFFFF;
121
122
	TQDataStream buffer(TQByteArray(8), IO_ReadWrite);
123
	buffer.setByteOrder(TQDataStream::LittleEndian);
124
	buffer << (TQ_INT32)high;
125
	buffer << (TQ_INT32)low;
126
127
	buffer.device()->reset();
128
	buffer.setByteOrder(TQDataStream::BigEndian);
129
	TQ_INT64 key;
130
	buffer >> key;
131
	
132
	return key;
133
}
134
135
TQString MSNChallengeHandler::hexSwap(const TQString& in)
136
{
137
	TQString sHex = in, swapped;
138
	while(sHex.length() > 0)
139
	{
140
		swapped = swapped + sHex.mid(sHex.length() - 2, 2);
141
		sHex = sHex.remove(sHex.length() - 2, 2);
142
	}
143
	return swapped;
144
}
145
146
TQString MSNChallengeHandler::productId()
147
{
148
	return m_productId;
149
}
150
151
#include "msnchallengehandler.moc"
(-)tdenetwork.ori/kopete/protocols/msn/msnchallengehandler.h (-65 lines)
Lines 1-65 Link Here
1
/*
2
    msnchallengehandler.h - Computes a msn challenge response hash key.
3
4
    Copyright (c) 2005 by Gregg Edghill       <gregg.edghill@gmail.com>
5
    Kopete    (c) 2003-2005 by The Kopete developers <kopete-devel@kde.org>
6
7
    Portions taken from
8
    	http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#ifndef MSNCHALLENGEHANDLER_H
21
#define MSNCHALLENGEHANDLER_H
22
23
#include <tqobject.h>
24
#include <tqvaluevector.h>
25
26
/**
27
 * Provides a simple way to compute a msn challenge response hash key.
28
 *
29
 * @author Gregg Edghill
30
 */
31
class MSNChallengeHandler : public TQObject
32
{
33
Q_OBJECT
34
  
35
public:
36
	MSNChallengeHandler(const TQString& productKey, const TQString& productId);
37
    ~MSNChallengeHandler();
38
39
	/**
40
	 * Computes the response hash string for the specified challenge string.
41
	 */
42
    TQString computeHash(const TQString& challengeString);
43
44
	/**
45
	 * Returns the product id used by the challenge handler.
46
	 */
47
    TQString productId();
48
    
49
private:
50
51
	/**
52
	 * Creates a 64-bit hash key.
53
	 */
54
	 TQ_INT64 createHashKey(const TQValueVector<TQ_INT32>& md5Integers, const TQValueVector<TQ_INT32>& challengeIntegers);
55
	 
56
	/**
57
	 * Swaps the bytes in a hex string.
58
	 */
59
	TQString hexSwap(const TQString& in);
60
	
61
	TQString m_productKey;
62
	TQString m_productId;
63
};
64
65
#endif
(-)tdenetwork.ori/kopete/protocols/msn/msnchatsession.cpp (-775 lines)
Lines 1-775 Link Here
1
/*
2
    msnchatsession.cpp - MSN Message Manager
3
4
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
18
#include "msnchatsession.h"
19
20
#include <tqlabel.h>
21
#include <tqimage.h>
22
#include <tqtooltip.h>
23
#include <tqfile.h>
24
#include <tqiconset.h>
25
26
27
#include <tdeconfig.h>
28
#include <kdebug.h>
29
#include <kinputdialog.h>
30
#include <tdelocale.h>
31
#include <tdemessagebox.h>
32
#include <tdepopupmenu.h>
33
#include <tdetempfile.h>
34
#include <tdemainwindow.h>
35
#include <tdetoolbar.h>
36
#include <krun.h>
37
38
#include "kopetecontactaction.h"
39
#include "kopetemetacontact.h"
40
#include "kopetecontactlist.h"
41
#include "kopetechatsessionmanager.h"
42
#include "kopeteuiglobal.h"
43
#include "kopeteglobal.h"
44
#include "kopeteview.h"
45
46
#include "msncontact.h"
47
#include "msnfiletransfersocket.h"
48
#include "msnaccount.h"
49
#include "msnswitchboardsocket.h"
50
51
#include "config.h"
52
53
#if !defined NDEBUG
54
#include "msndebugrawcmddlg.h"
55
#endif
56
57
MSNChatSession::MSNChatSession( Kopete::Protocol *protocol, const Kopete::Contact *user,
58
	Kopete::ContactPtrList others, const char *name )
59
: Kopete::ChatSession( user, others, protocol,  name )
60
{
61
	Kopete::ChatSessionManager::self()->registerChatSession( this );
62
	m_chatService = 0l;
63
	m_timeoutTimer =0L;
64
	m_newSession = true;
65
	m_connectionTry=0;
66
67
	setInstance(protocol->instance());
68
69
	connect( this, TQT_SIGNAL( messageSent( Kopete::Message&,
70
		Kopete::ChatSession* ) ),
71
		this, TQT_SLOT( slotMessageSent( Kopete::Message&,
72
		Kopete::ChatSession* ) ) );
73
74
	connect( this, TQT_SIGNAL( invitation(MSNInvitation*& ,  const TQString & , long unsigned int , MSNChatSession*  , MSNContact*  ) ) ,
75
		protocol,  TQT_SIGNAL( invitation(MSNInvitation*& ,  const TQString & , long unsigned int , MSNChatSession*  , MSNContact*  ) ) );
76
77
78
	m_actionInvite = new TDEActionMenu( i18n( "&Invite" ), "kontact_contacts", actionCollection(), "msnInvite" );
79
	connect ( m_actionInvite->popupMenu() , TQT_SIGNAL( aboutToShow() ) , this , TQT_SLOT(slotActionInviteAboutToShow() ) ) ;
80
81
	#if !defined NDEBUG
82
	new TDEAction( i18n( "Send Raw C&ommand..." ), 0, this, TQT_SLOT( slotDebugRawCommand() ), actionCollection(), "msnDebugRawCommand" ) ;
83
	#endif
84
85
86
	m_actionNudge=new TDEAction( i18n( "Send Nudge" ), "bell", 0, this, TQT_SLOT(slotSendNudge() ), actionCollection(), "msnSendNudge" ) ;
87
#if MSN_WEBCAM
88
	// Invite to receive webcam action
89
	m_actionWebcamReceive=new TDEAction( i18n( "View Contact's Webcam" ), "webcamreceive",  0, this, TQT_SLOT(slotWebcamReceive()), actionCollection(), "msnWebcamReceive" ) ;
90
	
91
	//Send webcam action
92
	m_actionWebcamSend=new TDEAction( i18n( "Send Webcam" ), "webcamsend",  0, this, TQT_SLOT(slotWebcamSend()), actionCollection(), "msnWebcamSend" ) ;
93
#endif
94
	
95
	new TDEAction( i18n( "Send File" ),"attach", 0, this, TQT_SLOT( slotSendFile() ), actionCollection(), "msnSendFile" );
96
97
	MSNContact *c = static_cast<MSNContact*>( others.first() );
98
	(new TDEAction( i18n( "Request Display Picture" ), "image", 0,  this, TQT_SLOT( slotRequestPicture() ), actionCollection(), "msnRequestDisplayPicture" ))->setEnabled(!c->object().isEmpty());
99
100
	if ( !c->object().isEmpty() )
101
	{
102
		
103
		connect( c, TQT_SIGNAL( displayPictureChanged() ), this, TQT_SLOT( slotDisplayPictureChanged() ) );
104
		m_image = new TQLabel( 0L, "kde toolbar widget" );
105
		new KWidgetAction( m_image, i18n( "MSN Display Picture" ), 0, this, TQT_SLOT( slotRequestPicture() ), actionCollection(), "msnDisplayPicture" );
106
		if(c->hasProperty(Kopete::Global::Properties::self()->photo().key())  )
107
		{
108
			//if the view doesn't exist yet, we will be unable to get the size of the toolbar
109
			// so when the view will exist, we will show the displaypicture.
110
			//How to know when a our view is created?  We can't.
111
			// but chances are the next created view will be for this KMM
112
			// And if it is not?  never mind. the icon will just be sized 22x22
113
			connect( Kopete::ChatSessionManager::self() , TQT_SIGNAL(viewActivated(KopeteView* )) , this, TQT_SLOT(slotDisplayPictureChanged()) );
114
			//it's viewActivated and not viewCreated because the view get his mainwindow only when it is shown.
115
		}
116
	}
117
	else
118
	{
119
		m_image = 0L;
120
	}
121
122
	setXMLFile("msnchatui.rc");
123
	
124
	setMayInvite( true );
125
}
126
127
MSNChatSession::~MSNChatSession()
128
{
129
	delete m_image;
130
	//force to disconnect the switchboard
131
	//not needed since the m_chatService has us as parent
132
	//	if(m_chatService)
133
	//		delete m_chatService;
134
135
	TQMap<unsigned long int, MSNInvitation*>::Iterator it;
136
	for( it = m_invitations.begin(); it != m_invitations.end() ; it = m_invitations.begin())
137
	{
138
		delete *it;
139
		m_invitations.remove( it );
140
	}
141
}
142
143
void MSNChatSession::createChat( const TQString &handle,
144
	const TQString &address, const TQString &auth, const TQString &ID )
145
{
146
	/* disabled because i don't want to reopen a chatwindow if we just closed it
147
	 * and the contact take much time to type his message
148
	 m_newSession= !(ID.isEmpty());
149
	*/
150
	
151
	if( m_chatService )
152
	{
153
		kdDebug(14140) << k_funcinfo << "Service already exists, disconnect them." << endl;
154
		delete m_chatService;
155
	}
156
157
//	uncomment this line if you don't want to the peer know when you close the window
158
//	setCanBeDeleted( false );
159
160
	m_chatService = new MSNSwitchBoardSocket( static_cast<MSNAccount*>( myself()->account() ) , this);
161
	m_chatService->setUseHttpMethod( static_cast<MSNAccount*>( myself()->account() )->useHttpMethod() );
162
	m_chatService->setHandle( myself()->account()->accountId() );
163
	m_chatService->setMsgHandle( handle );
164
	m_chatService->connectToSwitchBoard( ID, address, auth );
165
166
	connect( m_chatService, TQT_SIGNAL( userJoined(const TQString&,const TQString&,bool)),
167
		this, TQT_SLOT( slotUserJoined(const TQString&,const TQString&,bool) ) );
168
	connect( m_chatService, TQT_SIGNAL( userLeft(const TQString&,const TQString&)),
169
		this, TQT_SLOT( slotUserLeft(const TQString&,const TQString&) ) );
170
	connect( m_chatService, TQT_SIGNAL( msgReceived( Kopete::Message & ) ),
171
		this, TQT_SLOT( slotMessageReceived( Kopete::Message & ) ) );
172
	connect( m_chatService, TQT_SIGNAL( switchBoardClosed() ),
173
		this, TQT_SLOT( slotSwitchBoardClosed() ) );
174
	connect( m_chatService, TQT_SIGNAL( receivedTypingMsg( const TQString &, bool ) ),
175
		this, TQT_SLOT( receivedTypingMsg( const TQString &, bool ) ) );
176
	TDEConfig *config = TDEGlobal::config();
177
	config->setGroup( "MSN" );
178
	if(config->readBoolEntry( "SendTypingNotification" , true) )
179
	{
180
		connect( this, TQT_SIGNAL( myselfTyping( bool ) ),
181
			m_chatService, TQT_SLOT( sendTypingMsg( bool ) ) );
182
	}
183
	connect( m_chatService, TQT_SIGNAL( msgAcknowledgement(unsigned int, bool) ),
184
		this, TQT_SLOT( slotAcknowledgement(unsigned int, bool) ) );
185
	connect( m_chatService, TQT_SIGNAL( invitation( const TQString&, const TQString& ) ),
186
		this, TQT_SLOT( slotInvitation( const TQString&, const TQString& ) ) );
187
	connect( m_chatService, TQT_SIGNAL( nudgeReceived(const TQString&) ),
188
		this, TQT_SLOT( slotNudgeReceived(const TQString&) ) );
189
	connect( m_chatService, TQT_SIGNAL( errorMessage(int, const TQString& ) ), static_cast<MSNAccount *>(myself()->account()), TQT_SLOT( slotErrorMessageReceived(int, const TQString& ) ) );
190
	
191
	if(!m_timeoutTimer)
192
	{
193
		m_timeoutTimer=new TQTimer(this);
194
		connect( m_timeoutTimer , TQT_SIGNAL(timeout()), this , TQT_SLOT(slotConnectionTimeout() ) );
195
	}
196
	m_timeoutTimer->start(20000,true);
197
}
198
199
void MSNChatSession::slotUserJoined( const TQString &handle, const TQString &publicName, bool IRO )
200
{
201
	delete m_timeoutTimer;
202
	m_timeoutTimer=0L;
203
	
204
	if( !account()->contacts()[ handle ] )
205
		account()->addContact( handle, TQString(), 0L, Kopete::Account::Temporary);
206
207
	MSNContact *c = static_cast<MSNContact*>( account()->contacts()[ handle ] );
208
209
	c->setProperty( Kopete::Global::Properties::self()->nickName() , publicName);
210
	
211
	if(c->clientFlags() & MSNProtocol::MSNC4 )
212
	{
213
		m_actionNudge->setEnabled(true);
214
	}
215
#if MSN_WEBCAM
216
	if(c->clientFlags() & MSNProtocol::SupportWebcam )
217
	{
218
		m_actionWebcamReceive->setEnabled(true);
219
	}
220
#endif
221
222
	addContact(c , IRO); // don't show notificaions when we join wesalef
223
	if(!m_messagesQueue.empty() || !m_invitations.isEmpty())
224
		sendMessageQueue();
225
226
	TDEConfig *config = TDEGlobal::config();
227
	config->setGroup( "MSN" );
228
	if ( members().count()==1 && config->readNumEntry( "DownloadPicture", 1 ) >= 1 && !c->object().isEmpty() && !c->hasProperty(Kopete::Global::Properties::self()->photo().key()))
229
		slotRequestPicture();
230
}
231
232
void MSNChatSession::slotUserLeft( const TQString &handle, const TQString& reason )
233
{
234
	MSNContact *c = static_cast<MSNContact*>( myself()->account()->contacts()[ handle ] );
235
	if(c)
236
		removeContact(c, reason );
237
}
238
239
240
241
void MSNChatSession::slotSwitchBoardClosed()
242
{
243
	//kdDebug(14140) << "MSNChatSession::slotSwitchBoardClosed"  << endl;
244
	m_chatService->deleteLater();
245
	m_chatService=0l;
246
247
	cleanMessageQueue( i18n("Connection closed") );
248
249
	if(m_invitations.isEmpty())
250
		setCanBeDeleted( true );
251
}
252
253
void MSNChatSession::slotMessageSent(Kopete::Message &message,Kopete::ChatSession *)
254
{
255
	m_newSession=false;
256
 	if(m_chatService)
257
	{
258
		int id = m_chatService->sendMsg(message);
259
		if(id == -1)
260
		{
261
			m_messagesQueue.append(message);
262
			kdDebug(14140) << k_funcinfo << "Message added to the queue" <<endl;
263
		}
264
		else if( id== -2 ) //the message has not been sent
265
		{
266
			//FIXME:  tell the what window the message has been processed. but we havent't sent it 
267
			messageSucceeded();  //that should stop the blonking icon.
268
		}
269
		else if( id == -3) //the message has been sent as an immge
270
		{
271
			appendMessage(message); 
272
			messageSucceeded();
273
		}
274
		else
275
		{
276
			m_messagesSent.insert( id, message );
277
			message.setBg(TQColor()); // clear the bgColor
278
			message.setBody(message.plainBody() , Kopete::Message::PlainText ); //clear every custom tag which are not sent
279
			appendMessage(message); // send the own msg to chat window
280
		}
281
	}
282
	else // There's no switchboard available, so we must create a new one!
283
	{
284
		startChatSession();
285
		m_messagesQueue.append(message);
286
//		sendMessageQueue();
287
		//m_msgQueued=new Kopete::Message(message);
288
	}
289
}
290
291
void MSNChatSession::slotMessageReceived( Kopete::Message &msg )
292
{
293
	m_newSession=false;
294
	if( msg.plainBody().startsWith( "AutoMessage: " ) )
295
	{
296
		//FIXME: HardCodded color are not so good
297
		msg.setFg( TQColor( "SlateGray3" ) );
298
		TQFont f;
299
		f.setItalic( true );
300
		msg.setFont( f );
301
	}
302
	appendMessage( msg );
303
}
304
305
void MSNChatSession::slotActionInviteAboutToShow()
306
{
307
	// We can't simply insert  TDEAction in this menu bebause we don't know when to delete them.
308
	//  items inserted with insert items are automatically deleted when we call clear
309
310
	m_inviteactions.setAutoDelete(true);
311
	m_inviteactions.clear();
312
313
	m_actionInvite->popupMenu()->clear();
314
315
	
316
	TQDictIterator<Kopete::Contact> it( account()->contacts() );
317
	for( ; it.current(); ++it )
318
	{
319
		if( !members().contains( it.current() ) && it.current()->isOnline() && it.current() != myself() )
320
		{
321
			TDEAction *a=new KopeteContactAction( it.current(), this,
322
				TQT_SLOT( slotInviteContact( Kopete::Contact * ) ), m_actionInvite );
323
			m_actionInvite->insert( a );
324
			m_inviteactions.append( a ) ;
325
		}
326
	}
327
	TDEAction *b=new TDEAction( i18n ("Other..."), 0, this, TQT_SLOT( slotInviteOtherContact() ), m_actionInvite, "actionOther" );
328
	m_actionInvite->insert( b );
329
	m_inviteactions.append( b ) ;
330
}
331
332
void MSNChatSession::slotCloseSession()
333
{
334
	kdDebug(14140) << k_funcinfo  << m_chatService <<endl;
335
	if(m_chatService)
336
		m_chatService->slotCloseSession();
337
}
338
339
void MSNChatSession::slotInviteContact( Kopete::Contact *contact )
340
{
341
	if(contact)
342
		inviteContact( contact->contactId() );
343
}
344
345
void MSNChatSession::inviteContact(const TQString &contactId)
346
{
347
	if( m_chatService )
348
		m_chatService->slotInviteContact( contactId );
349
	else
350
		startChatSession();
351
}
352
353
void MSNChatSession::slotInviteOtherContact()
354
{
355
	bool ok;
356
	TQString handle = KInputDialog::getText(i18n( "MSN Plugin" ),
357
			i18n( "Please enter the email address of the person you want to invite:" ),
358
			TQString(), &ok );
359
	if( !ok )
360
		return;
361
362
	if( handle.contains('@') != 1 || handle.contains('.') <1)
363
	{
364
			KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry,
365
					i18n("<qt>You must enter a valid email address.</qt>"), i18n("MSN Plugin"));
366
			return;
367
	}
368
369
	inviteContact(handle);
370
}
371
372
373
void MSNChatSession::sendMessageQueue()
374
{
375
	if(!m_chatService)
376
	{
377
		kdDebug(14140) <<k_funcinfo << "Service doesn't exist" <<endl;
378
		return;
379
	}
380
//	kdDebug(14140) << "MSNChatSession::sendMessageQueue: " << m_messagesQueue.count() <<endl;
381
	for ( TQValueList<Kopete::Message>::iterator it = m_messagesQueue.begin(); it!=m_messagesQueue.end(); it = m_messagesQueue.begin() )
382
	{
383
		//m_chatService->sendMsg( *it)  ;
384
		slotMessageSent(*it , this);
385
		m_messagesQueue.remove(it);
386
	}
387
388
389
	TQMap<unsigned long int, MSNInvitation*>::Iterator it;
390
	for( it = m_invitations.begin(); it != m_invitations.end() ; ++it)
391
	{
392
		if(! (*it)->incoming() && (*it)->state()<MSNInvitation::Invited)
393
		{
394
			m_chatService->sendCommand( "MSG" , "N", true, (*it)->invitationHead().utf8() );
395
			(*it)->setState(MSNInvitation::Invited);
396
		}
397
	}
398
}
399
400
void MSNChatSession::slotAcknowledgement(unsigned int id, bool ack)
401
{
402
	if ( !m_messagesSent.contains( id ) )
403
	{
404
		// This is maybe a ACK/NAK for a non-messaging message
405
		return;
406
	}
407
408
	if ( !ack )
409
	{
410
		Kopete::Message m = m_messagesSent[ id ];
411
		TQString body = i18n( "The following message has not been sent correctly:\n%1" ).arg( m.plainBody() );
412
		Kopete::Message msg = Kopete::Message( m.to().first(), members(), body, Kopete::Message::Internal, Kopete::Message::PlainText );
413
		appendMessage( msg );
414
		//stop the stupid animation
415
		messageSucceeded();  
416
	}
417
	else
418
	{
419
		messageSucceeded();
420
	}
421
422
	m_messagesSent.remove( id );
423
}
424
425
void MSNChatSession::slotInvitation(const TQString &handle, const TQString &msg)
426
{
427
	//FIXME! a contact from another account can send a file
428
	MSNContact *c = static_cast<MSNContact*>( myself()->account()->contacts()[ handle ] );
429
	if(!c)
430
		return;
431
432
	TQRegExp rx("Invitation-Cookie: ([0-9]*)");
433
	rx.search(msg);
434
	long unsigned int cookie=rx.cap(1).toUInt();
435
436
	if(m_invitations.contains(cookie))
437
	{
438
		MSNInvitation *msnI=m_invitations[cookie];
439
		msnI->parseInvitation(msg);
440
	}
441
	else if( msg.contains("Invitation-Command: INVITE") )
442
	{
443
		if( msg.contains(MSNFileTransferSocket::applicationID()) )
444
		{
445
			MSNFileTransferSocket *MFTS=new MSNFileTransferSocket(myself()->account()->accountId(),c,true,this);
446
			connect(MFTS, TQT_SIGNAL( done(MSNInvitation*) ) , this , TQT_SLOT( invitationDone(MSNInvitation*) ));
447
			m_invitations.insert( cookie  , MFTS);
448
			MFTS->parseInvitation(msg);
449
			setCanBeDeleted(false);
450
		}
451
		else
452
		{
453
			MSNInvitation *i=0l;
454
			emit invitation( i , msg, cookie, this, c );
455
			if(i)
456
			{
457
				m_invitations.insert( cookie  , i );
458
				//don't delete this if all invitation are not done
459
				setCanBeDeleted(false);
460
			}
461
			else
462
			{
463
				rx=TQRegExp("Application-Name: ([^\\r\\n]*)");
464
				rx.search(msg);
465
				TQString inviteName = rx.cap( 1 );
466
467
				TQString body = i18n(
468
					"%1 has sent an unimplemented invitation, the invitation was rejected.\n"
469
					"The invitation was: %2" )
470
						.arg( c->property( Kopete::Global::Properties::self()->nickName()).value().toString(), inviteName );
471
				Kopete::Message tmpMsg = Kopete::Message( c , members() , body , Kopete::Message::Internal, Kopete::Message::PlainText);
472
				appendMessage(tmpMsg);
473
474
				m_chatService->sendCommand( "MSG" , "N", true, MSNInvitation::unimplemented(cookie) );
475
			}
476
		}
477
	}
478
}
479
480
void MSNChatSession::invitationDone(MSNInvitation* MFTS)
481
{
482
	kdDebug(14140) << k_funcinfo <<endl;
483
	m_invitations.remove(MFTS->cookie());
484
//	MFTS->deleteLater();
485
	delete MFTS;
486
	if(!m_chatService && m_invitations.isEmpty())
487
		setCanBeDeleted(true);
488
}
489
490
void MSNChatSession::sendFile(const TQString &fileLocation, const TQString &/*fileName*/,
491
	long unsigned int fileSize)
492
{
493
	// TODO create a switchboard to send the file is one is not available.
494
	if(m_chatService && members().getFirst())
495
	{
496
		m_chatService->PeerDispatcher()->sendFile(fileLocation, (TQ_INT64)fileSize, members().getFirst()->contactId());
497
	}
498
}
499
500
void MSNChatSession::initInvitation(MSNInvitation* invitation)
501
{
502
	connect(invitation->object(), TQT_SIGNAL( done(MSNInvitation*) ) , this , TQT_SLOT( invitationDone(MSNInvitation*) ));
503
	m_invitations.insert( invitation->cookie() , invitation);
504
505
	if(m_chatService)
506
	{
507
		m_chatService->sendCommand( "MSG" , "N", true, invitation->invitationHead().utf8() );
508
		invitation->setState(MSNInvitation::Invited);
509
	}
510
	else
511
	{
512
		startChatSession();
513
	}
514
}
515
516
void MSNChatSession::slotRequestPicture()
517
{
518
	TQPtrList<Kopete::Contact> mb=members();
519
	MSNContact *c = static_cast<MSNContact*>( mb.first() );
520
	if(!c)
521
	 return;
522
	
523
	if( !c->hasProperty(Kopete::Global::Properties::self()->photo().key()))
524
	{
525
		if(m_chatService)
526
		{
527
			if( !c->object().isEmpty() )
528
				m_chatService->requestDisplayPicture();
529
		}
530
		else if(myself()->onlineStatus().isDefinitelyOnline()  && myself()->onlineStatus().status() != Kopete::OnlineStatus::Invisible )
531
			startChatSession();
532
	}
533
	else
534
	{ //we already have the picture, just show it.
535
		KRun::runURL( KURL::fromPathOrURL( c->property(Kopete::Global::Properties::self()->photo()).value().toString() ), "image/png" );
536
	}
537
538
}
539
540
void MSNChatSession::slotDisplayPictureChanged()
541
{
542
	TQPtrList<Kopete::Contact> mb=members();
543
	MSNContact *c = static_cast<MSNContact *>( mb.first() );
544
	if ( c && m_image )
545
	{
546
		if(c->hasProperty(Kopete::Global::Properties::self()->photo().key()))
547
		{
548
			int sz=22;
549
			// get the size of the toolbar were the aciton is plugged.
550
			//  if you know a better way to get the toolbar, let me know
551
			TDEMainWindow *w= view(false) ? dynamic_cast<TDEMainWindow*>( view(false)->mainWidget()->topLevelWidget() ) : 0L;
552
			if(w)
553
			{
554
				//We connected that in the constructor.  we don't need to keep this slot active.
555
				disconnect( Kopete::ChatSessionManager::self() , TQT_SIGNAL(viewActivated(KopeteView* )) , this, TQT_SLOT(slotDisplayPictureChanged()) );
556
			
557
				TQPtrListIterator<TDEToolBar>  it=w->toolBarIterator() ;
558
				TDEAction *imgAction=actionCollection()->action("msnDisplayPicture");
559
				if(imgAction)  while(it)
560
				{
561
					TDEToolBar *tb=*it;
562
					if(imgAction->isPlugged(tb))
563
					{
564
						sz=tb->iconSize();
565
						//ipdate if the size of the toolbar change.
566
						disconnect(tb, TQT_SIGNAL(modechange()), this, TQT_SLOT(slotDisplayPictureChanged()));
567
						connect(tb, TQT_SIGNAL(modechange()), this, TQT_SLOT(slotDisplayPictureChanged()));
568
						break;
569
					}
570
					++it;
571
				}
572
			}
573
			TQString imgURL=c->property(Kopete::Global::Properties::self()->photo()).value().toString();
574
			TQImage scaledImg = TQPixmap( imgURL ).convertToImage().smoothScale( sz, sz );
575
			if(!scaledImg.isNull())
576
				m_image->setPixmap( scaledImg );
577
			else
578
			{ //the image has maybe not been transfered correctly..  force to download again
579
				c->removeProperty(Kopete::Global::Properties::self()->photo());
580
				//slotDisplayPictureChanged(); //don't do that or we might end in a infinite loop
581
			}
582
			TQToolTip::add( m_image, "<qt><img src=\"" + imgURL + "\"></qt>" );
583
			
584
		}
585
		else 
586
		{
587
			TDEConfig *config = TDEGlobal::config();
588
			config->setGroup( "MSN" );
589
			if ( config->readNumEntry( "DownloadPicture", 1 ) >= 1 && !c->object().isEmpty() )
590
				slotRequestPicture();
591
		}
592
	}
593
}
594
595
void MSNChatSession::slotDebugRawCommand()
596
{
597
#if !defined NDEBUG
598
	if ( !m_chatService )
599
		return;
600
601
	MSNDebugRawCmdDlg *dlg = new MSNDebugRawCmdDlg( 0L );
602
	int result = dlg->exec();
603
	if( result == TQDialog::Accepted && m_chatService )
604
	{
605
		m_chatService->sendCommand( dlg->command(), dlg->params(),
606
					dlg->addId(), dlg->msg().replace("\n","\r\n").utf8() );
607
	}
608
	delete dlg;
609
#endif
610
}
611
612
613
void MSNChatSession::receivedTypingMsg( const TQString &contactId, bool b )
614
{
615
	MSNContact *c = dynamic_cast<MSNContact *>( account()->contacts()[ contactId ] );
616
	if(c && m_newSession &&  !view(false))
617
	{
618
		//this was originaly in MSNAccount::slotCreateChat
619
		TDEGlobal::config()->setGroup( "MSN" );
620
		bool notifyNewChat = TDEGlobal::config()->readBoolEntry( "NotifyNewChat", false );
621
		if (  notifyNewChat  )
622
		{
623
			// this internal message should open the window if they not exist
624
			TQString body = i18n( "%1 has started a chat with you" ).arg( c->metaContact()->displayName() );
625
			Kopete::Message tmpMsg = Kopete::Message( c, members(), body, Kopete::Message::Internal, Kopete::Message::PlainText );
626
			appendMessage( tmpMsg );
627
		}
628
	}
629
	m_newSession=false;
630
	if(c)
631
		Kopete::ChatSession::receivedTypingMsg(c,b);
632
}
633
634
void MSNChatSession::slotSendNudge()
635
{
636
	if(m_chatService)
637
	{
638
		m_chatService->sendNudge();
639
		Kopete::Message msg = Kopete::Message( myself(), members() , i18n ( "has sent a nudge" ),  Kopete::Message::Outbound, 
640
											   Kopete::Message::PlainText, TQString(), Kopete::Message::TypeAction );
641
		appendMessage( msg );
642
643
	}
644
}
645
646
647
void MSNChatSession::slotNudgeReceived(const TQString& handle)
648
{
649
	Kopete::Contact *c = account()->contacts()[ handle ] ;
650
	if(!c)
651
		c=members().getFirst();
652
	Kopete::Message msg = Kopete::Message(c, myself(), i18n ( "has sent you a nudge" ), Kopete::Message::Inbound, 
653
										  Kopete::Message::PlainText, TQString(), Kopete::Message::TypeAction );
654
	appendMessage( msg );
655
	// Emit the nudge/buzz notification (configured by user).
656
	emitNudgeNotification();
657
}
658
659
660
void MSNChatSession::slotWebcamReceive()
661
{
662
#if MSN_WEBCAM
663
	if(m_chatService && members().getFirst())
664
	{
665
		m_chatService->PeerDispatcher()->startWebcam(myself()->contactId() , members().getFirst()->contactId() , true);
666
	}
667
#endif
668
}
669
670
void MSNChatSession::slotWebcamSend()
671
{
672
#if MSN_WEBCAM
673
	kdDebug(14140) << k_funcinfo << endl;
674
	if(m_chatService && members().getFirst())
675
	{
676
		m_chatService->PeerDispatcher()->startWebcam(myself()->contactId() , members().getFirst()->contactId() , false);
677
	}
678
#endif
679
}
680
681
682
void MSNChatSession::slotSendFile()
683
      {
684
              TQPtrList<Kopete::Contact>contacts = members();
685
              static_cast<MSNContact *>(contacts.first())->sendFile();
686
      }
687
688
void MSNChatSession::startChatSession()
689
{
690
	TQPtrList<Kopete::Contact> mb=members();
691
	static_cast<MSNAccount*>( account() )->slotStartChatSession( mb.first()->contactId() );
692
	
693
	if(!m_timeoutTimer)
694
	{
695
		m_timeoutTimer=new TQTimer(this);
696
		connect( m_timeoutTimer , TQT_SIGNAL(timeout()), this , TQT_SLOT(slotConnectionTimeout() ) );
697
	}
698
	m_timeoutTimer->start(20000, true);
699
}
700
701
702
void MSNChatSession::cleanMessageQueue( const TQString & reason )
703
{
704
	delete m_timeoutTimer;
705
	m_timeoutTimer=0L;
706
707
	uint nb=m_messagesQueue.count()+m_messagesSent.count();
708
	if(nb==0)
709
		return;
710
	else if(nb==1)
711
	{
712
		Kopete::Message m;
713
		if(m_messagesQueue.count() == 1)
714
			m=m_messagesQueue.first();
715
		else
716
			m=m_messagesSent.begin().data();
717
		
718
		TQString body=i18n("The following message has not been sent correctly  (%1): \n%2").arg(reason, m.plainBody());
719
		Kopete::Message msg = Kopete::Message(m.to().first() , members() , body , Kopete::Message::Internal, Kopete::Message::PlainText);
720
		appendMessage(msg);
721
	}
722
	else
723
	{
724
		Kopete::Message m;
725
		TQString body=i18n("These messages have not been sent correctly (%1): <br /><ul>").arg(reason);
726
		for ( TQMap<unsigned int , Kopete::Message>::iterator it = m_messagesSent.begin(); it!=m_messagesSent.end(); it = m_messagesSent.begin() )
727
		{
728
			m=it.data();
729
			body+= "<li>"+m.escapedBody()+"</li>";
730
			m_messagesSent.remove(it);
731
		}
732
		for ( TQValueList<Kopete::Message>::iterator it = m_messagesQueue.begin(); it!=m_messagesQueue.end(); it = m_messagesQueue.begin() )
733
		{
734
			m=(*it);
735
			body+= "<li>"+m.escapedBody()+"</li>";
736
			m_messagesQueue.remove(it);
737
		}
738
		body+="</ul>";
739
		Kopete::Message msg = Kopete::Message(m.to().first() , members() , body , Kopete::Message::Internal, Kopete::Message::RichText);
740
		appendMessage(msg);
741
742
	}
743
	m_messagesQueue.clear();
744
	m_messagesSent.clear();
745
	messageSucceeded(); //stop stupid animation
746
}
747
748
void MSNChatSession::slotConnectionTimeout()
749
{
750
	m_connectionTry++;
751
	if(m_chatService)
752
	{
753
		disconnect(m_chatService , 0 , this , 0 );
754
		m_chatService->deleteLater();
755
		m_chatService=0L;
756
	}
757
	
758
	if( m_connectionTry > 3 )
759
	{
760
		cleanMessageQueue( i18n("Impossible to establish the connection") );
761
		delete m_timeoutTimer;
762
		m_timeoutTimer=0L;
763
		return;
764
	}
765
	startChatSession();
766
767
}
768
769
770
771
772
#include "msnchatsession.moc"
773
774
// vim: set noet ts=4 sts=4 sw=4:
775
(-)tdenetwork.ori/kopete/protocols/msn/msnchatsession.h (-141 lines)
Lines 1-141 Link Here
1
/*
2
    msnchatsession.h - MSN Message Manager
3
4
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart @ kde.org>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
18
#ifndef MSNMESSAGEMANAGER_H
19
#define MSNMESSAGEMANAGER_H
20
21
#include "kopetechatsession.h"
22
23
class MSNSwitchBoardSocket;
24
class TDEActionCollection;
25
class MSNInvitation;
26
class MSNContact;
27
class TDEActionMenu;
28
class TQLabel;
29
30
31
/**
32
 * @author Olivier Goffart
33
 */
34
class KOPETE_EXPORT MSNChatSession : public Kopete::ChatSession
35
{
36
	Q_OBJECT
37
  
38
39
public:
40
	MSNChatSession( Kopete::Protocol *protocol, const Kopete::Contact *user, Kopete::ContactPtrList others, const char *name = 0 );
41
	~MSNChatSession();
42
43
	void createChat( const TQString &handle, const TQString &address, const TQString &auth, const TQString &ID = TQString() );
44
45
	MSNSwitchBoardSocket *service() { return m_chatService; };
46
47
	void sendFile( const TQString &fileLocation, const TQString &fileName,
48
		long unsigned int fileSize );
49
50
	/**
51
	 * append an invitation in the invitation map, and send the first invitation message
52
	 */
53
	void initInvitation(MSNInvitation* invitation);
54
	
55
	virtual void inviteContact(const TQString& );
56
57
public slots:
58
	void slotCloseSession();
59
	void slotInviteOtherContact();
60
61
	void invitationDone( MSNInvitation*  );
62
63
	void slotRequestPicture();
64
65
	/**
66
	 * this is a reimplementation of ChatSesstion slot.
67
	 * the original slot is not virtual, but that's not a problem because it's a slot.
68
	 */
69
	virtual void receivedTypingMsg( const TQString &, bool );
70
	
71
	void slotConnectionTimeout();
72
73
private slots:
74
	void slotMessageSent( Kopete::Message &message, Kopete::ChatSession *kmm );
75
	void slotMessageReceived( Kopete::Message &message );
76
77
	void slotUserJoined( const TQString &handle, const TQString &publicName, bool IRO );
78
	void slotUserLeft( const TQString &handle, const TQString &reason );
79
	void slotSwitchBoardClosed();
80
	void slotInviteContact( Kopete::Contact *contact );
81
	void slotAcknowledgement( unsigned int id, bool ack );
82
	void slotInvitation( const TQString &handle, const TQString &msg );
83
84
	void slotActionInviteAboutToShow();
85
86
	void slotDisplayPictureChanged();
87
88
	/**
89
	 * (debug)
90
	 */
91
	void slotDebugRawCommand();
92
93
	void slotSendNudge();
94
	void slotWebcamReceive();
95
	void slotWebcamSend();
96
	void slotSendFile();
97
98
	void slotNudgeReceived(const TQString& handle);
99
100
private:
101
102
	MSNSwitchBoardSocket *m_chatService;
103
	TQString otherString;
104
	TDEActionMenu *m_actionInvite;
105
	TQPtrList<TDEAction> m_inviteactions;
106
	TDEAction *m_actionNudge;
107
	TDEAction *m_actionWebcamReceive;
108
	TDEAction *m_actionWebcamSend;
109
110
	//Messages sent before the ending of the connection are queued
111
	TQValueList<Kopete::Message> m_messagesQueue;
112
	void sendMessageQueue();
113
	void cleanMessageQueue( const TQString &reason);
114
	void startChatSession();
115
116
	TQMap<unsigned int, Kopete::Message> m_messagesSent;
117
118
	TQMap<long unsigned int, MSNInvitation*> m_invitations;
119
120
121
	/**
122
	 * weither or not the "has opened a new chat" message need to be sent if the user is typing
123
	 */
124
	bool m_newSession;
125
126
	TQLabel *m_image;
127
	TQTimer *m_timeoutTimer;
128
	uint m_connectionTry;
129
130
131
signals:
132
	/*
133
	 * This signal is relayed to the protocol and after, to plugins
134
	 */
135
	void invitation(MSNInvitation*& invitation,  const TQString &bodyMSG , long unsigned int cookie , MSNChatSession* msnMM , MSNContact* c );
136
};
137
138
#endif
139
140
// vim: set noet ts=4 sts=4 tw=4:
141
(-)tdenetwork.ori/kopete/protocols/msn/msnchatui.rc (-27 lines)
Lines 1-27 Link Here
1
<!DOCTYPE kpartgui>
2
<kpartgui version="12" name="kopete_msn_chat">
3
	<MenuBar>
4
		<Menu noMerge="1" name="file">
5
			<text>&amp;Chat</text>
6
			<Action name="msnWebcamReceive" />
7
			<Action name="msnWebcamSend" />
8
			<Action name="msnSendFile" />		
9
			<Action name="msnSendNudge" />
10
			<Action name="msnRequestDisplayPicture" />
11
			<Action name="msnInvite" />
12
<!--			<Menu name="debug">
13
				<text>&amp;Debug</text>
14
				<Action name="msnDebugRawCommand" />
15
			</Menu> -->
16
		</Menu>
17
	</MenuBar>
18
19
20
	<ToolBar name="statusToolBar">
21
		<Action name="msnDisplayPicture" />
22
		<Action name="msnWebcamReceive" />	
23
		<Action name="msnWebcamSend" />
24
		<Action name="msnSendFile" />		
25
		<Action name="msnSendNudge" />
26
	</ToolBar>
27
</kpartgui>
(-)tdenetwork.ori/kopete/protocols/msn/msncontact.cpp (-713 lines)
Lines 1-713 Link Here
1
/*
2
    msncontact.cpp - MSN Contact
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002      by Ryan Cumming           <bodnar42@phalynx.dhs.org>
6
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
7
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
8
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
9
10
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
11
12
    *************************************************************************
13
    *                                                                       *
14
    * This library is free software; you can redistribute it and/or         *
15
    * modify it under the terms of the GNU Lesser General Public            *
16
    * License as published by the Free Software Foundation; either          *
17
    * version 2 of the License, or (at your option) any later version.      *
18
    *                                                                       *
19
    *************************************************************************
20
*/
21
22
#include "msncontact.h"
23
24
#include <tqcheckbox.h>
25
26
#undef KDE_NO_COMPAT
27
#include <tdeaction.h>
28
#include <kdebug.h>
29
#include <tdefiledialog.h>
30
#include <klineedit.h>
31
#include <tdelocale.h>
32
#include <kstandarddirs.h>
33
#include <tdemessagebox.h>
34
#include <krun.h>
35
#include <tdetempfile.h>
36
#include <tdeconfig.h>
37
#include <tdeglobal.h>
38
#include <tqregexp.h>
39
#include <tdeio/job.h>
40
41
#include "kopetecontactlist.h"
42
#include "kopetechatsessionmanager.h"
43
#include "kopetemetacontact.h"
44
#include "kopetegroup.h"
45
#include "kopeteuiglobal.h"
46
#include "kopeteglobal.h"
47
48
#include "msninfo.h"
49
#include "msnchatsession.h"
50
#include "msnnotifysocket.h"
51
#include "msnaccount.h"
52
53
MSNContact::MSNContact( Kopete::Account *account, const TQString &id, Kopete::MetaContact *parent )
54
: Kopete::Contact( account, id, parent )
55
{
56
	m_deleted = false;
57
	m_allowed = false;
58
	m_blocked = false;
59
	m_reversed = false;
60
	m_moving = false;
61
	
62
	m_clientFlags=0;
63
64
	setFileCapable( true );
65
66
	// When we are not connected, it's because we are loading the contactlist.
67
	// so we set the initial status to offline.
68
	// We set offline directly because modifying the status after is too slow.
69
	// (notification, contactlist updating,....)
70
	//
71
	// FIXME: Hacks like these shouldn't happen in the protocols, but should be
72
	//        covered properly at the libkopete level instead - Martijn
73
	//
74
	// When we are connected, it can be because the user added a contact with the
75
	// wizard, and it can be because we are creating a temporary contact.
76
	// if it's added by the wizard, the status will be set immediately after.
77
	// if it's a temporary contact, better to set the unknown status.
78
	setOnlineStatus( ( parent && parent->isTemporary() ) ? MSNProtocol::protocol()->UNK : MSNProtocol::protocol()->FLN );
79
80
	actionBlock = 0L;
81
82
	setProperty(MSNProtocol::protocol()->propEmail, id);
83
}
84
85
MSNContact::~MSNContact()
86
{
87
	kdDebug(14140) << k_funcinfo << endl;
88
}
89
90
bool MSNContact::isReachable()
91
{
92
	if ( account()->isConnected() && isOnline() && account()->myself()->onlineStatus() != MSNProtocol::protocol()->HDN )
93
		return true;
94
95
	MSNChatSession *kmm=dynamic_cast<MSNChatSession*>(manager(Kopete::Contact::CannotCreate));
96
	if( kmm && kmm->service() )  //the chat socket is open.  than mean message will be sent
97
		return true;
98
99
	// When we are invisible we can't start a chat with others, make isReachable return false
100
	// (This is an MSN limitation, not a problem in Kopete)
101
	if ( !account()->isConnected() || account()->myself()->onlineStatus() == MSNProtocol::protocol()->HDN )
102
		return false;
103
		
104
	//if the contact is offline, it is impossible to send it a message.  but it is impossible
105
	//to be sure the contact is realy offline. For example, if the contact is not on the contactlist for
106
	//some reason.
107
	if( onlineStatus() == MSNProtocol::protocol()->FLN && ( isAllowed() || isBlocked() ) && !serverGroups().isEmpty() )
108
		return false;
109
		
110
	return true;
111
}
112
113
Kopete::ChatSession *MSNContact::manager( Kopete::Contact::CanCreateFlags canCreate )
114
{
115
	Kopete::ContactPtrList chatmembers;
116
	chatmembers.append(this);
117
118
	Kopete::ChatSession *_manager = Kopete::ChatSessionManager::self()->findChatSession(  account()->myself(), chatmembers, protocol() );
119
	MSNChatSession *manager = dynamic_cast<MSNChatSession*>( _manager );
120
	if(!manager &&  canCreate==Kopete::Contact::CanCreate)
121
	{
122
		manager = new MSNChatSession( protocol(), account()->myself(), chatmembers  );
123
		static_cast<MSNAccount*>( account() )->slotStartChatSession( contactId() );
124
	}
125
	return manager;
126
}
127
128
TQPtrList<TDEAction> *MSNContact::customContextMenuActions()
129
{
130
	TQPtrList<TDEAction> *m_actionCollection = new TQPtrList<TDEAction>;
131
132
	// Block/unblock Contact
133
	TQString label = isBlocked() ? i18n( "Unblock User" ) : i18n( "Block User" );
134
	if( !actionBlock )
135
	{
136
		actionBlock = new TDEAction( label, "msn_blocked",0, this, TQT_SLOT( slotBlockUser() ),
137
			this, "actionBlock" );
138
139
		//show profile
140
		actionShowProfile = new TDEAction( i18n("Show Profile") , 0, this, TQT_SLOT( slotShowProfile() ),
141
			this, "actionShowProfile" );
142
143
		// Send mail (only available if it is an hotmail account)
144
		actionSendMail = new TDEAction( i18n("Send Email...") , "mail_generic",0, this, TQT_SLOT( slotSendMail() ),
145
			this, "actionSendMail" );
146
147
		// Invite to receive webcam
148
		actionWebcamReceive = new TDEAction( i18n( "View Contact's Webcam" ), "webcamreceive",  0, this, TQT_SLOT(slotWebcamReceive() ), this, "msnWebcamReceive" ) ;
149
150
		//Send webcam action
151
		actionWebcamSend = new TDEAction( i18n( "Send Webcam" ), "webcamsend",  0, this, TQT_SLOT(slotWebcamSend() ), this, "msnWebcamSend" ) ;
152
	}
153
	else
154
		actionBlock->setText( label );
155
156
	actionSendMail->setEnabled( static_cast<MSNAccount*>(account())->isHotmail());
157
158
	m_actionCollection->append( actionBlock );
159
	m_actionCollection->append( actionShowProfile );
160
	m_actionCollection->append( actionSendMail );
161
	m_actionCollection->append( actionWebcamReceive );
162
	m_actionCollection->append( actionWebcamSend );
163
164
165
	return m_actionCollection;
166
}
167
168
void MSNContact::slotBlockUser()
169
{
170
	MSNNotifySocket *notify = static_cast<MSNAccount*>( account() )->notifySocket();
171
	if( !notify )
172
	{
173
		KMessageBox::error( Kopete::UI::Global::mainWidget(),
174
			i18n( "<qt>Please go online to block or unblock a contact.</qt>" ),
175
			i18n( "MSN Plugin" ));
176
		return;
177
	}
178
179
	if( m_blocked )
180
	{
181
		notify->removeContact( contactId(), MSNProtocol::BL, TQString(), TQString() );
182
	}
183
	else
184
	{
185
		if(m_allowed)
186
			notify->removeContact( contactId(), MSNProtocol::AL, TQString(), TQString() );
187
		else
188
			notify->addContact( contactId(), MSNProtocol::BL, TQString(), TQString(), TQString() );
189
	}
190
}
191
192
void MSNContact::slotUserInfo()
193
{
194
	KDialogBase *infoDialog=new KDialogBase( 0l, "infoDialog", /*modal = */false, TQString(), KDialogBase::Close , KDialogBase::Close, false );
195
	TQString nick=property( Kopete::Global::Properties::self()->nickName()).value().toString();
196
	TQString personalMessage=property( MSNProtocol::protocol()->propPersonalMessage).value().toString();
197
	MSNInfo *info=new MSNInfo ( infoDialog,"info");
198
	info->m_id->setText( contactId() );
199
	info->m_displayName->setText(nick);
200
	info->m_personalMessage->setText(personalMessage);
201
	info->m_phh->setText(m_phoneHome);
202
	info->m_phw->setText(m_phoneWork);
203
	info->m_phm->setText(m_phoneMobile);
204
	info->m_reversed->setChecked(m_reversed);
205
206
	connect( info->m_reversed, TQT_SIGNAL(toggled(bool)) , this, TQT_SLOT(slotUserInfoDialogReversedToggled()));
207
208
	infoDialog->setMainWidget(info);
209
	infoDialog->setCaption(nick);
210
	infoDialog->show();
211
}
212
213
void MSNContact::slotUserInfoDialogReversedToggled()
214
{
215
	//workaround to make this checkboxe readonly
216
	const TQCheckBox *cb=dynamic_cast<const TQCheckBox*>(sender());
217
	if(cb && cb->isChecked()!=m_reversed)
218
		const_cast<TQCheckBox*>(cb)->setChecked(m_reversed);
219
}
220
221
void MSNContact::deleteContact()
222
{
223
	kdDebug( 14140 ) << k_funcinfo << endl;
224
225
	MSNNotifySocket *notify = static_cast<MSNAccount*>( account() )->notifySocket();
226
	if( notify )
227
	{
228
		if( hasProperty(MSNProtocol::protocol()->propGuid.key()) )
229
		{
230
			// Remove from all groups he belongs (if applicable)
231
			for( TQMap<TQString, Kopete::Group*>::Iterator it = m_serverGroups.begin(); it != m_serverGroups.end(); ++it )
232
			{
233
				kdDebug(14140) << k_funcinfo << "Removing contact from group \"" << it.key() << "\"" << endl;
234
				notify->removeContact( contactId(), MSNProtocol::FL, guid(), it.key() );
235
			}
236
	
237
			// Then trully remove it from server contact list, 
238
			// because only removing the contact from his groups isn't sufficent from MSNP11.
239
			kdDebug( 14140 ) << k_funcinfo << "Removing contact from top-level." << endl;
240
			notify->removeContact( contactId(), MSNProtocol::FL, guid(), TQString());
241
		}
242
		else
243
		{
244
			kdDebug( 14140 ) << k_funcinfo << "The contact is already removed from server, just delete it" << endl;
245
			deleteLater();
246
		}
247
	}
248
	else
249
	{
250
		// FIXME: This case should be handled by Kopete, not by the plugins :( - Martijn
251
		// FIXME: We should be able to delete contacts offline, and remove it from server next time we go online - Olivier
252
		KMessageBox::error( Kopete::UI::Global::mainWidget(), i18n( "<qt>Please go online to remove a contact from your contact list.</qt>" ), i18n( "MSN Plugin" ));
253
	}
254
}
255
256
bool MSNContact::isBlocked() const
257
{
258
	return m_blocked;
259
}
260
261
void MSNContact::setBlocked( bool blocked )
262
{
263
	if( m_blocked != blocked )
264
	{
265
		m_blocked = blocked;
266
		//update the status
267
		setOnlineStatus(m_currentStatus);
268
		//m_currentStatus is used here.  previously it was  onlineStatus()  but this may cause problem when
269
		// the account is offline because of the  Kopete::Contact::OnlineStatus()  account offline hack.
270
	}
271
}
272
273
bool MSNContact::isAllowed() const
274
{
275
	return m_allowed;
276
}
277
278
void MSNContact::setAllowed( bool allowed )
279
{
280
	m_allowed = allowed;
281
}
282
283
bool MSNContact::isReversed() const
284
{
285
	return m_reversed;
286
}
287
288
void MSNContact::setReversed( bool reversed )
289
{
290
	m_reversed= reversed;
291
}
292
293
bool MSNContact::isDeleted() const
294
{
295
	return m_deleted;
296
}
297
298
void MSNContact::setDeleted( bool deleted )
299
{
300
	m_deleted= deleted;
301
}
302
303
uint MSNContact::clientFlags() const
304
{
305
	return m_clientFlags;
306
}
307
308
void MSNContact::setClientFlags( uint flags )
309
{
310
	if(m_clientFlags != flags) 
311
	{
312
		if(hasProperty( MSNProtocol::protocol()->propClient.key() ))
313
		{
314
			if( flags & MSNProtocol::WebMessenger)
315
				setProperty(  MSNProtocol::protocol()->propClient , i18n("Web Messenger") );
316
			else if( flags & MSNProtocol::WindowsMobile)
317
				setProperty(  MSNProtocol::protocol()->propClient , i18n("Windows Mobile") );
318
			else if( flags & MSNProtocol::MSNMobileDevice)
319
				setProperty(  MSNProtocol::protocol()->propClient , i18n("MSN Mobile") );
320
			else if( m_obj.contains("kopete")  )
321
				setProperty(  MSNProtocol::protocol()->propClient , i18n("Kopete") );
322
		}
323
324
	}
325
	m_clientFlags=flags;
326
}
327
328
void MSNContact::setInfo(const  TQString &type,const TQString &data )
329
{
330
	if( type == "PHH" )
331
	{
332
		m_phoneHome = data;
333
		setProperty(MSNProtocol::protocol()->propPhoneHome, data);
334
	}
335
	else if( type == "PHW" )
336
	{
337
		m_phoneWork=data;
338
		setProperty(MSNProtocol::protocol()->propPhoneWork, data);
339
	}
340
	else if( type == "PHM" )
341
	{
342
		m_phoneMobile = data;
343
		setProperty(MSNProtocol::protocol()->propPhoneMobile, data);
344
	}
345
	else if( type == "MOB" )
346
	{
347
		if( data == "Y" )
348
			m_phone_mob = true;
349
		else if( data == "N" )
350
			m_phone_mob = false;
351
		else
352
			kdDebug( 14140 ) << k_funcinfo << "Unknown MOB " << data << endl;
353
	}
354
	else if( type == "MFN" )
355
	{
356
		setProperty(Kopete::Global::Properties::self()->nickName(), data );
357
	}
358
	else
359
	{
360
		kdDebug( 14140 ) << k_funcinfo << "Unknow info " << type << " " << data << endl;
361
	}
362
}
363
364
365
void MSNContact::serialize( TQMap<TQString, TQString> &serializedData, TQMap<TQString, TQString> & /* addressBookData */ )
366
{
367
	// Contact id and display name are already set for us, only add the rest
368
	TQString groups;
369
	bool firstEntry = true;
370
	for( TQMap<TQString, Kopete::Group *>::ConstIterator it = m_serverGroups.begin(); it != m_serverGroups.end(); ++it )
371
	{
372
		if( !firstEntry )
373
		{
374
			groups += ",";
375
			firstEntry = true;
376
		}
377
		groups += it.key();
378
	}
379
380
	TQString lists="C";
381
	if(m_blocked)
382
		lists +="B";
383
	if(m_allowed)
384
		lists +="A";
385
	if(m_reversed)
386
		lists +="R";
387
388
	serializedData[ "groups" ]  = groups;
389
	serializedData[ "PHH" ]  = m_phoneHome;
390
	serializedData[ "PHW" ]  = m_phoneWork;
391
	serializedData[ "PHM" ]  = m_phoneMobile;
392
	serializedData[ "lists" ] = lists;
393
	serializedData[ "obj" ] = m_obj;
394
	serializedData[ "contactGuid" ] = guid();
395
}
396
397
398
TQString MSNContact::guid(){ return property(MSNProtocol::protocol()->propGuid).value().toString(); }
399
400
TQString MSNContact::phoneHome(){ return m_phoneHome ;}
401
TQString MSNContact::phoneWork(){ return m_phoneWork ;}
402
TQString MSNContact::phoneMobile(){ return m_phoneMobile ;}
403
404
405
const TQMap<TQString, Kopete::Group*>  MSNContact::serverGroups() const
406
{
407
	return m_serverGroups;
408
}
409
void MSNContact::clearServerGroups() 
410
{
411
	m_serverGroups.clear();
412
}
413
414
415
void MSNContact::sync( unsigned int changed )
416
{
417
	if( !  (changed & Kopete::Contact::MovedBetweenGroup) )
418
		return;  //we are only interested by a change in groups
419
420
	if(!metaContact() || metaContact()->isTemporary() )
421
		return;
422
423
	if(m_moving)
424
	{
425
		//We need to make sure that syncGroups is not called twice successively
426
		// because m_serverGroups will be only updated with the reply of the server
427
		// and then, the same command can be sent twice.
428
		// FIXME: if this method is called a seconds times, that mean change can be
429
		//        done in the contactlist. we should found a way to recall this
430
		//        method later. (a TQTimer?)
431
		kdDebug( 14140 ) << k_funcinfo << " This contact is already moving. Abort sync    id: " << contactId() << endl;
432
		return;
433
	}
434
	
435
	MSNNotifySocket *notify = static_cast<MSNAccount*>( account() )->notifySocket();
436
	if( !notify )
437
	{
438
		//We are not connected, we will doing it next connection.
439
		//Force to reload the whole contactlist from server to suync groups when connecting
440
		account()->configGroup()->writeEntry("serial", 0 );
441
		return;
442
	}
443
	
444
	if(m_deleted)  //the contact hasn't been synced from server yet.
445
		return; 
446
447
	unsigned int count=m_serverGroups.count();
448
449
	//Don't add the contact if it's myself.
450
	if(count==0 && contactId() == account()->accountId())
451
		return;
452
453
	//STEP ONE : add the contact to every kopetegroups where the MC is
454
	TQPtrList<Kopete::Group> groupList = metaContact()->groups();
455
	for ( Kopete::Group *group = groupList.first(); group; group = groupList.next() )
456
	{
457
		//For each group, ensure it is on the MSN server
458
		if( !group->pluginData( protocol() , account()->accountId() + " id" ).isEmpty() )
459
		{
460
			TQString Gid=group->pluginData( protocol(), account()->accountId() + " id" );
461
			if( !static_cast<MSNAccount*>( account() )->m_groupList.contains(Gid) ) 
462
			{ // ohoh!   something is corrupted on the contactlist.xml
463
			  // anyway, we never should add a contact to an unexisting group on the server.
464
			  //     This shouln't be possible anymore  2004-06-10 -Olivier
465
466
				//repair the problem
467
				group->setPluginData( protocol() , account()->accountId() + " id" , TQString());
468
				group->setPluginData( protocol() , account()->accountId() + " displayName" , TQString());
469
				kdWarning( 14140 ) << k_funcinfo << " Group " << group->displayName() << " marked with id #" <<Gid << " does not seems to be anymore on the server" << endl;
470
471
				if(!group->displayName().isEmpty() && group->type() == Kopete::Group::Normal) //not the top-level
472
				{
473
					//Create the group and add the contact
474
					static_cast<MSNAccount*>( account() )->addGroup( group->displayName(),contactId() );
475
					count++;
476
					m_moving=true;
477
				}
478
			}
479
			else if( !m_serverGroups.contains(Gid) )
480
			{
481
				//Add the contact to the group on the server
482
				notify->addContact( contactId(), MSNProtocol::FL, TQString(), guid(), Gid );
483
				count++;
484
				m_moving=true;
485
			}
486
		}
487
		else
488
		{
489
			if(!group->displayName().isEmpty() && group->type() == Kopete::Group::Normal) //not the top-level
490
			{
491
				//Create the group and add the contact
492
				static_cast<MSNAccount*>( account() )->addGroup( group->displayName(),contactId() );
493
494
				//WARNING: if contact is not correctly added (because the group was not aded corrdctly for hinstance),
495
				// if we increment the count, the contact can be deleted from the old group, and be lost :-(
496
				count++;
497
				m_moving=true;
498
			}
499
		}
500
	}
501
502
	//STEP TWO : remove the contact from groups where the MC is not, but let it at least in one group
503
504
	//contact is not in that group. on the server. we will remove them dirrectly after the loop
505
	TQValueList<TQString> removinglist; 
506
	
507
	for( TQMap<TQString, Kopete::Group*>::Iterator it = m_serverGroups.begin();(count > 1 && it != m_serverGroups.end()); ++it )
508
	{
509
		if( !static_cast<MSNAccount*>( account() )->m_groupList.contains(it.key()) )
510
		{ // ohoh!   something is corrupted on the contactlist.xml
511
		  // anyway, we never should add a contact to an unexisting group on the server.
512
513
			//repair the problem ...     //contactRemovedFromGroup( it.key() );
514
			//         ... later  (we  can't remove it from the map now )
515
			removinglist.append(it.key());
516
			count--;
517
518
			kdDebug( 14140 ) << k_funcinfo << "the group marked with id #" << it.key() << " does not seems to be anymore on the server" << endl;
519
520
			continue;
521
		}
522
523
		Kopete::Group *group=it.data();
524
		if(!group) //we can't trust the data of it()   see in MSNProtocol::deserializeContact why
525
			group=static_cast<MSNAccount*>( account() )->m_groupList[it.key()];
526
		if( !metaContact()->groups().contains(group) )
527
		{
528
			m_moving=true;
529
			notify->removeContact( contactId(), MSNProtocol::FL, guid(), it.key() );
530
			count--;
531
		}
532
	}
533
	
534
	for(TQValueList<TQString>::Iterator it= removinglist.begin() ; it != removinglist.end() ; ++it )
535
		contactRemovedFromGroup(*it);
536
537
	//FINAL TEST: is the contact at least in a group..
538
	//   this may happens if we just added a temporary contact to top-level
539
	//   we add the contact to the group #0 (the default one)
540
	/*if(count==0)
541
	{
542
//		notify->addContact( contactId(), MSNProtocol::FL, TQString(), guid(), "0");
543
	}*/
544
}
545
546
void MSNContact::contactAddedToGroup( const TQString& groupId, Kopete::Group *group )
547
{
548
	m_serverGroups.insert( groupId, group );
549
	m_moving=false;
550
}
551
552
void MSNContact::contactRemovedFromGroup( const TQString& groupId )
553
{
554
	m_serverGroups.remove( groupId );
555
	if(m_serverGroups.isEmpty() && !m_moving)
556
	{
557
		deleteLater();
558
	}
559
	m_moving=false;
560
}
561
562
563
void MSNContact::rename( const TQString &newName )
564
{
565
	//kdDebug( 14140 ) << k_funcinfo << "From: " << displayName() << ", to: " << newName << endl;
566
567
/*	if( newName == displayName() )
568
		return;*/
569
570
	// FIXME: This should be called anymore.
571
	MSNNotifySocket *notify = static_cast<MSNAccount*>( account() )->notifySocket();
572
	if( notify )
573
	{
574
		notify->changePublicName( newName, contactId() );
575
	}
576
}
577
578
void MSNContact::slotShowProfile()
579
{
580
	KRun::runURL( KURL( TQString::fromLatin1("http://members.msn.com/?pgmarket=it-it&mem=") + contactId())  , "text/html" );
581
}
582
583
584
/**
585
 * FIXME: Make this a standard KMM API call
586
 */
587
void MSNContact::sendFile( const KURL &sourceURL, const TQString &altFileName, uint /*fileSize*/ )
588
{
589
	TQString filePath;
590
591
	//If the file location is null, then get it from a file open dialog
592
	if( !sourceURL.isValid() )
593
		filePath = KFileDialog::getOpenFileName( TQString() ,"*", 0l  , i18n( "Kopete File Transfer" ));
594
	else
595
		filePath = sourceURL.path(-1);
596
597
	//kdDebug(14140) << "MSNContact::sendFile: File chosen to send:" << fileName << endl;
598
599
	if ( !filePath.isEmpty() )
600
	{
601
		TQ_UINT32 fileSize = TQFileInfo(filePath).size();
602
		//Send the file
603
		static_cast<MSNChatSession*>( manager(Kopete::Contact::CanCreate) )->sendFile( filePath, altFileName, fileSize );
604
605
	}
606
}
607
608
void MSNContact::setOnlineStatus(const Kopete::OnlineStatus& status)
609
{
610
	if(isBlocked() && status.internalStatus() < 15)
611
	{
612
		Kopete::Contact::setOnlineStatus(
613
				Kopete::OnlineStatus(status.status() ,
614
				(status.weight()==0) ? 0 : (status.weight() -1)  ,
615
				protocol() ,
616
				status.internalStatus()+15 ,
617
				status.overlayIcons() + TQStringList("msn_blocked") ,
618
				i18n("%1|Blocked").arg( status.description() ) ) );
619
	}
620
	else if(!isBlocked() && status.internalStatus() >= 15)
621
	{	//the user is not blocked, but the status is blocked
622
		switch(status.internalStatus()-15)
623
		{
624
			case 1:
625
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->NLN);
626
				break;
627
			case 2:
628
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->BSY);
629
				break;
630
			case 3:
631
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->BRB);
632
				break;
633
			case 4:
634
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->AWY);
635
				break;
636
			case 5:
637
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->PHN);
638
				break;
639
			case 6:
640
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->LUN);
641
				break;
642
			case 7:
643
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->FLN);
644
				break;
645
			case 8:
646
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->HDN);
647
				break;
648
			case 9:
649
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->IDL);
650
				break;
651
			default:
652
				Kopete::Contact::setOnlineStatus(MSNProtocol::protocol()->UNK);
653
				break;
654
		}
655
	}
656
	else
657
		Kopete::Contact::setOnlineStatus(status);
658
	m_currentStatus=status;
659
}
660
661
void MSNContact::slotSendMail()
662
{
663
	MSNNotifySocket *notify = static_cast<MSNAccount*>( account() )->notifySocket();
664
	if( notify )
665
	{
666
		notify->sendMail( contactId() );
667
	}
668
}
669
670
void MSNContact::setDisplayPicture(KTempFile *f)
671
{
672
	//copy the temp file somewere else.
673
	// in a better world, the file could be dirrectly wrote at the correct location.
674
	// but the custom emoticon code is to deeply merged in the display picture code while it could be separated.
675
	TQString newlocation=locateLocal( "appdata", "msnpictures/"+ contactId().lower().replace(TQRegExp("[./~]"),"-")  +".png"  ) ;
676
677
	TDEIO::Job *j=TDEIO::file_move( KURL::fromPathOrURL( f->name() ) , KURL::fromPathOrURL( newlocation ) , -1, true /*overwrite*/ , false /*resume*/ , false /*showProgressInfo*/ );
678
	
679
	f->setAutoDelete(false);
680
	delete f;
681
682
	//let the time to TDEIO to copy the file
683
	connect(j, TQT_SIGNAL(result(TDEIO::Job *)) , this, TQT_SLOT(slotEmitDisplayPictureChanged() ));
684
}
685
686
void MSNContact::slotEmitDisplayPictureChanged()
687
{
688
	TQString newlocation=locateLocal( "appdata", "msnpictures/"+ contactId().lower().replace(TQRegExp("[./~]"),"-")  +".png"  ) ;
689
	setProperty( Kopete::Global::Properties::self()->photo() , newlocation );
690
	emit displayPictureChanged();
691
}
692
693
void MSNContact::setObject(const TQString &obj)
694
{
695
	if(m_obj==obj && (obj.isEmpty() || hasProperty(Kopete::Global::Properties::self()->photo().key())))
696
		return;
697
698
	m_obj=obj;
699
700
	removeProperty( Kopete::Global::Properties::self()->photo()  ) ;
701
	emit displayPictureChanged();
702
703
	TDEConfig *config = TDEGlobal::config();
704
	config->setGroup( "MSN" );
705
	if ( config->readNumEntry( "DownloadPicture", 2 ) >= 2 && !obj.isEmpty() 
706
			 && account()->myself()->onlineStatus().status() != Kopete::OnlineStatus::Invisible )
707
		manager(Kopete::Contact::CanCreate); //create the manager which will download the photo automatically.
708
}
709
710
#include "msncontact.moc"
711
712
// vim: set noet ts=4 sts=4 sw=4:
713
(-)tdenetwork.ori/kopete/protocols/msn/msncontact.h (-200 lines)
Lines 1-200 Link Here
1
/*
2
    msncontact.h - MSN Contact
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002      by Ryan Cumming           <bodnar42@phalynx.dhs.org>
6
    Copyright (c) 2002      by Martijn Klingens       <klingens@kde.org>
7
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
8
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
9
10
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
11
12
13
    *************************************************************************
14
    *                                                                       *
15
    * This program is free software; you can redistribute it and/or modify  *
16
    * it under the terms of the GNU General Public License as published by  *
17
    * the Free Software Foundation; either version 2 of the License, or     *
18
    * (at your option) any later version.                                   *
19
    *                                                                       *
20
    *************************************************************************
21
*/
22
23
#ifndef MSNCONTACT_H
24
#define MSNCONTACT_H
25
26
#include "kopetecontact.h"
27
#include "kopeteonlinestatus.h"
28
29
#include <kurl.h>
30
31
class TQListView;
32
class TQListViewItem;
33
class TQPixmap;
34
class TQTimer;
35
36
class MSNChatSession;
37
class TDEAction;
38
class TDEActionCollection;
39
class KTempFile;
40
41
namespace Kopete { class Protocol; }
42
namespace Kopete { class OnlineStatus; }
43
44
class MSNContact : public Kopete::Contact
45
{
46
	Q_OBJECT
47
  
48
49
public:
50
	MSNContact( Kopete::Account *account, const TQString &id, Kopete::MetaContact *parent );
51
	~MSNContact();
52
53
	/**
54
	 * Indicate whether this contact is blocked
55
	 */
56
	bool isBlocked() const;
57
	void setBlocked( bool b );
58
59
	/**
60
	 * Indicate whether this contact is deleted
61
	 *   (not on the serverside list)
62
	 */
63
	bool isDeleted() const;
64
	void setDeleted( bool d );
65
66
	/**
67
	 * Indicate whether this contact is allowed
68
	 */
69
	bool isAllowed() const;
70
	void setAllowed( bool d );
71
72
	/**
73
	 * Indicate whether this contact is on the reversed list
74
	 */
75
	bool isReversed() const;
76
	void setReversed( bool d );
77
	
78
	/**
79
	 * set one phone number
80
	 */
81
	void setInfo(const TQString &type, const TQString &data);
82
83
	/**
84
	 * The groups in which the user is located on the server.
85
	 */
86
	const TQMap<TQString, Kopete::Group *>  serverGroups() const;
87
	/**
88
	 * clear that map
89
	 */
90
	void clearServerGroups();
91
	
92
	/**
93
	 * client flags  (say what version of msn messenger the contact is using)
94
	 */
95
	uint clientFlags() const;
96
	void setClientFlags( uint );
97
98
	virtual bool isReachable();
99
100
	virtual TQPtrList<TDEAction> *customContextMenuActions();
101
102
	/**
103
	 * update the server group map
104
	 */
105
	void contactRemovedFromGroup( const TQString& groupId );
106
	void contactAddedToGroup(const TQString& groupId, Kopete::Group *group );
107
108
	virtual void serialize( TQMap<TQString, TQString> &serializedData, TQMap<TQString, TQString> &addressBookData );
109
110
	/**
111
	 * Rename contact on server
112
	 */
113
	virtual void rename( const TQString &newName ) KDE_DEPRECATED;
114
115
	/**
116
	 * Returns the MSN Message Manager associated with this contact
117
	 */
118
	virtual Kopete::ChatSession *manager( Kopete::Contact::CanCreateFlags = Kopete::Contact::CannotCreate );
119
120
121
	/**
122
	 * Because blocked contact have a small auto-modified status
123
	 */
124
	void setOnlineStatus(const Kopete::OnlineStatus&);
125
126
	TQString guid();
127
	TQString phoneHome();
128
	TQString phoneWork();
129
	TQString phoneMobile();
130
131
	void setObject(const TQString &obj);
132
	TQString object() const { return m_obj; }
133
134
public slots:
135
	virtual void slotUserInfo();
136
	virtual void deleteContact();
137
	virtual void sendFile( const KURL &sourceURL = KURL(),
138
						   const TQString &fileName = TQString(), uint fileSize = 0L );
139
140
	/**
141
	 * Every time the kopete's contactlist is modified, we sync the serverlist with it
142
	 */
143
	virtual void sync( unsigned int cvhanged= 0xff);
144
145
146
	void setDisplayPicture(KTempFile *f) ;
147
148
signals:
149
	void displayPictureChanged();
150
151
private slots:
152
	void slotBlockUser();
153
	void slotShowProfile();
154
	void slotSendMail();
155
	void slotEmitDisplayPictureChanged();
156
157
	/**
158
	 * Workaround to make this checkboxe readonly
159
	 */
160
	void slotUserInfoDialogReversedToggled();
161
162
private:
163
	TQMap<TQString, Kopete::Group *> m_serverGroups;
164
165
	bool m_blocked;
166
	bool m_allowed;
167
	bool m_deleted;
168
	bool m_reversed;
169
	bool m_moving;
170
	bool m_phone_mob;
171
	
172
	uint m_clientFlags;
173
174
	TQString m_phoneHome;
175
	TQString m_phoneWork;
176
	TQString m_phoneMobile;
177
178
179
	TDEAction *actionBlock;
180
	TDEAction *actionShowProfile;
181
	TDEAction *actionSendMail;
182
	TDEAction *actionWebcamReceive;
183
	TDEAction *actionWebcamSend;
184
185
	TQString m_obj; //the MSNObject
186
187
	/**
188
	 * keep the current status here.  (it's normally already in Kopete::Contact::d->onlineStatus)
189
	 * This is a workaround to prevent problems with the account offline status.
190
	 */
191
	Kopete::OnlineStatus m_currentStatus;
192
193
	//MSNProtocol::deserializeContact need to acess some contact insternals
194
	friend class MSNProtocol;
195
};
196
197
#endif
198
199
// vim: set noet ts=4 sts=4 sw=4:
200
(-)tdenetwork.ori/kopete/protocols/msn/msndebugrawcmddlg.cpp (-73 lines)
Lines 1-73 Link Here
1
/*
2
    msndebugrawcmddlg.cpp - Send a raw MSN command for debugging
3
4
    Copyright (c) 2002 by Martijn Klingens       <klingens@kde.org>
5
    Kopete    (c) 2002 by the Kopete developers  <kopete-devel@kde.org>
6
7
    Portions of this code are taken from KMerlin,
8
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#include "msndebugrawcmddlg.h"
21
22
#include "ui/msndebugrawcommand_base.h"
23
24
#include <tqcheckbox.h>
25
#include <tqlineedit.h>
26
#include <ktextedit.h>
27
28
#include <tdelocale.h>
29
30
MSNDebugRawCmdDlg::MSNDebugRawCmdDlg( TQWidget *parent )
31
: KDialogBase( parent, 0L, true,
32
	i18n( "DEBUG: Send Raw Command - MSN Plugin" ), Ok | Cancel,
33
	Ok, true )
34
{
35
	setInitialSize( TQSize( 350, 200 ) );
36
37
	m_main = new MSNDebugRawCommand_base( this );
38
	setMainWidget( m_main );
39
}
40
41
MSNDebugRawCmdDlg::~MSNDebugRawCmdDlg()
42
{
43
}
44
45
TQString MSNDebugRawCmdDlg::command()
46
{
47
	return m_main->m_command->text();
48
}
49
50
TQString MSNDebugRawCmdDlg::params()
51
{
52
	return m_main->m_params->text();
53
}
54
55
bool MSNDebugRawCmdDlg::addNewline()
56
{
57
	return m_main->m_addNewline->isChecked();
58
}
59
60
bool MSNDebugRawCmdDlg::addId()
61
{
62
	return m_main->m_addId->isChecked();
63
}
64
65
TQString MSNDebugRawCmdDlg::msg()
66
{
67
	return m_main->m_msg->text();
68
}
69
70
#include "msndebugrawcmddlg.moc"
71
72
// vim: set noet ts=4 sts=4 sw=4:
73
(-)tdenetwork.ori/kopete/protocols/msn/msndebugrawcmddlg.h (-54 lines)
Lines 1-54 Link Here
1
/*
2
    msndebugrawcmddlg.h - Send a raw MSN command for debugging
3
4
    Copyright (c) 2002 by Martijn Klingens       <klingens@kde.org>
5
    Kopete    (c) 2002 by the Kopete developers  <kopete-devel@kde.org>
6
7
    Portions of this code are taken from KMerlin,
8
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#ifndef MSNDEBUGRAWCMDDLG_H
21
#define MSNDEBUGRAWCMDDLG_H
22
23
#include <kdialogbase.h>
24
25
class MSNDebugRawCommand_base;
26
27
/**
28
 * @author Martijn Klingens <klingens@kde.org>
29
 *
30
 * Simple debugging help
31
 */
32
class MSNDebugRawCmdDlg : public KDialogBase
33
{
34
	Q_OBJECT
35
  
36
37
public:
38
	MSNDebugRawCmdDlg( TQWidget *parent );
39
	~MSNDebugRawCmdDlg();
40
41
	TQString command();
42
	TQString params();
43
	bool addNewline();
44
	bool addId();
45
	TQString msg();
46
47
private:
48
	MSNDebugRawCommand_base *m_main;
49
};
50
51
#endif
52
53
// vim: set noet ts=4 sts=4 sw=4:
54
(-)tdenetwork.ori/kopete/protocols/msn/msnfiletransfersocket.cpp (-481 lines)
Lines 1-481 Link Here
1
/***************************************************************************
2
                          msnfiletransfersocket.cpp  -  description
3
                             -------------------
4
    begin                : mer jui 31 2002
5
    copyright            : (C) 2002 by Olivier Goffart
6
    email                : ogoffart @ kde.org
7
 ***************************************************************************/
8
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17
18
#include "msnfiletransfersocket.h"
19
20
#include <stdlib.h>
21
#include <math.h>
22
23
//qt
24
#include <tqtimer.h>
25
26
// kde
27
#include <kdebug.h>
28
#include <kserversocket.h>
29
#include <kbufferedsocket.h>
30
#include <tdefiledialog.h>
31
#include <tdelocale.h>
32
33
#include "kopetetransfermanager.h"
34
#include "kopetecontact.h"
35
#include "kopetemetacontact.h"
36
#include "msnchatsession.h"
37
#include "msnswitchboardsocket.h"
38
#include "msnnotifysocket.h"
39
#include "msnaccount.h"
40
41
using namespace KNetwork;
42
43
MSNFileTransferSocket::MSNFileTransferSocket(const TQString &handle, Kopete::Contact *c,bool incoming, TQObject* parent)
44
	: MSNSocket(parent) , MSNInvitation(incoming, MSNFileTransferSocket::applicationID() , i18n("File Transfer - MSN Plugin"))
45
{
46
	m_handle=handle;
47
	m_kopeteTransfer=0l;
48
	m_file=0L;
49
	m_server=0L;
50
	m_contact=c;
51
	ready=true;
52
53
	TQObject::connect( this, TQT_SIGNAL( socketClosed() ), this, TQT_SLOT( slotSocketClosed() ) );
54
	TQObject::connect( this, TQT_SIGNAL( blockRead( const TQByteArray & ) ), this, TQT_SLOT(slotReadBlock( const TQByteArray & ) ) );
55
}
56
57
MSNFileTransferSocket::~MSNFileTransferSocket()
58
{
59
	delete m_file;
60
	delete m_server;
61
	kdDebug(14140) << "MSNFileTransferSocket::~MSNFileTransferSocket" <<endl;
62
}
63
64
void MSNFileTransferSocket::parseCommand(const TQString & cmd, uint id, const TQString & data)
65
{
66
	if( cmd == "VER" )
67
	{
68
		if(data.section( ' ', 0, 0 ) != "MSNFTP")
69
		{
70
			kdDebug(14140) << "MSNFileTransferSocket::parseCommand (VER): bad version: disconnect" <<endl;
71
			disconnect();
72
		}
73
		else
74
		{
75
			if( m_incoming )
76
				sendCommand( "USR", m_handle + " " + m_authcook, false );
77
			else
78
				sendCommand( "VER", "MSNFTP" , false );
79
		}
80
	}
81
	else if( cmd == "FIL" )
82
	{
83
		m_size=id; //data.toUInt(); //BUG: the size is take as id bye MSNSocket because it is a number
84
85
		m_downsize=0;
86
		m_file=new TQFile(m_fileName);
87
88
		if( m_file->open( IO_WriteOnly ))
89
			sendCommand( "TFR" ,NULL,false);
90
		else
91
		{
92
			kdDebug(14140) << "MSNFileTransferSocket::parseCommand: ERROR: unable to open file - disconnect " <<endl;
93
			disconnect();
94
		}
95
	}
96
	else if( cmd == "BYE" )
97
	{
98
		kdDebug(14140) << "MSNFileTransferSocket::parseCommand : end of transfer " <<endl;
99
		disconnect();
100
	}
101
	else if( cmd == "USR" )
102
	{
103
		if(data.section( ' ', 1, 1 )!= m_authcook)
104
		{
105
			kdDebug(14140) << "MSNFileTransferSocket::parseCommand (USR): bad auth" <<endl;
106
			disconnect();
107
		}
108
		else
109
			sendCommand("FIL" , TQString::number(size()) , false);
110
	}
111
	else if( cmd == "TFR" )
112
	{
113
		m_downsize=0;
114
		ready=true;
115
		TQTimer::singleShot( 0, this, TQT_SLOT(slotSendFile()) );
116
	}
117
	else if( cmd == "CCL" )
118
	{
119
		disconnect();
120
	}
121
	else
122
		kdDebug(14140) << "MSNFileTransferSocket::parseCommand : unknown command " <<cmd <<endl;
123
124
//	kdDebug(14140) << "MSNFileTransferSocket::parseCommand : done " <<cmd <<endl;
125
}
126
127
void MSNFileTransferSocket::doneConnect()
128
{
129
	if(m_incoming)
130
		sendCommand( "VER", "MSNFTP", false );
131
	MSNSocket::doneConnect();
132
}
133
134
void MSNFileTransferSocket::bytesReceived(const TQByteArray & head)
135
{
136
	if(head[0]!='\0')
137
	{
138
		kdDebug(14140) << "MSNFileTransferSocket::bytesReceived: transfer aborted" <<endl;
139
		TQTimer::singleShot(0,this,TQT_SLOT(disconnect()));
140
	}
141
	unsigned int sz=(int)((unsigned char)head.data()[2])*256+(int)((unsigned char)head.data()[1]);
142
//	kdDebug(14140) << "MSNFileTransferSocket::bytesReceived: " << sz <<endl;
143
	readBlock(sz);
144
}
145
146
void MSNFileTransferSocket::slotSocketClosed()
147
{
148
	kdDebug(14140) << "MSNFileTransferSocket::slotSocketClose "<<  endl;
149
	if(m_file)
150
		m_file->close();
151
	delete m_file;
152
	m_file=0L;
153
	delete m_server;
154
	m_server=0L;
155
	if(m_kopeteTransfer)
156
	{
157
		if( (m_downsize!=m_size  || m_downsize==0 ) )
158
			m_kopeteTransfer->slotError(  TDEIO::ERR_UNKNOWN , i18n( "An unknown error occurred" ) );
159
		else 
160
			m_kopeteTransfer->slotComplete();
161
	}	
162
	emit done(this);
163
}
164
165
void MSNFileTransferSocket::slotReadBlock(const TQByteArray &block)
166
{
167
	m_file->writeBlock( block.data(), block.size() );      // write to file
168
169
	m_downsize+=block.size();
170
	if(m_kopeteTransfer) m_kopeteTransfer->slotProcessed(m_downsize);
171
	kdDebug(14140) << "MSNFileTransferSocket  -  " << m_downsize << " of " << m_size <<" done"<<endl;
172
173
	if(m_downsize==m_size)
174
	{
175
		//the transfer seems to be finished.  
176
		sendCommand( "BYE" ,"16777989",false);
177
		//  if we are not already disconected in 30 seconds, do it.
178
		TQTimer::singleShot( 30000 , this, TQT_SLOT(disconnect() ) );
179
180
	}
181
}
182
183
void MSNFileTransferSocket::setKopeteTransfer(Kopete::Transfer *kt)
184
{
185
	m_kopeteTransfer=kt;
186
	if(kt)
187
	{
188
		TQObject::connect(kt , TQT_SIGNAL(transferCanceled()), this, TQT_SLOT(abort()));
189
		TQObject::connect(kt,  TQT_SIGNAL(destroyed()) , this , TQT_SLOT(slotKopeteTransferDestroyed()));
190
	}
191
}
192
193
void MSNFileTransferSocket::listen(int port)
194
{
195
	m_server = new TDEServerSocket();
196
197
	TQObject::connect( m_server, TQT_SIGNAL(readyAccept()), this,  TQT_SLOT(slotAcceptConnection()));
198
	m_server->setAddress(TQString::number(port));
199
200
	kdDebug(14140) << "MSNFileTransferSocket::listen: about to listen"<<endl;
201
	bool listenResult = m_server->listen(1);
202
	kdDebug(14140) << "MSNFileTransferSocket::listen: result: "<<  listenResult <<endl;
203
	TQTimer::singleShot( 60000, this, TQT_SLOT(slotTimer()) );
204
	kdDebug(14140) << "MSNFileTransferSocket::listen done" <<endl;
205
}
206
207
void MSNFileTransferSocket::slotAcceptConnection()
208
{
209
	kdDebug(14140) << "MSNFileTransferSocket::slotAcceptConnection" <<endl;
210
	if(!accept(m_server))
211
	{
212
		if( m_kopeteTransfer)
213
				m_kopeteTransfer->slotError(  TDEIO::ERR_UNKNOWN , i18n( "An unknown error occurred" ) );
214
		emit done(this);
215
	}
216
}
217
218
void MSNFileTransferSocket::slotTimer()
219
{
220
	if(onlineStatus() != Disconnected)
221
		return;
222
	kdDebug(14140) << "MSNFileTransferSocket::slotTimer: timeout "<<  endl;
223
	if( m_kopeteTransfer)
224
	{
225
		m_kopeteTransfer->slotError( TDEIO::ERR_CONNECTION_BROKEN , i18n( "Connection timed out" ) );
226
	}
227
228
	MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
229
	if(manager && manager->service())
230
		manager->service()->sendCommand( "MSG" , "N", true, rejectMessage("TIMEOUT") );
231
232
	emit done(this);
233
}
234
235
void MSNFileTransferSocket::abort()
236
{
237
	if(m_incoming)
238
	{
239
		sendCommand( "CCL" , NULL ,false);
240
	}
241
	else
242
	{
243
		TQByteArray bytes(3);
244
		bytes[0]='\1';
245
		bytes[1]='\0';
246
		bytes[2]='\0';
247
		sendBytes( bytes );
248
		m_downsize=m_size; //we don't want to send data anymore;
249
	}
250
	//the timer wait one second, the time to send the CCL or the binary header
251
	//retarding the disconnection keep away from a crash. (in TDEIO::Job::emitResult when `delete this`)
252
	TQTimer::singleShot( 1000, this, TQT_SLOT(disconnect()) );
253
	ready=false;
254
}
255
256
void MSNFileTransferSocket::setFile( const TQString &fn, long unsigned int fileSize )
257
{
258
	m_fileName=fn;
259
	if(!m_incoming)
260
	{
261
		if(m_file)
262
		{
263
			kdDebug(14140) << "MSNFileTransferSocket::setFileName: WARNING m_file already exists" << endl;
264
			delete m_file;
265
		}
266
		m_file = new TQFile( fn );
267
		if(!m_file->open(IO_ReadOnly))
268
		{
269
			//FIXME: abort transfer here
270
			kdDebug(14140) << "MSNFileTransferSocket::setFileName: WARNING unable to open the file" << endl;
271
		}
272
273
		//If the fileSize is 0 it was not given, we are to get it from the file
274
		if(fileSize == 0L)
275
			m_size = m_file->size();
276
		else
277
			m_size = fileSize;
278
	}
279
}
280
281
282
void MSNFileTransferSocket::slotSendFile()
283
{
284
//	kdDebug(14140) <<"MSNFileTransferSocket::slotSendFile()" <<endl;
285
	if( m_downsize >= m_size)
286
	{
287
		//the transfer seems to be finished.  
288
		//  if we are not already disconected in 30 seconds, do it.
289
		TQTimer::singleShot( 30000 , this, TQT_SLOT(disconnect() ) );
290
		return;
291
	}
292
293
	if(ready)
294
	{
295
		char data[2046];
296
		int bytesRead = m_file->readBlock( data, 2045 );
297
			
298
		TQByteArray block(bytesRead+3);
299
//		char i1= (char)fmod( bytesRead, 256 ) ;
300
//		char i2= (char)floor( bytesRead / 256 ) ;
301
//		kdDebug(14140) << "MSNFileTransferSocket::slotSendFile: " << (int)i1 <<" + 256* "<< (int)i2 <<" = " << bytesRead <<endl;
302
		block[0]='\0';
303
		block[1]= (char)fmod( bytesRead, 256 );
304
		block[2]= (char)floor( bytesRead / 256 );
305
306
		for (  int f = 0; f < bytesRead; f++ )
307
		{
308
			block[f+3] = data[f];
309
		}
310
311
		sendBytes(block);
312
313
		m_downsize+=bytesRead;
314
		if(m_kopeteTransfer)
315
			 m_kopeteTransfer->slotProcessed(m_downsize);
316
		kdDebug(14140) << "MSNFileTransferSocket::slotSendFile: " << m_downsize << " of " << m_size <<" done"<<endl;
317
	}
318
	ready=false;
319
320
	TQTimer::singleShot( 10, this, TQT_SLOT(slotSendFile()) );
321
}
322
323
void MSNFileTransferSocket::slotReadyWrite()
324
{
325
	ready=true;
326
	MSNSocket::slotReadyWrite();
327
}
328
329
TQString MSNFileTransferSocket::invitationHead()
330
{
331
	TQTimer::singleShot( 10 * 60000, this, TQT_SLOT(slotTimer()) );  //the user has 10 mins to accept or refuse or initiate the transfer
332
333
	return TQString( MSNInvitation::invitationHead()+
334
					"Application-File: "+ m_fileName.right( m_fileName.length() - m_fileName.findRev( '/' ) - 1 ) +"\r\n"
335
					"Application-FileSize: "+ TQString::number(size()) +"\r\n\r\n").utf8();
336
}
337
338
void MSNFileTransferSocket::parseInvitation(const TQString& msg)
339
{
340
	TQRegExp rx("Invitation-Command: ([A-Z]*)");
341
	rx.search(msg);
342
	TQString command=rx.cap(1);
343
	if( msg.contains("Invitation-Command: INVITE") )
344
	{
345
		rx=TQRegExp("Application-File: ([^\\r\\n]*)");
346
		rx.search(msg);
347
		TQString filename = rx.cap(1);
348
		rx=TQRegExp("Application-FileSize: ([0-9]*)");
349
		rx.search(msg);
350
		unsigned long int filesize= rx.cap(1).toUInt();
351
352
		MSNInvitation::parseInvitation(msg); //for the cookie
353
354
		Kopete::TransferManager::transferManager()->askIncomingTransfer( m_contact , filename, filesize, TQString(), TQString::number( cookie() ) );
355
356
		TQObject::connect( Kopete::TransferManager::transferManager(), TQT_SIGNAL( accepted( Kopete::Transfer *, const TQString& ) ),this, TQT_SLOT( slotFileTransferAccepted( Kopete::Transfer *, const TQString& ) ) );
357
		TQObject::connect( Kopete::TransferManager::transferManager(), TQT_SIGNAL( refused( const Kopete::FileTransferInfo & ) ), this, TQT_SLOT( slotFileTransferRefused( const Kopete::FileTransferInfo & ) ) );
358
359
	}
360
	else if( msg.contains("Invitation-Command: ACCEPT") )
361
	{
362
		if(incoming())
363
		{
364
			rx=TQRegExp("IP-Address: ([0-9\\.]*)");
365
			rx.search(msg);
366
			TQString ip_address = rx.cap(1);
367
			rx=TQRegExp("AuthCookie: ([0-9]*)");
368
			rx.search(msg);
369
			TQString authcook = rx.cap(1);
370
			rx=TQRegExp("Port: ([0-9]*)");
371
			rx.search(msg);
372
			TQString port = rx.cap(1);
373
374
			setAuthCookie(authcook);
375
			connect(ip_address, port.toUInt());
376
		}
377
		else
378
		{
379
			unsigned long int auth = (rand()%(999999))+1;
380
			setAuthCookie(TQString::number(auth));
381
382
			setKopeteTransfer(Kopete::TransferManager::transferManager()->addTransfer(m_contact, fileName(), size(),  m_contact->metaContact() ? m_contact->metaContact()->displayName() : m_contact->contactId() , Kopete::FileTransferInfo::Outgoing));
383
384
			MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
385
			if(manager && manager->service())
386
			{
387
				MSNNotifySocket *notify=static_cast<MSNAccount*>(manager->account())->notifySocket();
388
				if(notify){
389
				
390
				TQCString message=TQString(
391
					"MIME-Version: 1.0\r\n"
392
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
393
					"\r\n"
394
					"Invitation-Command: ACCEPT\r\n"
395
					"Invitation-Cookie: " + TQString::number(cookie()) + "\r\n"
396
					"IP-Address: " + notify->localIP()  + "\r\n"
397
					"Port: 6891\r\n"
398
					"AuthCookie: "+TQString::number(auth)+"\r\n"
399
					"Launch-Application: FALSE\r\n"
400
					"Request-Data: IP-Address:\r\n\r\n").utf8();
401
402
				manager->service()->sendCommand( "MSG" , "N", true, message );
403
				}
404
			}
405
406
			listen(6891);
407
		}
408
	}
409
	else //CANCEL
410
	{
411
		MSNInvitation::parseInvitation(msg);
412
		if( m_kopeteTransfer)
413
			m_kopeteTransfer->slotError( TDEIO::ERR_ABORTED , i18n( "The remote user aborted" ) );
414
		emit done(this);
415
416
	}
417
}
418
419
void MSNFileTransferSocket::slotFileTransferAccepted(Kopete::Transfer *trans, const TQString& fileName)
420
{
421
 	if(trans->info().internalId().toULong() != cookie())
422
		return;
423
424
	if(!trans->info().contact())
425
		return;
426
427
	setKopeteTransfer(trans);
428
429
	MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
430
431
	if(manager && manager->service())
432
	{
433
		setFile(fileName);
434
435
		TQCString message=TQString(
436
			"MIME-Version: 1.0\r\n"
437
			"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
438
			"\r\n"
439
			"Invitation-Command: ACCEPT\r\n"
440
			"Invitation-Cookie: " + TQString::number(cookie()) + "\r\n"
441
			"Launch-Application: FALSE\r\n"
442
			"Request-Data: IP-Address:\r\n"  ).utf8();
443
		manager->service()->sendCommand( "MSG" , "N", true, message );
444
445
		TQTimer::singleShot( 3 * 60000, this, TQT_SLOT(slotTimer()) ); //if after 3 minutes the transfer has not begin, delete this
446
	}
447
	else
448
	{
449
		if( m_kopeteTransfer)
450
			m_kopeteTransfer->slotError(  TDEIO::ERR_UNKNOWN , i18n( "An unknown error occurred" ) );
451
		emit done(this);
452
453
	}
454
}
455
456
void MSNFileTransferSocket::slotFileTransferRefused(const Kopete::FileTransferInfo &info)
457
{
458
	if(info.internalId().toULong() != cookie())
459
		return;
460
461
	if(!info.contact())
462
		return;
463
464
	MSNChatSession* manager=dynamic_cast<MSNChatSession*>(m_contact->manager());
465
466
	if(manager && manager->service())
467
	{
468
		manager->service()->sendCommand( "MSG" , "N", true, rejectMessage() );
469
	}
470
471
	emit done(this);
472
}
473
474
void MSNFileTransferSocket::slotKopeteTransferDestroyed()
475
{
476
	m_kopeteTransfer=0L;
477
}
478
479
480
#include "msnfiletransfersocket.moc"
481
(-)tdenetwork.ori/kopete/protocols/msn/msnfiletransfersocket.h (-120 lines)
Lines 1-120 Link Here
1
/***************************************************************************
2
                          msnfiletransfersocket.h  -  description
3
                             -------------------
4
    begin                : mer jui 31 2002
5
    copyright            : (C) 2002 by Olivier Goffart
6
    email                : ogoffart @ kde.org
7
 ***************************************************************************/
8
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17
18
#ifndef MSNFILETRANSFERSOCKET_H
19
#define MSNFILETRANSFERSOCKET_H
20
21
#include <tqwidget.h>
22
23
#include "msnsocket.h"
24
#include "msninvitation.h"
25
26
class TQFile;
27
28
namespace KNetwork {
29
  class TDEServerSocket;
30
}
31
32
namespace Kopete { class Transfer; }
33
namespace Kopete { class FileTransferInfo; }
34
namespace Kopete { class Protocol; }
35
namespace Kopete { class Contact; }
36
37
/**
38
 * @author Olivier Goffart
39
 */
40
class MSNFileTransferSocket : public MSNSocket , public MSNInvitation
41
{
42
	Q_OBJECT
43
  
44
45
public:
46
	MSNFileTransferSocket(const TQString &myID,Kopete::Contact* c, bool incoming, TQObject* parent = 0L );
47
	~MSNFileTransferSocket();
48
49
	static TQString applicationID() { return "5D3E02AB-6190-11d3-BBBB-00C04F795683"; }
50
	TQString invitationHead();
51
52
53
	void setKopeteTransfer( Kopete::Transfer *kt );
54
	Kopete::Transfer* kopeteTransfer() { return m_kopeteTransfer; }
55
	void setFile( const TQString &fn, long unsigned int fileSize = 0L );
56
	void setAuthCookie( const TQString &c ) { m_authcook = c; }
57
	TQString fileName() { return m_fileName;}
58
	long unsigned int size() { return m_size;}
59
	void listen( int port );
60
61
	virtual void parseInvitation(const TQString& invitation);
62
63
	virtual TQObject* object() { return this; }
64
65
public slots:
66
	void abort();
67
68
signals:
69
	void done( MSNInvitation * );
70
71
protected:
72
	/**
73
	 * This reimplementation sets up the negotiating with the server and
74
	 * suppresses the change of the status to online until the handshake
75
	 * is complete.
76
	 */
77
	virtual void doneConnect();
78
79
	/**
80
	 * Handle an MSN command response line.
81
	 */
82
	virtual void parseCommand(const TQString & cmd, uint id, const TQString & data);
83
	virtual void bytesReceived(const TQByteArray & data);
84
85
protected slots:
86
	virtual void slotReadyWrite();
87
88
private slots:
89
	void slotSocketClosed();
90
	void slotReadBlock(const TQByteArray &);
91
	void slotAcceptConnection();
92
	void slotTimer();
93
	void slotSendFile();
94
95
	void slotFileTransferRefused( const Kopete::FileTransferInfo &info );
96
	void slotFileTransferAccepted( Kopete::Transfer *trans, const TQString& fileName );
97
	/* the Kopete::Transfer has been deleted */
98
	void slotKopeteTransferDestroyed();
99
100
101
private:
102
	TQString m_handle;
103
	Kopete::Contact *m_contact;
104
105
	long unsigned int m_size;
106
	long unsigned int m_downsize;
107
	TQString m_authcook;
108
	TQString m_fileName;
109
	Kopete::Transfer* m_kopeteTransfer;
110
	TQFile *m_file ;
111
	KNetwork::TDEServerSocket *m_server;
112
113
	bool ready;
114
115
};
116
117
#endif
118
119
// vim: set noet ts=4 sts=4 tw=4:
120
(-)tdenetwork.ori/kopete/protocols/msn/msninvitation.cpp (-100 lines)
Lines 1-100 Link Here
1
/*
2
    msninvitation.cpp
3
4
    Copyright (c) 2003 by Olivier Goffart        <ogoffart @ kde.org>
5
6
    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
#include "msninvitation.h"
18
#include <stdlib.h>
19
#include <tqregexp.h>
20
21
MSNInvitation::MSNInvitation(bool incoming, const TQString &applicationID , const TQString &applicationName)
22
{
23
	m_incoming=incoming;
24
	m_applicationId=applicationID;
25
	m_applicationName=applicationName;
26
	m_cookie= (rand()%(999999))+1;
27
	m_state = Nothing;
28
}
29
30
31
MSNInvitation::~MSNInvitation()
32
{
33
}
34
35
TQCString MSNInvitation::unimplemented(long unsigned int cookie)
36
{
37
	return TQString( "MIME-Version: 1.0\r\n"
38
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
39
					"\r\n"
40
					"Invitation-Command: CANCEL\r\n"
41
					"Cancel-Code: REJECT_NOT_INSTALLED\r\n"
42
					"Invitation-Cookie: " + TQString::number(cookie) + "\r\n"
43
					"Session-ID: {120019D9-C3F5-4F94-978D-CB33534C3309}\r\n\r\n").utf8();
44
		//FIXME: i don't know at all what Seession-ID is
45
}
46
47
TQString MSNInvitation::invitationHead()
48
{
49
	setState(Invited);
50
	return TQString( "MIME-Version: 1.0\r\n"
51
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
52
					"\r\n"
53
					"Application-Name: " + m_applicationName + "\r\n"
54
					"Application-GUID: {" + m_applicationId + "}\r\n"
55
					"Invitation-Command: INVITE\r\n"
56
					"Invitation-Cookie: " +TQString::number(m_cookie) +"\r\n");
57
}
58
59
TQCString MSNInvitation::rejectMessage(const TQString & rejectcode)
60
{
61
	return TQString( "MIME-Version: 1.0\r\n"
62
					"Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n"
63
					"\r\n"
64
					"Invitation-Command: CANCEL\r\n"
65
					"Invitation-Cookie: " + TQString::number(cookie()) + "\r\n"
66
					"Cancel-Code: "+ rejectcode +"\r\n").utf8();
67
}
68
69
void MSNInvitation::parseInvitation(const TQString& msg)
70
{
71
	TQRegExp rx("Invitation-Command: ([A-Z]*)");
72
	rx.search(msg);
73
	TQString command=rx.cap(1);
74
75
	if(command=="INVITE")
76
	{
77
		rx=TQRegExp("Invitation-Cookie: ([0-9]*)");
78
		rx.search(msg);
79
		m_cookie=rx.cap(1).toUInt();
80
	}
81
	else if(command=="CANCEL")
82
	{
83
		/*rx=TQRegExp("Cancel-Code: ([0-9]*)");
84
		rx.search(msg);
85
		TQString code=rx.cap(1).toUInt();
86
		//TODO: parse the code*/
87
	}
88
//	else if(command=="ACCEPT")
89
}
90
91
MSNInvitation::State MSNInvitation::state()
92
{
93
	return m_state;
94
}
95
96
void MSNInvitation::setState(MSNInvitation::State s)
97
{
98
	m_state=s;
99
}
100
(-)tdenetwork.ori/kopete/protocols/msn/msninvitation.h (-126 lines)
Lines 1-126 Link Here
1
/*
2
    msninvitation.cpp
3
4
    Copyright (c) 2003 by Olivier Goffart        <ogoffart @ kde.org>
5
6
    Kopete    (c) 2003 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
#ifndef MSNINVITATION_H
18
#define MSNINVITATION_H
19
20
#include <tqstring.h>
21
22
#include "kopete_export.h"
23
24
class TQObject;
25
26
/**
27
 * @author Olivier Goffart
28
 *
29
 * The invitation is the base class which handle an MSN invitation.
30
 * The implemented class must to herits from TQObject too.
31
 * You can accept the invitation by catching @ref MSNProtocol::invitation() signals
32
 * or create one and insert it to a kmm with @ref MSNChatSession::initInvitation()
33
 * you can add action with @ref Kopete::Plugin::customChatActions()
34
 */
35
class KOPETE_EXPORT MSNInvitation
36
{
37
public:
38
	/**
39
	 * Constructor
40
	 * @param incoming say if it is an incoming invitation
41
	 * @param applicationID is the exadecimal id of the invitation
42
	 * @param applicationName is a i18n'ed string of the name of the application
43
	 */
44
	MSNInvitation(bool incoming,const TQString &applicationID , const TQString &applicationName);
45
	virtual ~MSNInvitation();
46
47
	/**
48
	 * @internal
49
	 * it is a reject invitation because the invitation is not implemented
50
	 */
51
	static TQCString unimplemented(long unsigned int cookie);
52
53
	/**
54
	 * you can set manualy the cookie. note that a cookie is automatically generated when a new
55
	 * invitation is created, or in @ref parseInvitation
56
	 */
57
	void setCookie( long unsigned int c ) { m_cookie = c; }
58
	/**
59
	 * @return the cookie
60
	 */
61
	long unsigned int cookie() { return m_cookie; }
62
63
	/**
64
	 * @return true if it is an incommijng invitation
65
	 */
66
	bool incoming() { return m_incoming; }
67
68
69
	/**
70
	 * reimplement this. this is the invitation string used in @ref MSNChatSession::initInvitation()
71
	 * the default implementation return the common begin.
72
	 * You can also set the state to Invited (the default implementation do that)
73
	 */
74
	virtual TQString invitationHead();
75
76
	/**
77
	 * This is the reject invitation string
78
	 * @param rejectcode is the code, it can be "REJECT" or "TIMEOUT"
79
	 */
80
	TQCString rejectMessage(const TQString & rejectcode = "REJECT");
81
82
	/**
83
	 * reimplement this method. it is called when an invitation message with the invitation's cookie is received
84
	 * the default implementation parse the cookie, or the reject message
85
	 */
86
	virtual void parseInvitation(const TQString& invitation);
87
88
	/**
89
	 * return the qobject (this)
90
	 */
91
	virtual TQObject* object()=0;
92
//signals:
93
	/**
94
	 * reimplement this as a signal, and emit it when the invitation has to be destroyed.
95
	 * don't delete the invitation yourself
96
	 */
97
	virtual void done(MSNInvitation*)=0;
98
99
	/**
100
	 * This indiquate the state. it is going to be completed later
101
	 * - Nothing means than nothing has been done in the invitaiton (nothing has been sent/received)
102
	 * - Invited means than the invitaiton has been sent
103
	 */
104
	enum State { Nothing=0 , Invited=1 };
105
	/**
106
	 * retrun the current state
107
	 */
108
	State state();
109
	/**
110
	 * set the current State
111
	 */
112
	void setState(State);
113
114
115
116
protected:
117
	bool m_incoming;
118
	long unsigned int m_cookie;
119
	TQString m_applicationId;
120
	TQString m_applicationName;
121
	State m_state;
122
123
124
};
125
126
#endif
(-)tdenetwork.ori/kopete/protocols/msn/msnnotifysocket.cpp (-1309 lines)
Lines 1-1309 Link Here
1
/*
2
    msnnotifysocket.cpp - Notify Socket for the MSN Protocol
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
6
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
7
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
8
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
9
10
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
11
12
    Portions taken from
13
    KMerlin   (c) 2001      by Olaf Lueg              <olueg@olsd.de>
14
15
    *************************************************************************
16
    *                                                                       *
17
    * This program is free software; you can redistribute it and/or modify  *
18
    * it under the terms of the GNU General Public License as published by  *
19
    * the Free Software Foundation; either version 2 of the License, or     *
20
    * (at your option) any later version.                                   *
21
    *                                                                       *
22
    *************************************************************************
23
*/
24
25
#include "msnnotifysocket.h"
26
#include "msncontact.h"
27
#include "msnaccount.h"
28
#include "msnsecureloginhandler.h"
29
#include "msnchallengehandler.h"
30
31
#include <tqdatetime.h>
32
#include <tqregexp.h>
33
#include <tqdom.h>
34
35
#include <kdebug.h>
36
#include <tdeversion.h>
37
#include <tdelocale.h>
38
#include <kmdcodec.h>
39
#include <tdemessagebox.h>
40
#include <kstandarddirs.h>
41
#include <tdetempfile.h>
42
#include <krun.h>
43
#include <tdeio/job.h>
44
#include <tqfile.h>
45
#include <tdeconfig.h>
46
#include <knotification.h>
47
48
#include "kopeteuiglobal.h"
49
#include "kopeteglobal.h"
50
51
#include <ctime>
52
53
54
MSNNotifySocket::MSNNotifySocket( MSNAccount *account, const TQString& /*msnId*/, const TQString &password )
55
: MSNSocket( account )
56
{
57
	m_newstatus = MSNProtocol::protocol()->NLN;
58
	m_secureLoginHandler=0L;
59
	m_challengeHandler = 0L;
60
61
	m_isHotmailAccount=false;
62
	m_ping=false;
63
	m_disconnectReason=Kopete::Account::Unknown;
64
65
	m_account = account;
66
	m_password=password;
67
	TQObject::connect( this, TQT_SIGNAL( blockRead( const TQByteArray & ) ),
68
		this, TQT_SLOT( slotReadMessage( const TQByteArray & ) ) );
69
	m_keepaliveTimer = 0L;
70
	m_isLogged = false;
71
}
72
73
MSNNotifySocket::~MSNNotifySocket()
74
{
75
	delete m_secureLoginHandler;
76
	delete m_challengeHandler;
77
78
	kdDebug(14140) << k_funcinfo << endl;
79
}
80
81
void MSNNotifySocket::doneConnect()
82
{
83
//	kdDebug( 14140 ) << k_funcinfo << "Negotiating server protocol version" << endl;
84
	sendCommand( "VER", "MSNP11 MSNP10 CVR0" );
85
}
86
87
88
void MSNNotifySocket::disconnect()
89
{
90
	m_isLogged = false;
91
	if(	m_disconnectReason==Kopete::Account::Unknown )
92
		m_disconnectReason=Kopete::Account::Manual;
93
	if( onlineStatus() == Connected )
94
		sendCommand( "OUT", TQString(), false );
95
96
	if( m_keepaliveTimer )
97
		m_keepaliveTimer->stop();
98
99
	// the socket is not connected yet, so I should force the signals
100
	if ( onlineStatus() == Disconnected || onlineStatus() == Connecting )
101
		emit socketClosed();
102
	else
103
		MSNSocket::disconnect();
104
}
105
106
void MSNNotifySocket::handleError( uint code, uint id )
107
{
108
	kdDebug(14140) << k_funcinfo << endl;
109
110
	TQString handle;
111
	if(m_tmpHandles.contains(id))
112
		handle=m_tmpHandles[id];
113
114
	TQString msg;
115
	MSNSocket::ErrorType type;
116
	// See http://www.hypothetic.org/docs/msn/basics.php for a
117
	// description of all possible error codes.
118
	// TODO: Add support for all of these!
119
	switch( code )
120
	{
121
		case 201:
122
		case 205:
123
		case 208:
124
		{
125
			msg = i18n( "<qt>The MSN user '%1' does not exist.<br>Please check the MSN ID.</qt>" ).arg( handle );
126
			type = MSNSocket::ErrorServerError;
127
			break;
128
		}
129
		case 207:
130
		case 218:
131
		case 540:
132
		{
133
			msg = i18n( "<qt>An internal error occurred in the MSN plugin.<br>"
134
						"MSN Error: %1<br>"
135
						"please send us a detailed bug report "
136
						"at kopete-devel@kde.org containing the raw debug output on the "
137
						"console (in gzipped format, as it is probably a lot of output.)" ).arg(code);
138
			type = MSNSocket::ErrorServerError;
139
			break;
140
		}
141
		case 209:
142
		{
143
			if(handle==m_account->accountId())
144
			{
145
				msg = i18n( "Unable to change your display name.\n"
146
					"Please ensure your display is not too long and does not contains censored words." );
147
				type = MSNSocket::ErrorServerError;
148
			}
149
			/*else
150
			{
151
				TQString msg = i18n( "You are trying to change the display name of a user who has not "
152
					"confirmed his or her email address;\n"
153
					"the contact was not renamed on the server." );
154
				KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Error, msg, i18n( "MSN Plugin" ) );
155
			}*/
156
			break;
157
		}
158
		case 210:
159
		{
160
			msg = i18n("Your contact list is full; you cannot add any new contacts.");
161
			type = MSNSocket::ErrorServerError;
162
			break;
163
		}
164
		case 215:
165
		{
166
			msg = i18n( "<qt>The user '%1' already exists in this group on the MSN server;<br>"
167
				"if Kopete does not show the user, please send us a detailed bug report "
168
				"at kopete-devel@kde.org containing the raw debug output on the "
169
				"console (in gzipped format, as it is probably a lot of output.)</qt>" ).arg(handle);
170
			type = MSNSocket::ErrorInformation;
171
			break;
172
		}
173
		case 216:
174
		{
175
			//This might happen is you rename an user if he is not in the contactlist
176
			//currently, we just iniore;
177
			//TODO: try to don't rename user not in the list
178
			//actualy, the bug is in MSNChatSession::slotUserJoined()
179
			break;
180
		}	
181
		case 219:
182
		{
183
			msg = i18n( "The user '%1' seems to already be blocked or allowed on the server." ).arg(handle);
184
			type = MSNSocket::ErrorServerError;
185
			break;
186
		}
187
		case 223:
188
		{
189
			msg = i18n( "You have reached the maximum number of groups:\n"
190
				"MSN does not support more than 30 groups." );
191
			type = MSNSocket::ErrorServerError;
192
			break;
193
		}
194
		case 224:
195
		case 225:
196
		case 230:
197
		{
198
			msg = i18n("Kopete is trying to perform an operation on a group or a contact that does not exists on the server.\n"
199
				"This might happen if the Kopete contact list and the MSN-server contact list are not correctly synchronized; if this is the case, you probably should send a bug report.");
200
			type = MSNSocket::ErrorServerError;
201
			break;
202
		}
203
204
		case 229:
205
		{
206
			msg = i18n("The group name is too long; it has not been changed on the MSN server.");
207
			type = MSNSocket::ErrorServerError;
208
			break;
209
		}
210
		case 710:
211
		{
212
			msg = i18n( "You cannot open a Hotmail inbox because you do not have an MSN account with a valid "
213
				"Hotmail or MSN mailbox." );
214
			type = MSNSocket::ErrorServerError;
215
			break;
216
		}
217
		case 715:
218
		{
219
			/*
220
			//if(handlev==m_account->accountId())
221
			TQString msg = i18n( "Your email address has not been verified with the MSN server.\n"
222
				"You should have received a mail with a link to confirm your email address.\n"
223
				"Some functions will be restricted if you do not confirm your email address." );
224
			KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, msg, i18n( "MSN Plugin" ) );//TODO don't show again
225
			*/
226
			break;
227
		}
228
		case 800:
229
		{
230
			//This happen when too much commends are sent to the server.
231
			//the command will not be executed, too bad.
232
			// ignore it for now, as we don't really know what command it was.
233
	/*		TQString msg = i18#n( "You are trying to change your status, or your display name too rapidly.\n"
234
				"This might happen if you added yourself to your own contact list." );
235
			KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, msg, i18n( "MSN Plugin" ) );
236
			//FIXME: try to fix this problem*/
237
			break;
238
		}
239
		case 911:
240
			m_disconnectReason=Kopete::Account::BadPassword;
241
			disconnect();
242
			break;
243
		case 913:
244
		{
245
			msg = i18n( "You can not send messages when you are offline or when you are invisible." );
246
			type = MSNSocket::ErrorServerError;
247
			break;
248
		}
249
		case 923:
250
		{
251
			msg = i18n( "You are trying to perform an action you are not allowed to perform in 'kid mode'." );
252
			type = MSNSocket::ErrorServerError;
253
			break;
254
		}
255
	
256
		default:
257
			MSNSocket::handleError( code, id );
258
			break;
259
	}
260
261
	if( !msg.isEmpty() )
262
		emit errorMessage( type, msg );
263
}
264
265
void MSNNotifySocket::parseCommand( const TQString &cmd, uint id, const TQString &data )
266
{
267
	//kdDebug(14140) << "MSNNotifySocket::parseCommand: Command: " << cmd << endl;
268
269
	if ( cmd == "VER" )
270
	{
271
		sendCommand( "CVR", "0x0409 winnt 5.1 i386 MSNMSGR 7.0.0816 MSMSGS " + m_account->accountId() );
272
/*
273
		struct utsname utsBuf;
274
		uname ( &utsBuf );
275
276
		sendCommand( "CVR", i18n( "MS Local code, see http://www.microsoft.com/globaldev/reference/oslocversion.mspx", "0x0409" ) +
277
			" " + escape( utsBuf.sysname ) + " " + escape( utsBuf.release ) + " " + escape( utsBuf.machine ) + " Kopete " +
278
			escape( kapp->aboutData()->version() ) + " Kopete " + m_msnId );
279
*/
280
	}
281
	else if ( cmd == "CVR" ) //else if ( cmd == "INF" )
282
	{
283
		sendCommand( "USR", "TWN I " + m_account->accountId() );
284
	}
285
	else if( cmd == "USR" ) //// here follow the auth processus
286
	{
287
		if( data.section( ' ', 1, 1 ) == "S" )
288
		{
289
			m_secureLoginHandler = new MSNSecureLoginHandler(m_account->accountId(), m_password, data.section( ' ' , 2 , 2 ));
290
291
			TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginFailed()), this, TQT_SLOT(sslLoginFailed()));
292
			TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginBadPassword()), this, TQT_SLOT(sslLoginIncorrect()));
293
			TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginSuccesful(TQString )), this, TQT_SLOT(sslLoginSucceeded(TQString )));
294
295
			m_secureLoginHandler->login();
296
		}
297
		else
298
		{
299
			// Successful authentication.
300
			m_disconnectReason=Kopete::Account::Unknown;
301
302
			// Synchronize with the server.
303
			TQString lastSyncTime, lastChange;
304
305
			if(m_account->contacts().count() > 1)
306
			{
307
				// Retrieve the last synchronization timestamp, and last change timestamp.
308
				lastSyncTime = m_account->configGroup()->readEntry("lastsynctime", "0");
309
				lastChange = m_account->configGroup()->readEntry("lastchange", "0");
310
			}
311
			else
312
			{
313
				//the contactliust has maybe being removed, force to sync
314
				//(the only contact is myself)
315
				lastSyncTime="0";
316
				lastChange="0";
317
			}
318
319
			sendCommand( "SYN", lastChange + " " + lastSyncTime);
320
			// Get client features.
321
			if(!useHttpMethod()) {
322
				sendCommand( "GCF", "Shields.xml");
323
				// We are connected start to ping
324
				slotSendKeepAlive();
325
			}
326
		}
327
	}
328
	else if( cmd == "LST" )
329
	{
330
		// MSNP11 changed command. Now it's:
331
		// LST N=passport@hotmail.com F=Display%20Name C=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 13 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
332
		// But can be
333
		// LST N=passport@hotmail.com 10
334
		TQString publicName, contactGuid, groups;
335
		uint lists;
336
337
		TQRegExp regex("N=([^ ]+)(?: F=([^ ]+))?(?: C=([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}))? (\\d+)\\s?((?:[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12},?)*)$");
338
		regex.search(data);
339
340
		// Capture passport email.
341
		m_tmpLastHandle = regex.cap(1);
342
		// Capture public name.
343
		publicName = unescape( regex.cap(2) );
344
		// Capture contact guid.
345
		contactGuid = regex.cap(3);
346
		// Capture list enum type.
347
		lists = regex.cap(4).toUInt();
348
		// Capture contact group(s) guid(s)
349
		groups = regex.cap(5);
350
351
// 		kdDebug(14140) << k_funcinfo << " msnId: " << m_tmpLastHandle << " publicName: " << publicName << " contactGuid: " << contactGuid << " list: " << lists << " groupGuid: " << groups << endl;
352
353
		// handle, publicName, Contact GUID, lists, Group GUID
354
		emit contactList(  m_tmpLastHandle , publicName, contactGuid, lists, groups );
355
	}
356
	else if( cmd == "GCF" )
357
	{
358
		m_configFile = data.section(' ', 0, 0);
359
		readBlock( data.section( ' ', 1, 1 ).toUInt() );
360
	}
361
	else if( cmd == "MSG" )
362
	{
363
		readBlock( data.section( ' ', 2, 2 ).toUInt() );
364
	}
365
	else if( cmd == "ILN" ||  cmd == "NLN" )
366
	{
367
		// status handle publicName strangeNumber MSNOBJECT
368
		MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ data.section( ' ', 1, 1 ) ] );
369
		if( c && c->contactId() != m_account->accountId() )
370
		{
371
			TQString publicName=unescape( data.section( ' ', 2, 2 ) );
372
			if ( (publicName!=c->contactId() ||  c->hasProperty(Kopete::Global::Properties::self()->nickName().key())  ) &&
373
						 publicName!=c->property( Kopete::Global::Properties::self()->nickName()).value().toString() )
374
375
				changePublicName(publicName,c->contactId());
376
			TQString obj=unescape(data.section( ' ', 4, 4 ));
377
			c->setObject( obj );
378
			c->setOnlineStatus( convertOnlineStatus( data.section( ' ', 0, 0 ) ) );
379
			c->setClientFlags(data.section( ' ', 3, 3 ).toUInt());
380
		}
381
	}
382
	else if( cmd == "UBX" )
383
	{
384
		m_tmpLastHandle = data.section(' ', 0, 0);
385
		uint length = data.section( ' ', 1, 1 ).toUInt();
386
		if(length > 0) {
387
			readBlock( length );
388
		}
389
	}
390
	else if( cmd == "UUX" )
391
	{
392
		// UUX is sended to acknowledge that the server has received and processed the personal Message.
393
		// if the result is 0, set the myself() contact personalMessage.
394
		if( data.section(' ', 0, 0) == TQString::fromUtf8("0") )
395
			m_account->myself()->setProperty(MSNProtocol::protocol()->propPersonalMessage, m_propertyPersonalMessage);
396
	}
397
	else if( cmd == "FLN" )
398
	{
399
		MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ data.section( ' ', 0, 0 ) ] );
400
		if( c && c->contactId() != m_account->accountId() )
401
		{
402
			c->setOnlineStatus( MSNProtocol::protocol()->FLN );
403
			c->removeProperty(  MSNProtocol::protocol()->propClient );
404
		}
405
	}
406
	else if( cmd == "XFR" )
407
	{
408
		TQString stype=data.section( ' ', 0, 0 );
409
		if( stype=="SB" ) //switchboard connection (chat)
410
		{
411
			// Address, AuthInfo
412
			emit startChat( data.section( ' ', 1, 1 ), data.section( ' ', 3, 3 ) );
413
		}
414
		else if( stype=="NS" ) //notifysocket  ; Got our notification server
415
		{ //we are connecting and we receive the initial NS, or the msn server encounter a problem, and we are switching to another switchboard
416
			TQString host = data.section( ' ', 1, 1 );
417
			TQString server = host.section( ':', 0, 0 );
418
			uint port = host.section( ':', 1, 1 ).toUInt();
419
			setOnlineStatus( Connected );
420
			emit receivedNotificationServer( server, port );
421
			disconnect();
422
		}
423
424
	}
425
	else if( cmd == "RNG" )
426
	{
427
		// SessionID, Address, AuthInfo, handle, publicName
428
		emit invitedToChat( TQString::number( id ), data.section( ' ', 0, 0 ), data.section( ' ', 2, 2 ),
429
			data.section( ' ', 3, 3 ), unescape( data.section( ' ', 4, 4 ) ) );
430
	}
431
	else if( cmd == "ADC" )
432
	{
433
		TQString msnId, list, publicName, contactGuid, groupGuid;
434
435
		// Retrieve the list parameter (FL/AL/BL/RL)
436
		list = data.section( ' ', 0, 0 );
437
438
		// Examples of received data
439
		// ADC TrID xL N=example@passport.com
440
		// ADC TrID FL C=contactGuid groupdGuid
441
		// ADC TrID RL N=example@passport.com F=friednly%20name
442
		// ADC TrID FL N=ex@pas.com F=My%20Name C=contactGuid
443
		// Thanks Gregg for that complex RegExp.
444
		TQRegExp regex("(?:N=([^ ]+))?(?: F=([^ ]+))?(?: C=([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}))?\\s?((?:[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12},?)*)$");
445
		regex.search( data.section( ' ', 1 ) );
446
447
		// Capture passport email.
448
		msnId = regex.cap(1);
449
		// Capture public name.
450
		publicName = unescape( regex.cap(2) );
451
		// Capture contact guid.
452
		contactGuid = regex.cap(3);
453
		// Capture contact group(s) guid(s)
454
		groupGuid = regex.cap(4);
455
456
// 		kdDebug(14140) << k_funcinfo << list << " msnId: " << msnId << " publicName: " << publicName << " contactGuid: " << contactGuid << " groupGuid: " << groupGuid << endl;
457
458
		// handle, list, publicName, contactGuid, groupGuid
459
		emit contactAdded( msnId, list, publicName, contactGuid, groupGuid );
460
	}
461
	else if( cmd == "REM" ) // someone is removed from a list
462
	{
463
		TQString handle, list, contactGuid, groupGuid;
464
		list = data.section( ' ', 0, 0 );
465
		if( list  == "FL" )
466
		{
467
			// Removing a contact
468
		 	if( data.contains( ' ' ) < 2 )
469
			{
470
				contactGuid = data.section( ' ', 1, 1 );
471
			}
472
			// Removing a contact from a group
473
			else if( data.contains( ' ' ) < 3 )
474
			{
475
				contactGuid = data.section( ' ', 1, 1 );
476
				groupGuid = data.section( ' ', 2, 2 );
477
			}
478
		}
479
		else
480
		{
481
			handle = data.section( ' ', 1, 1);
482
		}
483
484
		// handle, list, contactGuid, groupGuid
485
		emit contactRemoved( handle, list, contactGuid, groupGuid );
486
487
	}
488
	else if( cmd == "OUT" )
489
	{
490
		if( data.section( ' ', 0, 0 ) == "OTH" )
491
		{
492
			m_disconnectReason=Kopete::Account::OtherClient;
493
		}
494
		disconnect();
495
	}
496
	else if( cmd == "CHG" )
497
	{
498
		TQString status = data.section( ' ', 0, 0 );
499
		setOnlineStatus( Connected );
500
		emit statusChanged( convertOnlineStatus( status ) );
501
	}
502
	else if( cmd == "SBP" )
503
	{
504
		TQString contactGuid, type, publicName;
505
		contactGuid = data.section( ' ', 0, 0 );
506
		type = data.section( ' ', 1, 1 );
507
		if(type == "MFN" )
508
		{
509
			publicName = unescape( data.section( ' ', 2, 2 ) );
510
			MSNContact *c = m_account->findContactByGuid( contactGuid );
511
			if(c != 0L)
512
			{
513
				c->setProperty( Kopete::Global::Properties::self()->nickName(), publicName );
514
			}
515
		}
516
	}
517
	else if( cmd == "LSG" )
518
	{
519
		// New Format: LSG Friends xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
520
		// groupDisplayName, groupGuid
521
		emit groupListed( unescape( data.section( ' ', 0, 0 ) ), data.section( ' ', 1, 1) );
522
	}
523
	else if( cmd == "ADG" )
524
	{
525
		// groupName, groupGuid
526
		emit groupAdded( unescape( data.section( ' ', 0, 0 ) ),
527
			data.section( ' ', 1, 1 ) );
528
	}
529
	else if( cmd == "REG" )
530
	{
531
		// groupGuid, groupName
532
		emit groupRenamed( data.section( ' ', 0, 0 ), unescape( data.section( ' ', 1, 1 ) ) );
533
	}
534
	else if( cmd == "RMG" )
535
	{
536
		// groupGuid
537
		emit groupRemoved( data.section( ' ', 1, 1 ) );
538
	}
539
	else if( cmd  == "CHL" )
540
	{
541
		m_challengeHandler = new MSNChallengeHandler("CFHUR$52U_{VIX5T", "PROD0101{0RM?UBW");
542
		// Compute the challenge response hash, and send the response.
543
		TQString chlResponse = m_challengeHandler->computeHash(data.section(' ', 0, 0));
544
		sendCommand("QRY", m_challengeHandler->productId(), true, chlResponse.utf8());
545
		// Dispose of the challenge handler.
546
		m_challengeHandler->deleteLater();
547
		m_challengeHandler = 0L;
548
	}
549
	else if( cmd == "SYN" )
550
	{
551
		// Retrieve the last synchronization timestamp known to the server.
552
		TQString lastSyncTime = data.section( ' ', 1, 1 );
553
		TQString lastChange   = data.section( ' ', 0, 0 );
554
		if( lastSyncTime != m_account->configGroup()->readEntry("lastsynctime") ||
555
			lastChange != m_account->configGroup()->readEntry("lastchange") )
556
		{
557
			// If the server timestamp and the local timestamp are different,
558
			// prepare to receive the contact list.
559
			emit newContactList();  // remove all contacts datas, msn sends a new contact list
560
			m_account->configGroup()->writeEntry( "lastsynctime" , lastSyncTime);
561
			m_account->configGroup()->writeEntry( "lastchange", lastChange);
562
		}else
563
			kdDebug(14140) << k_funcinfo << "Contact list up-to-date." << endl;
564
565
		// set the status
566
		setStatus( m_newstatus );
567
	}
568
	else if( cmd == "BPR" )
569
	{
570
		MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ m_tmpLastHandle ] );
571
		if( c )
572
			c->setInfo(data.section( ' ', 0, 0 ),unescape(data.section( ' ', 1, 1 )));
573
	}
574
	else if( cmd == "PRP" )
575
	{
576
		MSNContact *c = static_cast<MSNContact*>( m_account->myself() );
577
		if( c )
578
		{
579
			TQString type = data.section( ' ', 0, 0 );
580
			TQString prpData = unescape( data.section( ' ', 1, 1 ) ); //SECURITY????????
581
			c->setInfo( type, prpData );
582
			m_account->configGroup()->writeEntry( type, prpData );
583
		}
584
	}
585
	else if( cmd == "BLP" )
586
	{
587
		if( id > 0 ) //FROM BLP
588
		{
589
			m_account->configGroup()->writeEntry( "serial" , data.section( ' ', 0, 0 ) );
590
			m_account->configGroup()->writeEntry( "BLP" , data.section( ' ', 1, 1 ) );
591
		}
592
		else //FROM SYN
593
			m_account->configGroup()->writeEntry( "BLP" , data.section( ' ', 0, 0 ) );
594
	}
595
	else if( cmd == "QRY" )
596
	{
597
		// Do nothing
598
	}
599
	else if( cmd == "QNG" )
600
	{
601
		//this is a reply from a ping
602
		m_ping=false;
603
604
		// id is the timeout in fact, and we remove 5% of it
605
		if( m_keepaliveTimer )
606
			m_keepaliveTimer->start( id * 950, true );
607
		kdDebug( 14140 ) << k_funcinfo << "timerTimeout=" << id << "sec"<< endl;
608
	}
609
	else if( cmd == "URL" )
610
	{
611
		// URL 6 /cgi-bin/HoTMaiL https://loginnet.passport.com/ppsecure/md5auth.srf?lc=1033 2
612
		//example of reply: URL 10 /cgi-bin/HoTMaiL https://msnialogin.passport.com/ppsecure/md5auth.srf?lc=1036 3
613
		TQString from_action_url = data.section( ' ', 1, 1 );
614
		TQString rru = data.section( ' ', 0, 0 );
615
		TQString id = data.section( ' ', 2, 2 );
616
617
		//write the tmp file
618
		TQString UserID=m_account->accountId();
619
620
		time_t actualTime;
621
		time(&actualTime);
622
		TQString sl = TQString::number( ( unsigned long ) actualTime - m_loginTime.toULong() );
623
624
		TQString md5this( m_MSPAuth + sl + m_password );
625
		KMD5 md5( md5this.utf8() );
626
627
		TQString hotmailRequest = "<html>\n"
628
			"<head>\n"
629
				"<noscript>\n"
630
					"<meta http-equiv=Refresh content=\"0; url=http://www.hotmail.com\">\n"
631
				"</noscript>\n"
632
			"</head>\n"
633
			"<body onload=\"document.pform.submit(); \">\n"
634
				"<form name=\"pform\" action=\"" + from_action_url  + "\" method=\"POST\">\n"
635
					"<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n"
636
					"<input type=\"hidden\" name=\"login\" value=\"" + UserID.left( UserID.find('@') ) + "\">\n"
637
					"<input type=\"hidden\" name=\"username\" value=\"" + UserID + "\">\n"
638
					"<input type=\"hidden\" name=\"sid\" value=\"" + m_sid + "\">\n"
639
					"<input type=\"hidden\" name=\"kv\" value=\"" + m_kv + "\">\n"
640
					"<input type=\"hidden\" name=\"id\" value=\""+ id +"\">\n"
641
					"<input type=\"hidden\" name=\"sl\" value=\"" + sl +"\">\n"
642
					"<input type=\"hidden\" name=\"rru\" value=\"" + rru + "\">\n"
643
					"<input type=\"hidden\" name=\"auth\" value=\"" + m_MSPAuth + "\">\n"
644
					"<input type=\"hidden\" name=\"creds\" value=\"" + TQString::fromLatin1( md5.hexDigest() ) + "\">\n"
645
					"<input type=\"hidden\" name=\"svc\" value=\"mail\">\n"
646
					"<input type=\"hidden\" name=\"js\" value=\"yes\">\n"
647
				"</form></body>\n</html>\n";
648
649
		KTempFile tmpMailFile( locateLocal( "tmp", "kopetehotmail-" ), ".html" );
650
		*tmpMailFile.textStream() << hotmailRequest;
651
		tmpMailFile.file()->flush();
652
653
		KRun::runURL( KURL::fromPathOrURL( tmpMailFile.name() ), "text/html" , true );
654
655
	}
656
	else if ( cmd == "NOT" )
657
	{
658
		kdDebug( 14140 ) << k_funcinfo << "Received NOT command, issueing read block for '" << id << " more bytes" << endl;
659
		readBlock( id );		
660
	}	
661
	else
662
	{
663
		// Let the base class handle the rest
664
		//MSNSocket::parseCommand( cmd, id, data );
665
		kdDebug( 14140 ) << k_funcinfo << "Unimplemented command '" << cmd << " " << id << " " << data << "' from server!" << endl;
666
	}
667
}
668
669
670
void MSNNotifySocket::sslLoginFailed()
671
{
672
	m_disconnectReason=Kopete::Account::InvalidHost;
673
	disconnect();
674
}
675
676
void MSNNotifySocket::sslLoginIncorrect()
677
{
678
	m_disconnectReason=Kopete::Account::BadPassword;
679
	disconnect();
680
}
681
682
void MSNNotifySocket::sslLoginSucceeded(TQString ticket)
683
{
684
	sendCommand("USR" , "TWN S " + ticket);
685
686
	m_secureLoginHandler->deleteLater();
687
	m_secureLoginHandler = 0L;
688
}
689
690
void MSNNotifySocket::slotMSNAlertUnwanted()
691
{
692
	// user not interested .. clean up the list of actions
693
	m_msnAlertURLs.clear();
694
}
695
696
void MSNNotifySocket::slotMSNAlertLink(unsigned int action)
697
{
698
	// index into our action list and pull out the URL that was clicked ..
699
	KURL tempURLForLaunch(m_msnAlertURLs[action-1]);
700
	
701
	KRun* urlToRun = new KRun(tempURLForLaunch);
702
}
703
704
void MSNNotifySocket::slotOpenInbox()
705
{
706
	sendCommand("URL", "INBOX" );
707
}
708
709
void MSNNotifySocket::sendMail(const TQString &email)
710
{
711
	sendCommand("URL", TQString("COMPOSE " + email).utf8() );
712
}
713
714
bool MSNNotifySocket::setUseHttpMethod(bool useHttp)
715
{
716
	bool ret = MSNSocket::setUseHttpMethod( useHttp );
717
718
	if( useHttpMethod() ) {
719
		if( m_keepaliveTimer ) {
720
			delete m_keepaliveTimer;
721
			m_keepaliveTimer = 0L;
722
		}
723
	}
724
	else {
725
		if( !m_keepaliveTimer ) {
726
			m_keepaliveTimer = new TQTimer( this, "m_keepaliveTimer" );
727
			TQObject::connect( m_keepaliveTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotSendKeepAlive() ) );
728
		}
729
	}
730
731
	return ret;
732
}
733
734
void MSNNotifySocket::slotReadMessage( const TQByteArray &bytes )
735
{
736
	TQString msg = TQString::fromUtf8(bytes, bytes.size());
737
738
	if(msg.contains("text/x-msmsgsinitialmdatanotification"))
739
	{
740
		//Mail-Data: <MD><E><I>301</I><IU>1</IU><O>4</O><OU>2</OU></E><Q><TQTM>409600</TQTM><TQNM>204800</TQNM></Q></MD>
741
		// MD - Mail Data
742
		// E  - email
743
		// I  - initial mail
744
		// IU - initial unread
745
		// O  - other mail
746
		// OU - other unread.
747
		TQRegExp regex("<MD><E><I>(\\d+)?</I>(?:<IU>(\\d+)?</IU>)<O>(\\d+)?</O><OU>(\\d+)?</OU></E><Q>.*</Q></MD>");
748
		regex.search(msg);
749
750
		bool unread;
751
		// Retrieve the number of unread email messages.
752
		mailCount = regex.cap(2).toUInt(&unread);
753
		if(unread && mailCount > 0)
754
		{
755
			// If there are new email message available, raise the unread email event.
756
			TQObject::connect(KNotification::event( "msn_mail", i18n( "You have one unread message in your MSN inbox.",
757
					"You have %n unread messages in your MSN inbox.", mailCount ), 0 , 0 , i18n( "Open Inbox..." ) ),
758
				TQT_SIGNAL(activated(unsigned int ) ) , this, TQT_SLOT( slotOpenInbox() ) );
759
		}
760
	}
761
	else if(msg.contains("text/x-msmsgsactivemailnotification"))
762
	{
763
		 //this sends the server if mails are deleted
764
		 TQString m = msg.right(msg.length() - msg.find("Message-Delta:") );
765
		 m = m.left(msg.find("\r\n"));
766
		 mailCount = mailCount - m.right(m.length() -m.find(" ")-1).toUInt();
767
	}
768
	else if(msg.contains("text/x-msmsgsemailnotification"))
769
	{
770
		 //this sends the server if a new mail has arrived
771
		TQRegExp rx("From-Addr: ([A-Za-z0-9@._\\-]*)");
772
		rx.search(msg);
773
		TQString m=rx.cap(1);
774
775
		mailCount++;
776
777
		//TODO:  it is also possible to get the subject  (but warning about the encoding)
778
		TQObject::connect(KNotification::event( "msn_mail",i18n( "You have one new email from %1 in your MSN inbox." ).arg(m),
779
										0 , 0 , i18n( "Open Inbox..." ) ),
780
				TQT_SIGNAL(activated(unsigned int ) ) , this, TQT_SLOT( slotOpenInbox() ) );
781
	}
782
	else if(msg.contains("text/x-msmsgsprofile"))
783
	{
784
		//Hotmail profile
785
		if(msg.contains("MSPAuth:"))
786
		{
787
			TQRegExp rx("MSPAuth: ([A-Za-z0-9$!*]*)");
788
			rx.search(msg);
789
			m_MSPAuth=rx.cap(1);
790
		}
791
		if(msg.contains("sid:"))
792
		{
793
			TQRegExp rx("sid: ([0-9]*)");
794
			rx.search(msg);
795
			m_sid=rx.cap(1);
796
		}
797
		if(msg.contains("kv:"))
798
		{
799
			TQRegExp rx("kv: ([0-9]*)");
800
			rx.search(msg);
801
			m_kv=rx.cap(1);
802
		}
803
		if(msg.contains("LoginTime:"))
804
		{
805
			TQRegExp rx("LoginTime: ([0-9]*)");
806
			rx.search(msg);
807
			m_loginTime=rx.cap(1);
808
		}
809
			else //IN MSNP9  there are no logintime it seems, so set it manualy
810
			{
811
				time_t actualTime;
812
				time(&actualTime);
813
				m_loginTime=TQString::number((unsigned long)actualTime);
814
			}
815
		if(msg.contains("EmailEnabled:"))
816
		{
817
			TQRegExp rx("EmailEnabled: ([0-9]*)");
818
			rx.search(msg);
819
			m_isHotmailAccount = (rx.cap(1).toUInt() == 1);
820
			emit hotmailSeted(m_isHotmailAccount);
821
		}
822
		if(msg.contains("ClientIP:"))
823
		{
824
			TQRegExp rx("ClientIP: ([0-9.]*)");
825
			rx.search(msg);
826
			m_localIP = rx.cap(1);
827
		}
828
829
		// We are logged when we receive the initial profile from Hotmail.
830
		m_isLogged = true;
831
	}
832
	else if (msg.contains("NOTIFICATION"))
833
	{
834
		// MSN alert (i.e. NOTIFICATION) [for docs see http://www.hypothetic.org/docs/msn/client/notification.php]
835
		// format of msg is as follows:
836
		//
837
		// <NOTIFICATION ver="2" id="1342902633" siteid="199999999" siteurl="http://alerts.msn.com">
838
		// <TO pid="0x0006BFFD:0x8582C0FB" name="example@passport.com"/>
839
		// <MSG pri="1" id="1342902633">
840
		// 	<SUBSCR url="http://g.msn.com/3ALMSNTRACKING/199999999ToastChange?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1"/>
841
		// 	<ACTION url="http://g.msn.com/3ALMSNTRACKING/199999999ToastAction?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1"/>
842
		// 	<BODY lang="3076" icon="">
843
		// 		<TEXT>utf8-encoded text</TEXT>
844
		//	</BODY>
845
		// </MSG>
846
		// </NOTIFICATION>
847
848
		// MSN sends out badly formed XML .. fix it for them (thanks MS!)
849
		TQString notificationDOMAsString(msg);
850
851
		TQRegExp rx( "&(?!amp;)" );      // match ampersands but not &amp;
852
		notificationDOMAsString.replace(rx, "&amp;");
853
		TQDomDocument alertDOM;
854
		alertDOM.setContent(notificationDOMAsString);
855
856
		TQDomNodeList msgElements = alertDOM.elementsByTagName("MSG");
857
		for (uint i = 0 ; i < msgElements.count() ; i++)
858
		{
859
			TQString subscString;
860
			TQString actionString;
861
			TQString textString;
862
863
			TQDomNode msgDOM = msgElements.item(i);
864
865
			TQDomNodeList msgChildren = msgDOM.childNodes();
866
			for (uint i = 0 ; i < msgChildren.length() ; i++) {
867
				TQDomNode child = msgChildren.item(i);
868
				TQDomElement element = child.toElement();
869
				if (element.tagName() == "SUBSCR")
870
				{
871
					TQDomAttr subscElementURLAttribute;
872
					if (element.hasAttribute("url"))
873
					{
874
						subscElementURLAttribute = element.attributeNode("url");
875
						subscString = subscElementURLAttribute.value();
876
					}
877
				}
878
				else if (element.tagName() == "ACTION")
879
				{
880
					// process ACTION node to pull out URL the alert is tied to
881
					TQDomAttr actionElementURLAttribute;
882
					if (element.hasAttribute("url"))
883
					{
884
						actionElementURLAttribute = element.attributeNode("url");
885
						actionString = actionElementURLAttribute.value();
886
					}
887
				}
888
				else if (element.tagName() == "BODY")
889
				{
890
					// process BODY node to get the text of the alert
891
					TQDomNodeList textElements = element.elementsByTagName("TEXT");
892
					if (textElements.count() >= 1)
893
					{
894
						TQDomElement textElement = textElements.item(0).toElement();
895
						textString = textElement.text();
896
					}
897
				}
898
899
900
			}
901
902
//			kdDebug( 14140 ) << "subscString " << subscString << " actionString " << actionString << " textString " << textString << endl;
903
			// build an internal list of actions ... we'll need to index into this list when we receive an event
904
			TQStringList actions;
905
			actions.append(i18n("More Information"));
906
			m_msnAlertURLs.append(actionString);
907
908
			actions.append(i18n("Manage Subscription"));
909
			m_msnAlertURLs.append(subscString);
910
911
			// Don't do any MSN alerts notification for new blog updates
912
			if( subscString != TQString::fromLatin1("s.htm") && actionString != TQString::fromLatin1("a.htm") )
913
			{
914
				KNotification* notification = KNotification::event("msn_alert", textString, 0L, 0L, actions);
915
				TQObject::connect(notification, TQT_SIGNAL(activated(unsigned int)), this, TQT_SLOT(slotMSNAlertLink(unsigned int)));
916
				TQObject::connect(notification, TQT_SIGNAL(closed()), this, TQT_SLOT(slotMSNAlertUnwanted()));
917
			}
918
		} // end for each MSG tag
919
	}
920
921
	if(!m_configFile.isNull())
922
	{
923
		// TODO Get client features.
924
	}
925
926
	if(!m_tmpLastHandle.isNull())
927
	{
928
		TQString personalMessage, currentMedia;
929
		TQDomDocument psm;
930
		if( psm.setContent(msg) )
931
		{
932
			// Get the first child of the xml "document";
933
			TQDomElement psmElement = psm.documentElement().firstChild().toElement();
934
935
			while( !psmElement.isNull() )
936
			{
937
				if(psmElement.tagName() == TQString::fromUtf8("PSM"))
938
				{
939
					personalMessage = psmElement.text();
940
					kdDebug(14140) << k_funcinfo << "Personnal Message received: " << personalMessage << endl;
941
				}
942
				else if(psmElement.tagName() == TQString::fromUtf8("CurrentMedia"))
943
				{
944
					if( !psmElement.text().isEmpty() )
945
					{
946
						kdDebug(14140) << k_funcinfo << "XML CurrentMedia: " << psmElement.text() << endl;
947
						currentMedia = processCurrentMedia( psmElement.text() );
948
					}
949
				}
950
				psmElement = psmElement.nextSibling().toElement();
951
			}
952
953
			MSNContact *contact = static_cast<MSNContact*>(m_account->contacts()[ m_tmpLastHandle ]);
954
			if(contact)
955
			{
956
				contact->setProperty(MSNProtocol::protocol()->propPersonalMessage, currentMedia.isEmpty() ? personalMessage : currentMedia);
957
			}
958
		}
959
		m_tmpLastHandle = TQString();
960
	}
961
}
962
963
TQString MSNNotifySocket::processCurrentMedia( const TQString &mediaXmlElement )
964
{
965
	/*
966
		The value of the CurrentMedia tag you can think of like an array
967
		seperated by "\0" characters (literal backslash followed by zero, not NULL).
968
969
		The elements of this "array" are as follows:
970
971
		* Application - This is the app you are using. Usually empty
972
		* Type - This is the type of PSM, either “Music”, “Games” or “Office”
973
		* Enabled - This is a boolean value (0/1) to enable/disable
974
		* Format - A formatter string ala .Net; For example, “{0} - {1}”
975
		* First line - The first line (Matches {0} in the Format)
976
		* Second line - The second line (Matches {1} in the Format)
977
		* Third line - The third line (Matches {2} in the Format)
978
979
		There is probably no limit to the number of lines unless you go over the maximum length of the tag.
980
981
		Example of currentMedia xml tag:
982
		<CurrentMedia>\0Music\01\0{0} - {1}\0 Song Title\0Song Artist\0Song Album\0\0</CurrentMedia>
983
		<CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia>
984
		<CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia>
985
986
		From http://msnpiki.msnfanatic.com/index.php/MSNP11:Changes
987
	*/
988
	TQString application, type, format, currentMedia;
989
	bool enabled=false, test;
990
	// \0 is textual, it's the "array" separator.
991
	TQStringList argumentLists = TQStringList::split(TQString::fromUtf8("\\0"), mediaXmlElement, true);
992
993
	// Retrive the "stable" array elements.
994
	application = argumentLists[0];
995
	type = argumentLists[1];
996
	enabled = argumentLists[2].toInt(&test);
997
	format = argumentLists[3];
998
999
	// Get the formatter strings
1000
	TQStringList formatterStrings;
1001
	TQStringList::ConstIterator it;
1002
	for( it = argumentLists.at(4); it != argumentLists.end(); ++it )
1003
	{
1004
		formatterStrings.append( *it );
1005
	}
1006
1007
	// Replace the formatter in the format string.
1008
	currentMedia = format;
1009
	for(uint i=0; i<formatterStrings.size(); i++)
1010
	{
1011
		currentMedia = currentMedia.replace(TQString("{%1}").arg(i), formatterStrings[i]);
1012
	}
1013
1014
	if( type == TQString::fromUtf8("Music") )
1015
	{
1016
		// the  "♫" is encoded in utf8 (and should be in utf8)
1017
		currentMedia = i18n("Now Listening: ♫ %1 ♫").arg(currentMedia);
1018
	}
1019
1020
	kdDebug(1414) << "Current Media received: " << currentMedia << endl;
1021
1022
	return currentMedia;
1023
}
1024
1025
void MSNNotifySocket::addGroup(const TQString& groupName)
1026
{
1027
	// escape spaces
1028
	sendCommand( "ADG", escape( groupName ) );
1029
}
1030
1031
void MSNNotifySocket::renameGroup( const TQString& groupName, const TQString& groupGuid )
1032
{
1033
	// escape spaces
1034
	sendCommand( "REG", groupGuid + " " + escape( groupName ) );
1035
}
1036
1037
void MSNNotifySocket::removeGroup( const TQString& groupGuid )
1038
{
1039
	sendCommand( "RMG",  groupGuid );
1040
}
1041
1042
void MSNNotifySocket::addContact( const TQString &handle, int list, const TQString& publicName, const TQString& contactGuid, const TQString& groupGuid )
1043
{
1044
	TQString args;
1045
	switch( list )
1046
	{
1047
		case MSNProtocol::FL:
1048
		{
1049
			// Adding the contact to a group
1050
			if( !contactGuid.isEmpty() )
1051
			{
1052
				args = TQString("FL C=%1 %2").arg( contactGuid ).arg( groupGuid );
1053
				kdDebug(14140) << k_funcinfo << "In adding contact to a group" << endl;
1054
			}
1055
			// Adding a new contact
1056
			else
1057
			{
1058
				args = TQString("FL N=%1 F=%2").arg( handle ).arg( escape( publicName ) );
1059
				kdDebug(14140) << k_funcinfo << "In adding contact to a new contact" << endl;
1060
			}
1061
			break;
1062
		}
1063
		case MSNProtocol::AL:
1064
			args = TQString("AL N=%1").arg( handle );
1065
			break;
1066
		case MSNProtocol::BL:
1067
			args = TQString("BL N=%1").arg( handle );
1068
			break;
1069
		case MSNProtocol::RL:
1070
			args = TQString("RL N=%1").arg( handle );
1071
			break;
1072
		default:
1073
			kdDebug(14140) << k_funcinfo <<"WARNING! Unknown list " << list << "!" << endl;
1074
			return;
1075
	}
1076
	unsigned int id=sendCommand( "ADC", args );
1077
	m_tmpHandles[id]=handle;
1078
}
1079
1080
void MSNNotifySocket::removeContact( const TQString &handle, int list, const TQString& contactGuid, const TQString& groupGuid )
1081
{
1082
	TQString args;
1083
	switch( list )
1084
	{
1085
	case MSNProtocol::FL:
1086
		args = "FL " + contactGuid;
1087
		// Removing a contact from a group
1088
		if( !groupGuid.isEmpty() )
1089
			args += " " + groupGuid;
1090
		break;
1091
	case MSNProtocol::AL:
1092
		args = "AL " + handle;
1093
		break;
1094
	case MSNProtocol::BL:
1095
		args = "BL " + handle;
1096
		break;
1097
	case MSNProtocol::PL:
1098
		args = "PL " + handle;
1099
		break;
1100
	default:
1101
		kdDebug(14140) <<k_funcinfo  << "WARNING! Unknown list " << list << "!" << endl;
1102
		return;
1103
	}
1104
	unsigned int id=sendCommand( "REM", args );
1105
	m_tmpHandles[id]=handle;
1106
}
1107
1108
void MSNNotifySocket::setStatus( const Kopete::OnlineStatus &status )
1109
{
1110
//	kdDebug( 14140 ) << k_funcinfo << statusToString( status ) << endl;
1111
1112
	if( onlineStatus() == Disconnected )
1113
		m_newstatus = status;
1114
	else
1115
		sendCommand( "CHG", statusToString( status ) + " " + m_account->myselfClientId() + " " + escape(m_account->pictureObject()) );
1116
}
1117
1118
void MSNNotifySocket::changePublicName( const TQString &publicName, const TQString &handle )
1119
{
1120
	TQString tempPublicName = publicName;
1121
1122
	//The maximum length is 387.  but with utf8 or encodage, each character may be triple
1123
	//  387/3 = 129   so we make sure the length is not longer than 129 char,  even if
1124
	// it's possible to have longer nicks.
1125
	if( escape(publicName).length() > 129 )
1126
	{
1127
		tempPublicName = publicName.left(129);
1128
	}
1129
1130
	if( handle.isNull() )
1131
	{
1132
		unsigned int id = sendCommand( "PRP", "MFN " + escape( tempPublicName ) );
1133
		m_tmpHandles[id] = m_account->accountId();
1134
	}
1135
	else
1136
	{
1137
		MSNContact *currentContact = static_cast<MSNContact *>(m_account->contacts()[handle]);
1138
		if(currentContact && !currentContact->guid().isEmpty() )
1139
		{
1140
			// FIXME if there is not guid server disconnects.
1141
			unsigned int id = sendCommand( "SBP", currentContact->guid() + " MFN " + escape( tempPublicName ) );
1142
			m_tmpHandles[id] = handle;
1143
		}
1144
	}
1145
}
1146
1147
void MSNNotifySocket::changePersonalMessage( MSNProtocol::PersonalMessageType type, const TQString &personalMessage )
1148
{
1149
	TQString tempPersonalMessage;
1150
	TQString xmlCurrentMedia;
1151
1152
	// Only espace and cut the personalMessage is the type is normal.
1153
	if(type == MSNProtocol::PersonalMessageNormal)
1154
	{
1155
		tempPersonalMessage = personalMessage;
1156
		//Magic number : 129 characters
1157
		if( escape(personalMessage).length() > 129 )
1158
		{
1159
			// We cut. for now.
1160
			tempPersonalMessage = personalMessage.left(129);
1161
		}
1162
	}
1163
1164
	TQDomDocument xmlMessage;
1165
	xmlMessage.appendChild( xmlMessage.createElement( "Data" ) );
1166
1167
	TQDomElement psm = xmlMessage.createElement("PSM");
1168
	psm.appendChild( xmlMessage.createTextNode( tempPersonalMessage ) );
1169
	xmlMessage.documentElement().appendChild( psm );
1170
1171
	TQDomElement currentMedia = xmlMessage.createElement("CurrentMedia");
1172
1173
	/* Example of currentMedia xml tag:
1174
		<CurrentMedia>\0Music\01\0{0} - {1}\0 Song Title\0Song Artist\0Song Album\0\0</CurrentMedia>
1175
		<CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia>
1176
		<CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia>
1177
	*/
1178
	switch(type)
1179
	{
1180
		case MSNProtocol::PersonalMessageMusic:
1181
		{
1182
			xmlCurrentMedia = "\\0Music\\01\\0";
1183
			TQStringList mediaList = TQStringList::split(";", personalMessage);
1184
			TQString formatterArguments;
1185
			if( !mediaList[0].isEmpty() ) // Current Track
1186
			{
1187
				xmlCurrentMedia += "{0}";
1188
				formatterArguments += TQString("%1\\0").arg(mediaList[0]);
1189
			}
1190
			if( !mediaList[1].isEmpty() ) // Current Artist
1191
			{
1192
				xmlCurrentMedia += " - {1}";
1193
				formatterArguments += TQString("%1\\0").arg(mediaList[1]);
1194
			}
1195
			if( !mediaList[2].isEmpty() ) // Current Album
1196
			{
1197
				xmlCurrentMedia += " ({2})";
1198
				formatterArguments += TQString("%1\\0").arg(mediaList[2]);
1199
			}
1200
			xmlCurrentMedia += "\\0" + formatterArguments + "\\0";
1201
			break;
1202
		}
1203
		default:
1204
			break;
1205
	}
1206
1207
	currentMedia.appendChild( xmlMessage.createTextNode( xmlCurrentMedia ) );
1208
1209
	// Set the status message for myself, check if currentMedia is empty, for either using the normal or Music personal
1210
	m_propertyPersonalMessage = xmlCurrentMedia.isEmpty() ? tempPersonalMessage : processCurrentMedia( currentMedia.text() );
1211
1212
	xmlMessage.documentElement().appendChild( currentMedia );
1213
1214
	unsigned int id = sendCommand("UUX","",true, xmlMessage.toString().utf8(), false);
1215
	m_tmpHandles[id] = m_account->accountId();
1216
1217
}
1218
1219
void MSNNotifySocket::changePhoneNumber( const TQString &key, const TQString &data )
1220
{
1221
	sendCommand( "PRP", key + " " + escape ( data ) );
1222
}
1223
1224
1225
void MSNNotifySocket::createChatSession()
1226
{
1227
	sendCommand( "XFR", "SB" );
1228
}
1229
1230
TQString MSNNotifySocket::statusToString( const Kopete::OnlineStatus &status ) const
1231
{
1232
	if( status == MSNProtocol::protocol()->NLN )
1233
		return "NLN";
1234
	else if( status == MSNProtocol::protocol()->BSY )
1235
		return "BSY";
1236
	else if( status == MSNProtocol::protocol()->BRB )
1237
		return "BRB";
1238
	else if( status == MSNProtocol::protocol()->AWY )
1239
		return "AWY";
1240
	else if( status == MSNProtocol::protocol()->PHN )
1241
		return "PHN";
1242
	else if( status == MSNProtocol::protocol()->LUN )
1243
		return "LUN";
1244
	else if( status == MSNProtocol::protocol()->FLN )
1245
		return "FLN";
1246
	else if( status == MSNProtocol::protocol()->HDN )
1247
		return "HDN";
1248
	else if( status == MSNProtocol::protocol()->IDL )
1249
		return "IDL";
1250
	else
1251
	{
1252
		kdWarning( 14140 ) << k_funcinfo << "Unknown status " << status.internalStatus() << "!" << endl;
1253
		return "UNK";
1254
	}
1255
}
1256
1257
void MSNNotifySocket::slotSendKeepAlive()
1258
{
1259
	//we did not received the previous TQNG
1260
	if(m_ping)
1261
	{
1262
		m_disconnectReason=Kopete::Account::ConnectionReset;
1263
		disconnect();
1264
		/*KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Information,
1265
		i18n( "The connection with the MSN network has been lost." ) , i18n ("MSN Plugin") );*/
1266
		return;
1267
	}
1268
	else
1269
	{
1270
		// Send a dummy command to fake activity. This makes sure MSN doesn't
1271
		// disconnect you when the notify socket is idle.
1272
		sendCommand( "PNG" , TQString() , false );
1273
		m_ping=true;
1274
	}
1275
1276
	//at least 90 second has been ellapsed since the last messages
1277
	// we shouldn't receive error from theses command anymore
1278
	m_tmpHandles.clear();
1279
}
1280
1281
Kopete::OnlineStatus MSNNotifySocket::convertOnlineStatus( const TQString &status )
1282
{
1283
	if( status == "NLN" )
1284
		return MSNProtocol::protocol()->NLN;
1285
	else if( status == "FLN" )
1286
		return MSNProtocol::protocol()->FLN;
1287
	else if( status == "HDN" )
1288
		return MSNProtocol::protocol()->HDN;
1289
	else if( status == "PHN" )
1290
		return MSNProtocol::protocol()->PHN;
1291
	else if( status == "LUN" )
1292
		return MSNProtocol::protocol()->LUN;
1293
	else if( status == "BRB" )
1294
		return MSNProtocol::protocol()->BRB;
1295
	else if( status == "AWY" )
1296
		return MSNProtocol::protocol()->AWY;
1297
	else if( status == "BSY" )
1298
		return MSNProtocol::protocol()->BSY;
1299
	else if( status == "IDL" )
1300
		return MSNProtocol::protocol()->IDL;
1301
	else
1302
		return MSNProtocol::protocol()->UNK;
1303
}
1304
1305
1306
#include "msnnotifysocket.moc"
1307
1308
// vim: set noet ts=4 sts=4 sw=4:
1309
(-)tdenetwork.ori/kopete/protocols/msn/msnnotifysocket.h (-217 lines)
Lines 1-217 Link Here
1
/*
2
    msnnotifysocket.h - Notify Socket for the MSN Protocol
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
6
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
7
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
8
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
9
10
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
11
12
    Portions taken from
13
    KMerlin   (c) 2001      by Olaf Lueg              <olueg@olsd.de>
14
15
    *************************************************************************
16
    *                                                                       *
17
    * This program is free software; you can redistribute it and/or modify  *
18
    * it under the terms of the GNU General Public License as published by  *
19
    * the Free Software Foundation; either version 2 of the License, or     *
20
    * (at your option) any later version.                                   *
21
    *                                                                       *
22
    *************************************************************************
23
*/
24
25
#ifndef MSNNOTIFYSOCKET_H
26
#define MSNNOTIFYSOCKET_H
27
28
#include "msnsocket.h"
29
#include "msnprotocol.h"
30
31
32
class MSNDispatchSocket;
33
class MSNAccount;
34
class KTempFile;
35
class MSNSecureLoginHandler;
36
class MSNChallengeHandler;
37
38
/**
39
 * @author Olaf Lueg
40
 * @author Olivier Goffart
41
 */
42
class MSNNotifySocket : public MSNSocket
43
{
44
	Q_OBJECT
45
  
46
47
public:
48
	MSNNotifySocket( MSNAccount* account, const TQString &msnId, const TQString &password );
49
	~MSNNotifySocket();
50
51
	virtual void disconnect();
52
53
	void setStatus( const Kopete::OnlineStatus &status );
54
	void addContact( const TQString &handle, int list, const TQString& publicName, const TQString& contactGuid, const TQString& groupGuid );
55
	void removeContact( const TQString &handle, int list, const TQString &contactGuid, const TQString &groupGuid );
56
57
	void addGroup( const TQString& groupName );
58
	void removeGroup( const TQString& group );
59
	void renameGroup( const TQString& groupName, const TQString& groupGuid );
60
61
	void changePublicName( const TQString& publicName , const TQString &handle=TQString() );
62
	void changePersonalMessage( MSNProtocol::PersonalMessageType type , const TQString& personalMessage );
63
64
	void changePhoneNumber( const TQString &key, const TQString &data );
65
66
	void createChatSession();
67
68
	void sendMail(const TQString &email);
69
70
	/**
71
	 * this should return a  Kopete::Account::DisconnectReason value
72
	 */
73
	int  disconnectReason() { return m_disconnectReason; }
74
75
	TQString localIP() { return m_localIP; }
76
77
	bool setUseHttpMethod( bool useHttpMethod );
78
79
	bool isLogged() const { return m_isLogged; }
80
81
public slots:
82
	void slotOpenInbox();
83
	void slotMSNAlertLink(unsigned int action);
84
	void slotMSNAlertUnwanted();
85
86
signals:
87
	void newContactList();
88
	void contactList(const TQString& handle, const TQString& publicName, const TQString &contactGuid, uint lists, const TQString& groups);
89
	void contactStatus(const TQString&, const TQString&, const TQString& );
90
	void contactAdded(const TQString& handle, const TQString& list, const TQString& publicName, const TQString& contactGuid, const TQString& groupGuid);
91
	//void contactRemoved(const TQString&, const TQString&, uint);
92
	void contactRemoved(const TQString& handle, const TQString& list, const TQString& contactGuid, const TQString& groupGuid);
93
94
	void groupListed(const TQString&, const TQString&);
95
	void groupAdded( const TQString&, const TQString&);
96
	void groupRenamed( const TQString&, const TQString& );
97
	void groupRemoved( const TQString& );
98
99
	void invitedToChat(const TQString&, const TQString&, const TQString&, const TQString&, const TQString& );
100
	void startChat( const TQString&, const TQString& );
101
102
	void statusChanged( const Kopete::OnlineStatus &newStatus );
103
104
	void hotmailSeted(bool) ;
105
106
107
	/**
108
	 * When the dispatch server sends us the notification server to use, this
109
	 * signal is emitted. After this the socket is automatically closed.
110
	 */
111
	void receivedNotificationServer( const TQString &host, uint port );
112
113
114
protected:
115
	/**
116
	 * Handle an MSN command response line.
117
	 */
118
	virtual void parseCommand( const TQString &cmd, uint id,
119
		const TQString &data );
120
121
	/**
122
	 * Handle an MSN error condition.
123
	 * This reimplementation handles most of the other MSN error codes.
124
	 */
125
	virtual void handleError( uint code, uint id );
126
127
	/**
128
	 * This reimplementation sets up the negotiating with the server and
129
	 * suppresses the change of the status to online until the handshake
130
	 * is complete.
131
	 */
132
	virtual void doneConnect();
133
134
135
private slots:
136
	/**
137
	 * We received a message from the server, which is sent as raw data,
138
	 * instead of cr/lf line-based text.
139
	 */
140
	void slotReadMessage( const TQByteArray &bytes );
141
142
	/**
143
	 * Send a keepalive to the server to avoid idle connections to cause
144
	 * MSN closing the connection
145
	 */
146
	void slotSendKeepAlive();
147
148
	void sslLoginFailed();
149
	void sslLoginIncorrect();
150
	void sslLoginSucceeded(TQString ticket);
151
152
153
private:
154
	/**
155
	 * Convert the MSN status strings to a Kopete::OnlineStatus
156
	 */
157
	Kopete::OnlineStatus convertOnlineStatus( const TQString &statusString );
158
159
	MSNAccount *m_account;
160
	TQString m_password;
161
	TQStringList m_msnAlertURLs;
162
163
	unsigned int mailCount;
164
165
	Kopete::OnlineStatus m_newstatus;
166
167
	/**
168
	 * Convert an entry of the Status enum back to a string
169
	 */
170
	TQString statusToString( const Kopete::OnlineStatus &status ) const;
171
172
	/**
173
	 * Process the CurrentMedia XML element.
174
	 * @param mediaXmlElement the source XML element as text.
175
	 */
176
	TQString processCurrentMedia( const TQString &mediaXmlElement );
177
178
	//know the last handle used
179
	TQString m_tmpLastHandle;
180
	TQMap <unsigned int,TQString> m_tmpHandles;
181
	TQString m_configFile;
182
183
	//for hotmail inbox opening
184
	bool m_isHotmailAccount;
185
	TQString m_MSPAuth;
186
	TQString m_kv;
187
	TQString m_sid;
188
	TQString m_loginTime;
189
	TQString m_localIP;
190
	MSNSecureLoginHandler *m_secureLoginHandler;
191
192
	MSNChallengeHandler *m_challengeHandler;
193
	TQTimer *m_keepaliveTimer;
194
195
	bool m_ping;
196
197
	int m_disconnectReason;
198
199
	/**
200
	 * Used to set the myself() personalMessage when the acknowledge(UUX) command is received.
201
	 * The personalMessage is built into @ref changePersonalMessage
202
	 */
203
	TQString m_propertyPersonalMessage;
204
205
	/**
206
	 * Used to tell when we are logged in to MSN Messeger service.
207
	 * Logged when we receive the initial profile message from Hotmail.
208
	 *
209
	 * Some commands only make sense to be done when logged.
210
	 */
211
	bool m_isLogged;
212
};
213
214
#endif
215
216
// vim: set noet ts=4 sts=4 sw=4:
217
(-)tdenetwork.ori/kopete/protocols/msn/msnprotocol.cpp (-179 lines)
Lines 1-179 Link Here
1
/*
2
    msnprotocol.cpp - Kopete MSN Protocol Plugin
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
6
    Copyright (c) 2002-2003 by Olivier Goffart        <ogoffart @ kde.org>
7
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
8
9
    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>
10
11
    *************************************************************************
12
    *                                                                       *
13
    * This program is free software; you can redistribute it and/or modify  *
14
    * it under the terms of the GNU General Public License as published by  *
15
    * the Free Software Foundation; either version 2 of the License, or     *
16
    * (at your option) any later version.                                   *
17
    *                                                                       *
18
    *************************************************************************
19
*/
20
21
#include <tqimage.h>
22
23
#include <kdebug.h>
24
#include <kgenericfactory.h>
25
#include <tdeconfig.h>
26
#include <tdeversion.h>
27
#include <tdeaboutdata.h>
28
29
#include "kopeteaccountmanager.h"
30
#include "kopeteglobal.h"
31
#include "kopeteonlinestatusmanager.h"
32
33
#include "msnaddcontactpage.h"
34
#include "msneditaccountwidget.h"
35
#include "msncontact.h"
36
#include "msnaccount.h"
37
#include "msnprotocol.h"
38
#include "msnchatsession.h"
39
40
typedef KGenericFactory<MSNProtocol> MSNProtocolFactory;
41
#if KDE_IS_VERSION(3,2,90)
42
static const TDEAboutData aboutdata("kopete_msn", I18N_NOOP("MSN Messenger") , "1.0" );
43
K_EXPORT_COMPONENT_FACTORY( libkopete_msn_shared, MSNProtocolFactory( &aboutdata ) )
44
#else
45
K_EXPORT_COMPONENT_FACTORY( libkopete_msn_shared, MSNProtocolFactory( "kopete_msn" ) )
46
#endif
47
48
MSNProtocol *MSNProtocol::s_protocol = 0L;
49
50
MSNProtocol::MSNProtocol( TQObject *parent, const char *name, const TQStringList & /* args */ )
51
: Kopete::Protocol( MSNProtocolFactory::instance(), parent, name ),
52
	NLN( Kopete::OnlineStatus::Online,    25, this, 1, TQString(),               i18n( "Online" ) ,           i18n( "O&nline" ),        Kopete::OnlineStatusManager::Online,Kopete::OnlineStatusManager::HasAwayMessage ),
53
	BSY( Kopete::OnlineStatus::Away,      20, this, 2, "msn_busy",                  i18n( "Busy" ) ,             i18n( "&Busy" ),          Kopete::OnlineStatusManager::Busy,  Kopete::OnlineStatusManager::HasAwayMessage ),
54
	BRB( Kopete::OnlineStatus::Away,      22, this, 3, "msn_brb",                   i18n( "Be Right Back" ),     i18n( "Be &Right Back" ) ,  0  ,                              Kopete::OnlineStatusManager::HasAwayMessage ),
55
	AWY( Kopete::OnlineStatus::Away,      18, this, 4, "contact_away_overlay",      i18n( "Away From Computer" ),i18n( "&Away" ),          Kopete::OnlineStatusManager::Away,  Kopete::OnlineStatusManager::HasAwayMessage ),
56
	PHN( Kopete::OnlineStatus::Away,      12, this, 5, "contact_phone_overlay",     i18n( "On the Phone" ) ,     i18n( "On The &Phone" )  ,  0  ,                              Kopete::OnlineStatusManager::HasAwayMessage ),
57
	LUN( Kopete::OnlineStatus::Away,      15, this, 6, "contact_food_overlay",      i18n( "Out to Lunch" ) ,     i18n( "Out To &Lunch" )  ,  0  ,                              Kopete::OnlineStatusManager::HasAwayMessage ),
58
	FLN( Kopete::OnlineStatus::Offline,    0, this, 7, TQString(),               i18n( "Offline" ) ,          i18n( "&Offline" ),       Kopete::OnlineStatusManager::Offline,Kopete::OnlineStatusManager::DisabledIfOffline ),
59
	HDN( Kopete::OnlineStatus::Invisible,  3, this, 8, "contact_invisible_overlay", i18n( "Invisible" ) ,        i18n( "&Invisible" ),     Kopete::OnlineStatusManager::Invisible ), 
60
	IDL( Kopete::OnlineStatus::Away,      10, this, 9, "contact_away_overlay",      i18n( "Idle" ) ,             i18n( "&Idle" ),          Kopete::OnlineStatusManager::Idle , Kopete::OnlineStatusManager::HideFromMenu ),
61
	UNK( Kopete::OnlineStatus::Unknown,   25, this, 0, "status_unknown",            i18n( "Status not available" ) ),
62
	CNT( Kopete::OnlineStatus::Connecting, 2, this, 10,"msn_connecting",            i18n( "Connecting" ) ),
63
	propEmail(Kopete::Global::Properties::self()->emailAddress()),
64
	propPhoneHome(Kopete::Global::Properties::self()->privatePhone()),
65
	propPhoneWork(Kopete::Global::Properties::self()->workPhone()),
66
	propPhoneMobile(Kopete::Global::Properties::self()->privateMobilePhone()),
67
	propClient("client", i18n("Remote Client"), 0, false),
68
	propGuid("guid", i18n("Contact GUID"), 0, true),
69
	propPersonalMessage(Kopete::Global::Properties::self()->awayMessage())
70
{
71
	s_protocol = this;
72
73
	addAddressBookField( "messaging/msn", Kopete::Plugin::MakeIndexField );
74
75
	setCapabilities( Kopete::Protocol::BaseFgColor | Kopete::Protocol::BaseFont | Kopete::Protocol::BaseFormatting );
76
77
	// m_status = m_unknownStatus = UNK;
78
}
79
80
Kopete::Contact *MSNProtocol::deserializeContact( Kopete::MetaContact *metaContact, const TQMap<TQString, TQString> &serializedData,
81
	const TQMap<TQString, TQString> & /* addressBookData */ )
82
{
83
	TQString contactId   = serializedData[ "contactId" ] ;
84
	TQString accountId   = serializedData[ "accountId" ] ;
85
	TQString lists = serializedData[ "lists" ];
86
	TQStringList groups  = TQStringList::split( ",", serializedData[ "groups" ] );
87
	TQString contactGuid = serializedData[ "contactGuid" ] ;
88
89
	TQDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts( this );
90
91
	Kopete::Account *account = accounts[ accountId ];
92
	if( !account )
93
		account = createNewAccount( accountId );
94
95
	// Create MSN contact
96
	MSNContact *c = new MSNContact( account, contactId, metaContact );
97
98
	for( TQStringList::Iterator it = groups.begin() ; it != groups.end(); ++it )
99
		c->contactAddedToGroup( *it, 0L  /* FIXME - m_groupList[ ( *it ).toUInt() ]*/ );
100
101
	c->m_obj= serializedData[ "obj" ];
102
	c->setInfo( "PHH" , serializedData[ "PHH" ] );
103
	c->setInfo( "PHW" , serializedData[ "PHW" ] );
104
	c->setInfo( "PHM" , serializedData[ "PHM" ] );
105
	c->setProperty( propGuid, contactGuid );
106
107
	c->setBlocked(  (bool)(lists.contains('B')) );
108
	c->setAllowed(  (bool)(lists.contains('A')) );
109
	c->setReversed( (bool)(lists.contains('R')) );
110
111
	return c;
112
}
113
114
AddContactPage *MSNProtocol::createAddContactWidget(TQWidget *parent , Kopete::Account *i)
115
{
116
	return (new MSNAddContactPage(i->isConnected(),parent));
117
}
118
119
KopeteEditAccountWidget *MSNProtocol::createEditAccountWidget(Kopete::Account *account, TQWidget *parent)
120
{
121
	return new MSNEditAccountWidget(this,account,parent);
122
}
123
124
Kopete::Account *MSNProtocol::createNewAccount(const TQString &accountId)
125
{
126
	return new MSNAccount(this, accountId);
127
}
128
129
130
// NOTE: CALL THIS ONLY BEING CONNECTED
131
void MSNProtocol::slotSyncContactList()
132
{
133
/*	if ( ! mIsConnected )
134
	{
135
		return;
136
	}
137
	// First, delete D marked contacts
138
	TQStringList localcontacts;
139
140
	contactsFile->setGroup("Default");
141
142
	contactsFile->readListEntry("Contacts",localcontacts);
143
	TQString tmpUin;
144
	tmpUin.sprintf("%d",uin);
145
	tmp.append(tmpUin);
146
	cnt=contactsFile->readNumEntry("Count",0);
147
*/
148
}
149
150
MSNProtocol* MSNProtocol::protocol()
151
{
152
	return s_protocol;
153
}
154
155
bool MSNProtocol::validContactId(const TQString& userid)
156
{
157
	return ( userid.contains('@') ==1 && userid.contains('.') >=1 && userid.contains(' ') == 0);
158
}
159
160
TQImage MSNProtocol::scalePicture(const TQImage &picture)
161
{
162
	TQImage img(picture);
163
	img = img.smoothScale( 96, 96, TQ_ScaleMin );
164
	// crop image if not square
165
	if(img.width() < img.height())
166
	{
167
		img = img.copy((img.width()-img.height())/2, 0, 96, 96);
168
	}
169
	else if(img.width() > img.height())
170
	{
171
		img = img.copy(0, (img.height()-img.width())/2, 96, 96);
172
	}
173
174
	return img;
175
}
176
#include "msnprotocol.moc"
177
178
// vim: set noet ts=4 sts=4 sw=4:
179
(-)tdenetwork.ori/kopete/protocols/msn/msnprotocol.h (-188 lines)
Lines 1-188 Link Here
1
/*
2
    msnprotocol.h - Kopete MSN Protocol Plugin
3
4
    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
5
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
6
    Copyright (c) 2002-2003 by Olivier Goffart        <ogoffart @ kde.org>
7
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
8
9
    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>
10
11
    *************************************************************************
12
    *                                                                       *
13
    * This program is free software; you can redistribute it and/or modify  *
14
    * it under the terms of the GNU General Public License as published by  *
15
    * the Free Software Foundation; either version 2 of the License, or     *
16
    * (at your option) any later version.                                   *
17
    *                                                                       *
18
    *************************************************************************
19
*/
20
21
#ifndef __msnprotocol_h__
22
#define __msnprotocol_h__
23
24
#include <tqmap.h>
25
#include <tqstringlist.h>
26
27
#include "kopeteprotocol.h"
28
#include "kopeteonlinestatus.h"
29
#include "kopetecontactproperty.h"
30
31
#include "msnsocket.h"
32
33
34
class TQImage;
35
36
class TDEAction;
37
class TDEActionMenu;
38
39
class MSNContact;
40
class MSNAccount;
41
class MSNNotifySocket;
42
class MSNSwitchBoardSocket;
43
class MSNChatSession;
44
class MSNInvitation;
45
namespace Kopete { class ChatSession; }
46
namespace Kopete { class MetaContact; }
47
namespace Kopete { class Contact; }
48
namespace Kopete { class Message; }
49
namespace Kopete { class Group; }
50
51
/**
52
 * @author duncan
53
 * @author Martijn Klingens <klingens@kde.org>
54
 * @author Olivier Goffart  <ogoffart @ kde.org>
55
 */
56
class KOPETE_EXPORT MSNProtocol : public Kopete::Protocol
57
{
58
	Q_OBJECT
59
  
60
61
public:
62
	MSNProtocol( TQObject *parent, const char *name, const TQStringList &args );
63
64
	/**
65
	 * SyncMode indicates whether settings differing between client and
66
	 * server should be propagated to keep them in sync.
67
	 * SyncToServer   - Ignore the server setting when sent. Instead, push
68
	 *                  the local setting to the server. Used when changing
69
	 *                  settings offline.
70
	 * SyncFromServer - Update locally stored settings with the value sent
71
	 *                  by the server. Used when connecting to the server if
72
	 *                  no offline changes are pending to force a sync.
73
	 * SyncBoth       - Changes are updated both ways. This is truly a
74
	 *                  'first come, first serve' scenario, which breaks if
75
	 *                  the 'old' value is sent by one peer before the other
76
	 *                  end is able to push the new value. An example of this
77
	 *                  is changing the MSN nickname offline - the server can
78
	 *                  only be updated after it has sent the old value to
79
	 *                  the client during connect, destroying the new setting.
80
	 *                  Once connected this is often the most useful setting.
81
	 * DontSync       - Do not sync values at all. This is used if settings
82
	 *                  are overridden locally, but should not be sent to the
83
	 *                  server, nor should the client update server-pushed
84
	 *                  values. This can be useful for e.g. contact lists.
85
	 */
86
	enum SyncMode
87
	{
88
		DontSync       = 0x00,
89
		SyncToServer   = 0x01,
90
		SyncFromServer = 0x02,
91
		SyncBoth       = 0x03
92
	};
93
94
	/**
95
	 * The possible MSN online statuses
96
	 */
97
	const Kopete::OnlineStatus NLN;  //online
98
	const Kopete::OnlineStatus BSY;  //busy
99
	const Kopete::OnlineStatus BRB;  //be right back
100
	const Kopete::OnlineStatus AWY;  //away
101
	const Kopete::OnlineStatus PHN;  //on the phone
102
	const Kopete::OnlineStatus LUN;  //out to lunch
103
	const Kopete::OnlineStatus FLN;  //offline
104
	const Kopete::OnlineStatus HDN;  //invisible
105
	const Kopete::OnlineStatus IDL;  //idle
106
	const Kopete::OnlineStatus UNK;  //inknown (internal)
107
	const Kopete::OnlineStatus CNT;  //connecting (internal)
108
109
	const Kopete::ContactPropertyTmpl propEmail;
110
	const Kopete::ContactPropertyTmpl propPhoneHome;
111
	const Kopete::ContactPropertyTmpl propPhoneWork;
112
	const Kopete::ContactPropertyTmpl propPhoneMobile;
113
	const Kopete::ContactPropertyTmpl propClient;
114
	const Kopete::ContactPropertyTmpl propGuid;
115
	const Kopete::ContactPropertyTmpl propPersonalMessage; // it's the equivalent of away message.
116
117
	enum List
118
	{
119
		FL,    // forward
120
		AL,    // allow
121
		BL,    // blocked
122
		RL,    // reverse
123
		PL     // pending
124
	};
125
126
	// Enums used to build the Kopete's MSN ClientId.
127
	enum MSNClientInformationFields
128
	{
129
		WindowsMobile = 0x1,
130
		InkFormatGIF = 0x04,
131
		InkFormatISF = 0x08,
132
		SupportWebcam = 0x10,
133
		SupportMultiPacketMessaging = 0x20,
134
		MSNMobileDevice = 0x40,
135
		MSNDirectDevice = 0x80,
136
		WebMessenger = 0x100,
137
		SupportDirectIM =  0x4000,
138
		SupportWinks = 0x8000,
139
		MSNC1 = 0x10000000,
140
		MSNC2 = 0x20000000,
141
		MSNC3 = 0x30000000,
142
		MSNC4 = 0x40000000
143
	};
144
145
	enum PersonalMessageType
146
	{
147
		PersonalMessageNormal,
148
		PersonalMessageMusic,
149
		PersonalMessageGame,
150
		PersonalMessageOffice
151
	};
152
153
	virtual Kopete::Contact *deserializeContact( Kopete::MetaContact *metaContact,
154
		const TQMap<TQString, TQString> &serializedData, const TQMap<TQString, TQString> &addressBookData );
155
156
	virtual AddContactPage *createAddContactWidget( TQWidget *parent , Kopete::Account *i);
157
	virtual KopeteEditAccountWidget *createEditAccountWidget(Kopete::Account *account, TQWidget *parent);
158
	virtual Kopete::Account *createNewAccount(const TQString &accountId);
159
160
	static MSNProtocol* protocol();
161
	static bool validContactId(const TQString&);
162
	TQImage scalePicture(const TQImage &picture);
163
164
private slots:
165
	void slotSyncContactList();
166
167
private:
168
169
	static MSNProtocol *s_protocol;
170
171
signals:
172
	/**
173
	 * A new msn invitation has been arrived. plugins can connect this signal to handle invitations.
174
	 * if the invitationID match to their internal id. they can create a new MSNInvitation and pass it via invitation
175
	 *
176
	 * @param invitation should be set by the plugin to the new invitaiton. plugin should check it is equal to 0L before
177
	 * @param bodyMSG is the whole invitation message
178
	 * @param cookie is the invitation cookie
179
	 * @param msnMM is the message manager
180
	 * @param c is the contact
181
	 */
182
	void invitation(MSNInvitation*& invitation,  const TQString &bodyMSG , long unsigned int cookie , MSNChatSession* msnMM , MSNContact* c );
183
};
184
185
#endif
186
187
// vim: set noet ts=4 sts=4 sw=4:
188
(-)tdenetwork.ori/kopete/protocols/msn/msnsecureloginhandler.cpp (-131 lines)
Lines 1-131 Link Here
1
/*
2
    msnsecureloginhandler.cpp - SSL login for MSN protocol
3
4
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
#include "msnsecureloginhandler.h"
18
19
// TQt includes
20
#include <tqregexp.h>
21
22
// KDE includes
23
#include <tdeio/job.h>
24
#include <kurl.h>
25
#include <kdebug.h>
26
27
MSNSecureLoginHandler::MSNSecureLoginHandler(const TQString &accountId, const TQString &password, const TQString &authParameters)
28
  : m_password(password), m_accountId(accountId), m_authentification(authParameters)
29
{
30
	
31
}
32
33
MSNSecureLoginHandler::~MSNSecureLoginHandler()
34
{
35
//	kdDebug(14140) << k_funcinfo << endl;
36
}
37
38
void MSNSecureLoginHandler::login()
39
{
40
	// Retrive the login server.
41
	// Do a reload and don't show the progress.
42
	TDEIO::Job *getLoginServer = TDEIO::get(KURL("https://nexus.passport.com/rdr/pprdr.asp"), true, false);
43
44
	getLoginServer->addMetaData("cookies", "manual");
45
	getLoginServer->addMetaData("cache", "reload");
46
	getLoginServer->addMetaData("PropagateHttpHeader", "true");
47
48
	connect(getLoginServer, TQT_SIGNAL(result(TDEIO::Job *)), this, TQT_SLOT(slotLoginServerReceived(TDEIO::Job* )));
49
}
50
51
void MSNSecureLoginHandler::slotLoginServerReceived(TDEIO::Job *loginJob)
52
{
53
	if(!loginJob->error())
54
	{
55
		// Retrive the HTTP header
56
		TQString httpHeaders = loginJob->queryMetaData("HTTP-Headers");
57
58
		// Get the login URL using TQRegExp
59
		TQRegExp rx("PassportURLs: DARealm=(.*),DALogin=(.*),DAReg=");
60
		rx.search(httpHeaders);
61
62
		// Set the loginUrl and loginServer
63
		TQString loginUrl = rx.cap(2);
64
		TQString loginServer = loginUrl.section('/', 0, 0);
65
66
		kdDebug(14140) << k_funcinfo << loginServer << endl;
67
68
		TQString authURL = "https://" + loginUrl;
69
70
		TDEIO::Job *authJob = TDEIO::get(KURL(authURL), true, false);
71
		authJob->addMetaData("cookies", "manual");
72
73
		TQString authRequest = "Authorization: Passport1.4 "
74
								"OrgVerb=GET,"
75
								"OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,"
76
								"sign-in=" + KURL::encode_string(m_accountId) +
77
								",pwd=" + KURL::encode_string( m_password ).replace(',',"%2C") +
78
								"," + m_authentification + "\r\n";
79
80
//   warning, this debug contains the password
81
//		kdDebug(14140) << k_funcinfo << "Auth request: " << authRequest << endl;
82
83
		authJob->addMetaData("customHTTPHeader", authRequest);
84
		authJob->addMetaData("SendLanguageSettings", "false");
85
		authJob->addMetaData("PropagateHttpHeader", "true");
86
		authJob->addMetaData("cookies", "manual");
87
		authJob->addMetaData("cache", "reload");
88
		
89
		connect(authJob, TQT_SIGNAL(result(TDEIO::Job *)), this, TQT_SLOT(slotTweenerReceived(TDEIO::Job* )));
90
	}
91
	else
92
	{
93
		kdDebug(14140) << k_funcinfo << loginJob->errorString() << endl;
94
95
		emit loginFailed();
96
	}	
97
}
98
99
void MSNSecureLoginHandler::slotTweenerReceived(TDEIO::Job *authJob)
100
{
101
	if(!authJob->error())
102
	{
103
		TQString httpHeaders = authJob->queryMetaData("HTTP-Headers");
104
105
// 		kdDebug(14140) << k_funcinfo << "HTTP headers: " << httpHeaders << endl;
106
107
		// Check if we get "401 Unauthorized", thats means it's a bad password.
108
		if(httpHeaders.contains(TQString::fromUtf8("401 Unauthorized")))
109
		{
110
// 			kdDebug(14140) << k_funcinfo << "MSN Login Bad password." << endl;
111
			emit loginBadPassword();
112
		}
113
		else
114
		{
115
			TQRegExp rx("from-PP='(.*)'");
116
			rx.search(httpHeaders);
117
			TQString ticket = rx.cap(1);
118
		
119
	//		kdDebug(14140) << k_funcinfo << "Received ticket: " << ticket << endl;
120
	
121
			emit loginSuccesful(ticket);
122
		}
123
	}
124
	else
125
	{
126
		kdDebug(14140) << k_funcinfo << authJob->errorString() << endl;
127
128
		emit loginFailed();
129
	}
130
}
131
#include "msnsecureloginhandler.moc"
(-)tdenetwork.ori/kopete/protocols/msn/msnsecureloginhandler.h (-77 lines)
Lines 1-77 Link Here
1
/*
2
    msnsecureloginhandler.h - SSL login for MSN protocol
3
4
    Copyright (c) 2005      by Michaël Larouche       <michael.larouche@kdemail.net>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; either version 2 of the License, or     *
13
    * (at your option) any later version.                                   *
14
    *                                                                       *
15
    *************************************************************************
16
*/
17
#ifndef MSNSECURELOGINHANDLER_H
18
#define MSNSECURELOGINHANDLER_H
19
20
#include <tqobject.h>
21
22
namespace TDEIO
23
{
24
	class Job;
25
	class MetaData;
26
}
27
28
/**
29
 * This class handle the login process. It connect to the .NET Password service and retrive the ticket(tweener) to login.
30
 * Use TDEIO.
31
 *
32
 * @author Michaël Larouche <michael.larouche@kdemail.net>
33
*/
34
class MSNSecureLoginHandler : public TQObject
35
{
36
Q_OBJECT
37
  
38
public:
39
    MSNSecureLoginHandler(const TQString &accountId, const TQString &password, const TQString &authParameters);
40
41
    ~MSNSecureLoginHandler();
42
43
	void login();
44
45
signals:
46
	/**
47
	 * TODO: return to const TQString &
48
	 */
49
	void loginSuccesful(TQString ticket);
50
	void loginBadPassword();
51
	void loginFailed();
52
53
private slots:
54
	void slotLoginServerReceived(TDEIO::Job *);
55
	/**
56
	 * We have received our ticket to login.
57
	 */
58
	void slotTweenerReceived(TDEIO::Job *);
59
60
private:
61
	/**
62
	 * Store the password.
63
	 */
64
	TQString m_password;
65
	/**
66
	 * Store the accountId.
67
	 */
68
	TQString m_accountId;
69
	/**
70
	 * Store the authentification parameters
71
	 */
72
	TQString m_authentification;
73
74
	void displayMetaData(TDEIO::MetaData data);
75
};
76
77
#endif
(-)tdenetwork.ori/kopete/protocols/msn/msnsocket.cpp (-1099 lines)
Lines 1-1099 Link Here
1
/*
2
    msnsocket.cpp - Base class for the sockets used in MSN
3
4
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
5
    Copyright (c) 2002-2005 by Olivier Goffart        <ogoffart at kde.org>
6
    Copyright (c) 2005		by Gregg Edghill 		  <gregg.edghill@gmail.com>
7
8
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
9
10
    Portions of this code are taken from KMerlin,
11
              (c) 2001      by Olaf Lueg              <olueg@olsd.de>
12
13
    *************************************************************************
14
    *                                                                       *
15
    * This program is free software; you can redistribute it and/or modify  *
16
    * it under the terms of the GNU General Public License as published by  *
17
    * the Free Software Foundation; either version 2 of the License, or     *
18
    * (at your option) any later version.                                   *
19
    *                                                                       *
20
    *************************************************************************
21
*/
22
23
#include "msnsocket.h"
24
//#include "msnprotocol.h"
25
26
#include <tqregexp.h>
27
#include <tqtimer.h>
28
29
#include <kdebug.h>
30
#include <tdeconfig.h>
31
#include <kbufferedsocket.h>
32
#include <kserversocket.h>
33
#include <kresolver.h>
34
#include <tdelocale.h>
35
#include <tdemessagebox.h>
36
#include <kurl.h>
37
38
#include "kopeteuiglobal.h"
39
40
using namespace KNetwork;
41
42
class MimeMessage
43
{
44
	public:
45
		MimeMessage(const TQString &msg) : message(msg) {}
46
47
		TQString getValue(const TQString &key)
48
		{
49
			TQRegExp rx(key+": ([^\r\n]+)");
50
			rx.search(message);
51
			return rx.cap(1);
52
		}
53
	private:
54
		TQString message;
55
};
56
57
MSNSocket::MSNSocket(TQObject* parent)  : TQObject (parent)
58
{
59
	m_onlineStatus = Disconnected;
60
	m_socket = 0L;
61
	m_useHttp = false;
62
	m_timer  = 0L;
63
}
64
65
MSNSocket::~MSNSocket()
66
{
67
	//if ( m_onlineStatus != Disconnected )
68
	//	disconnect();
69
	delete m_timer;
70
	m_timer = 0L;
71
	doneDisconnect();
72
	if ( m_socket )
73
		m_socket->deleteLater();
74
}
75
76
void MSNSocket::connect( const TQString &server, uint port )
77
{
78
	if ( m_onlineStatus == Connected || m_onlineStatus == Connecting )
79
	{
80
		kdWarning( 14140 ) << k_funcinfo << "Already connected or connecting! Not connecting again." << endl;
81
		return;
82
	}
83
84
	if( m_onlineStatus == Disconnecting )
85
	{
86
		// Cleanup first.
87
		// FIXME: More generic!!!
88
		kdWarning( 14140 ) << k_funcinfo << "We're still disconnecting! Deleting socket the hard way first." << endl;
89
		delete m_socket;
90
	}
91
92
	setOnlineStatus( Connecting );
93
	m_id = 0;
94
	//m_lastId = 0;
95
	m_waitBlockSize = 0;
96
	m_buffer = Buffer( 0 );
97
98
	//m_sendQueue.clear();
99
100
	m_server = server;
101
	m_port = port;
102
103
	if(!m_useHttp)
104
		m_socket = new TDEBufferedSocket( server, TQString::number(port) );
105
	else {
106
		m_socket = new TDEBufferedSocket( m_gateway, "80" );
107
	}
108
109
	m_socket->enableRead( true );
110
111
	// enableWrite eats the CPU, and we only need it when the queue is
112
	// non-empty, so disable it until we have actual data in the queue
113
	m_socket->enableWrite( false );
114
115
	TQObject::connect( m_socket, TQT_SIGNAL( readyRead() ),             this, TQT_SLOT( slotDataReceived() ) );
116
	TQObject::connect( m_socket, TQT_SIGNAL( readyWrite() ),            this, TQT_SLOT( slotReadyWrite() ) );
117
	TQObject::connect( m_socket, TQT_SIGNAL( hostFound() ),	       this, TQT_SLOT( slotHostFound() ) );
118
	TQObject::connect( m_socket, TQT_SIGNAL( connected( const KResolverEntry&) ), this, TQT_SLOT( slotConnectionSuccess() ) );
119
	TQObject::connect( m_socket, TQT_SIGNAL( gotError( int ) ),         this, TQT_SLOT( slotSocketError( int ) ) );
120
	TQObject::connect( m_socket, TQT_SIGNAL( closed( ) ),               this, TQT_SLOT( slotSocketClosed( ) ) );
121
122
	if(m_useHttp)
123
	{
124
		if(m_timer == 0L)
125
		{
126
			m_timer = new TQTimer(this, "Http poll timer");
127
			// Connect the slot HttpPoll with the timer timeout signal.
128
			TQObject::connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotHttpPoll()));
129
		}
130
	}
131
132
	aboutToConnect();
133
134
	// start the asynchronous connection
135
	m_socket->connect();
136
}
137
138
void MSNSocket::disconnect()
139
{
140
	if(m_useHttp)
141
		if(m_timer->isActive()) {
142
			// If the timer is still active, stop the timer.
143
			m_timer->stop();
144
		}
145
146
	if ( m_socket )
147
		m_socket->closeNow();
148
	else
149
		slotSocketClosed();
150
}
151
152
void MSNSocket::aboutToConnect()
153
{
154
	/* Empty default implementation */
155
}
156
157
void MSNSocket::doneConnect()
158
{
159
	setOnlineStatus( Connected );
160
}
161
162
void MSNSocket::doneDisconnect()
163
{
164
	setOnlineStatus( Disconnected );
165
}
166
167
void MSNSocket::setOnlineStatus( MSNSocket::OnlineStatus status )
168
{
169
	if ( m_onlineStatus == status )
170
		return;
171
172
	m_onlineStatus = status;
173
	emit onlineStatusChanged( status );
174
}
175
176
void MSNSocket::slotSocketError( int error )
177
{
178
	kdWarning( 14140 ) << k_funcinfo << "Error: " << error << " (" << m_socket->TDESocketBase::errorString() << ")" << endl;
179
180
	if(!TDESocketBase::isFatalError(error))
181
		return;
182
		//we only care about fatal error
183
184
	TQString errormsg = i18n( "There was an error while connecting to the MSN server.\nError message:\n" );
185
	if ( error == TDESocketBase::LookupFailure )
186
		errormsg += i18n( "Unable to lookup %1" ).arg( m_socket->peerResolver().nodeName() );
187
	else
188
		errormsg +=  m_socket->TDESocketBase::errorString() ;
189
190
	//delete m_socket;
191
	m_socket->deleteLater();
192
	m_socket = 0L;
193
194
	setOnlineStatus( Disconnected );
195
	emit connectionFailed();
196
	//like if the socket is closed
197
	emit socketClosed();
198
199
	emit errorMessage( ErrorConnectionError, errormsg );
200
}
201
202
void MSNSocket::slotDataReceived()
203
{
204
	int avail = m_socket->bytesAvailable();
205
	if ( avail < 0 )
206
	{
207
		// error!
208
		kdWarning( 14140 ) << k_funcinfo << "bytesAvailable() returned " << avail
209
		 	<< ". This should not happen!" << endl
210
			<< "Are we disconnected? Backtrace:" << endl << kdBacktrace() << endl;
211
		return;
212
	}
213
214
	// incoming data, plus an extra char where we pretend a NUL is so the conversion
215
	// to TQCString doesn't go over the end of the allocated memory.
216
	char *buffer = new char[ avail + 1 ];
217
	int ret = m_socket->readBlock( buffer, avail );
218
219
	if ( ret < 0 )
220
	{
221
		kdWarning( 14140 ) << k_funcinfo << "readBlock() returned " << ret << "!" <<endl;
222
	}
223
	else if ( ret == 0 )
224
	{
225
		kdWarning( 14140 ) << k_funcinfo << "readBlock() returned no data!" <<endl;
226
	}
227
	else
228
	{
229
		if ( avail )
230
		{
231
			if ( ret != avail)
232
			{
233
				kdWarning( 14140 ) << k_funcinfo << avail << " bytes were reported available, "
234
					<< "but readBlock() returned only " << ret << " bytes! Proceeding anyway." << endl;
235
			}
236
		}
237
		else
238
		{
239
			kdDebug( 14140 ) << k_funcinfo << "Read " << ret << " bytes into 4kb block." << endl;
240
		}
241
242
243
		TQString rawData;
244
245
		if(m_useHttp)
246
		{
247
			bool error = false;
248
			TQByteArray bytes;
249
250
			// Check if all data has arrived.
251
			rawData = TQString(TQCString(buffer, avail + 1));
252
			bool headers = (rawData.find(TQRegExp("HTTP/\\d\\.\\d (\\d+) ([^\r\n]+)")) != -1);
253
254
			if(headers)
255
			{
256
				// The http header packet arrived.
257
				int endOfHeaders = rawData.find("\r\n\r\n");
258
				if((endOfHeaders + 4) == avail)
259
				{
260
					// Only the response headers data is included.
261
					TQRegExp re("Content-Length: ([^\r\n]+)");
262
					if(re.search(rawData) != -1)
263
					{
264
						bool valid;
265
						int l = re.cap(1).toInt(&valid);
266
						if(valid && l > 0)
267
						{
268
							// The packet contains the headers but does not contain the content data;
269
							// buffer the data received and read again.
270
							m_buffer.add(buffer, avail);
271
272
							delete[] buffer;
273
							// Update how much data remains.
274
							m_remaining = l;
275
							return;
276
						}
277
					}
278
				}
279
			}
280
			else
281
			{
282
				// Write the received data to the buffer.
283
				m_buffer.add(buffer, avail);
284
285
				m_remaining -= avail;
286
				if(m_remaining != 0)
287
				{
288
					// We have not received all the content data, read again.
289
					delete[] buffer;
290
					return;
291
				}
292
293
				// At this point, we have all the bytes returned from the web request.
294
				bytes = m_buffer.take(m_buffer.size());
295
			}
296
			
297
			if(bytes.size() == 0) 
298
			{
299
				// The response headers and the content came in one packet.
300
				bytes.assign(buffer, avail);
301
			}
302
303
304
			// Create the web response object from the response bytes.
305
			WebResponse response(bytes);
306
307
			if(response.getStatusCode() == 100) {
308
				return;
309
			}
310
311
			if(response.getStatusCode() == 200)
312
			{
313
				// If we received a valid response, read the required headers.
314
				// Retrieve the X-MSN-Messenger header.
315
				TQString header = response.getHeaders()->getValue("X-MSN-Messenger");
316
317
				TQStringList parts = TQStringList::split(";", header.replace(" ", ""));
318
				if(!header.isNull() && (parts.count() >= 2))
319
				{
320
					if(parts[0].find("SessionID", 0) != -1)
321
					{
322
						// Assign the session id.
323
						m_sessionId = parts[0].section("=", 1, 1);
324
					}else
325
						error = true;
326
327
					if(parts[1].find("GW-IP", 0) != -1)
328
					{
329
						// Assign the gateway IP address.
330
						m_gwip = parts[1].section("=", 1, 1);
331
					}else
332
						error = true;
333
334
335
					if(parts.count() > 2)
336
						if((parts[2].find("Session", 0) != -1) && (parts[2].section("=", 1, 1) == "close"))
337
						{
338
							// The http session has been closed by the server, disconnect.
339
							kdDebug(14140) << k_funcinfo << "Session closed." << endl;
340
							m_bCanPoll = false;
341
							disconnect();
342
							return;
343
						}
344
				}else
345
					error = true;
346
347
				// Retrieve the content length header.
348
				header = response.getHeaders()->getValue("Content-Length");
349
350
				if(!header.isNull())
351
				{
352
					bool valid;
353
					int length = header.toInt(&valid);
354
					if(valid && (length == 0))
355
					{
356
						// If the response content length is zero, there is nothing to do.
357
						m_pending  = false;
358
						return;
359
					}
360
361
					if(valid && (length > 0))
362
					{
363
						// Otherwise, if the content length is greater than zero, get the web response stream.
364
						TQDataStream *stream = response.getResponseStream();
365
						buffer = new char[length];
366
						// Read the web response content.
367
						stream->readRawBytes(buffer, length);
368
						ret = length;
369
					}else
370
						error = true;
371
				}else
372
					error = true;
373
			}else
374
				error = true;
375
376
			if(error)
377
			{
378
				kdDebug(14140) << k_funcinfo << "Http error: " << response.getStatusCode() << " "
379
					<< response.getStatusDescription() << endl;
380
381
				// If we encountered an error, disconnect and return.
382
				m_bCanPoll = false;
383
				// Disconnect from the service.
384
				disconnect();
385
				return;
386
			}
387
		}
388
389
		// Simple check to avoid dumping the binary data from the icons and emoticons to kdDebug:
390
		// all MSN commands start with one or more uppercase characters.
391
		// For now just check the first three chars, let's see how accurate it is.
392
		// Additionally, if we receive an MSN-P2P packet, strip off anything after the P2P header.
393
		rawData = TQString( TQCString( buffer, ((!m_useHttp)? avail : ret) + 1 ) ).stripWhiteSpace().replace(
394
			TQRegExp( "(P2P-Dest:.[a-zA-Z@.]*).*" ), "\\1\n\n(Stripped binary data)" );
395
396
		bool isBinary = false;
397
		for ( uint i = 0; i < 3 ; ++i )
398
		{
399
			if ( (rawData[ i ] < 'A' || rawData[ i ] > 'Z') && (rawData[ i ] < '0' || rawData[ i ] > '9')  )
400
				isBinary = true;
401
		}
402
403
		if ( isBinary )
404
			kdDebug( 14141 ) << k_funcinfo << "(Stripped binary data)" << endl;
405
		else
406
			kdDebug( 14141 ) << k_funcinfo << rawData << endl;
407
408
		// fill the buffer with the received data
409
		m_buffer.add( buffer, ret );
410
411
		slotReadLine();
412
413
		if(m_useHttp) {
414
			// Set data pending to false.
415
			m_pending  = false;
416
		}
417
	}
418
419
	// Cleanup.
420
	delete[] buffer;
421
}
422
423
void MSNSocket::slotReadLine()
424
{
425
	// We have data, first check if it's meant for a block read, otherwise
426
	// parse the first line (which will recursively parse the other lines)
427
	if ( !pollReadBlock() )
428
	{
429
		if ( m_buffer.size() >= 3 && ( m_buffer.data()[ 0 ] == '\0' || m_buffer.data()[ 0 ]== '\1' ) )
430
		{
431
			bytesReceived( m_buffer.take( 3 ) );
432
			TQTimer::singleShot( 0, this, TQT_SLOT( slotReadLine() ) );
433
			return;
434
		}
435
436
		int index = -1;
437
		for ( uint x = 0; m_buffer.size() > x + 1; ++x )
438
		{
439
			if ( ( m_buffer[ x ] == '\r' ) && ( m_buffer[ x + 1 ] == '\n' ) )
440
			{
441
				index = x;
442
				break;
443
			}
444
		}
445
446
		if ( index != -1 )
447
		{
448
			TQString command = TQString::fromUtf8( m_buffer.take( index + 2 ), index );
449
			command.replace( "\r\n", "" );
450
			//kdDebug( 14141 ) << k_funcinfo << command << endl;
451
452
			// Don't block the GUI while parsing data, only do a single line!
453
			// (Done before parseLine() to prevent a potential crash)
454
			TQTimer::singleShot( 0, this, TQT_SLOT( slotReadLine() ) );
455
456
			parseLine( command );
457
			// WARNING: At this point 'this' can be deleted (when disconnecting)
458
		}
459
	}
460
}
461
462
void MSNSocket::readBlock( uint len )
463
{
464
	if ( m_waitBlockSize )
465
	{
466
		kdWarning( 14140 ) << k_funcinfo << "Cannot wait for data block: still waiting for other block of size "
467
			<< m_waitBlockSize << "! Data will not be returned." << endl;
468
		return;
469
	}
470
471
	m_waitBlockSize = len;
472
473
	//kdDebug( 14140 ) << k_funcinfo << "Preparing for block read of size " << len << endl;
474
475
	// Try to return the data now, if available. Otherwise slotDataReady
476
	// will do this whenever all data is there.
477
	pollReadBlock();
478
}
479
480
bool MSNSocket::pollReadBlock()
481
{
482
	if ( !m_waitBlockSize )
483
	{
484
		return false;
485
	}
486
	else if ( m_buffer.size() < m_waitBlockSize )
487
	{
488
		kdDebug( 14140 ) << k_funcinfo << "Waiting for data. Received: " << m_buffer.size() << ", required: " << m_waitBlockSize << endl;
489
		return true;
490
	}
491
492
	TQByteArray block = m_buffer.take( m_waitBlockSize );
493
494
	//kdDebug( 14140 ) << k_funcinfo << "Successfully read block of size " << m_waitBlockSize << endl;
495
496
	m_waitBlockSize = 0;
497
	emit blockRead( block);
498
499
	return false;
500
}
501
502
void MSNSocket::parseLine( const TQString &str )
503
{
504
	TQString cmd  = str.section( ' ', 0, 0 );
505
	TQString data = str.section( ' ', 2 ).replace( "\r\n" , "" );
506
507
	bool isNum;
508
	uint id = str.section( ' ', 1, 1 ).toUInt( &isNum );
509
510
	// In some rare cases, like the 'NLN' / 'FLN' commands no id at all
511
	// is sent. Here it's actually a real parameter...
512
	if ( !isNum )
513
		data = str.section( ' ', 1, 1 ) + " " + data;
514
515
	//if ( isNum && id )
516
	//	m_lastId = id;
517
518
	//kdDebug( 14140 ) << k_funcinfo << "Parsing command " << cmd << " (ID " << id << "): '" << data << "'" << endl;
519
520
	data.replace( "\r\n", "" );
521
	bool isError;
522
	uint errorCode = cmd.toUInt( &isError );
523
	if ( isError )
524
		handleError( errorCode, id );
525
	else
526
		parseCommand( cmd, id, data );
527
}
528
529
void MSNSocket::handleError( uint code, uint /* id */ )
530
{
531
	kdDebug(14140) << k_funcinfo << endl;
532
	TQString msg;
533
	ErrorType type = ErrorServerError;
534
	switch ( code )
535
	{
536
/*
537
		// We cant show message for error we don't know what they are or not related to the correct socket
538
		//  Theses following messages are not so instructive
539
	case 205:
540
		msg = i18n ( "An invalid username has been specified.\nPlease correct it, and try to reconnect.\n" );
541
		break;
542
	case 201:
543
		msg = i18n ( "Fully Qualified domain name missing.\n" );
544
		break;
545
	case 207:
546
		msg = i18n ( "You are already logged in!\n" );
547
		break;
548
	case 208:
549
		msg = i18n ( "You specified an invalid username.\nPlease correct it, and try to reconnect.\n");
550
		break;
551
	case 209:
552
		msg = i18n ( "Your nickname is invalid. Please check it, correct it,\nand try to reconnect.\n" );
553
		break;
554
	case 210:
555
		msg = i18n ( "Your list has reached its maximum capacity.\nNo more contacts can be added, unless you remove some first.\n" );
556
		break;
557
	case 216:
558
		 msg = i18n ( "This user is not in your contact list.\n " );
559
		break;
560
	case 300:
561
		msg = i18n ( "Some required fields are missing. Please fill them in and try again.\n" );
562
		break;
563
	case 302:
564
		msg = i18n ( "You are not logged in.\n" );
565
		break;
566
*/
567
	case 500:
568
		msg = i18n ( "An internal server error occurred. Please try again later." );
569
		type = MSNSocket::ErrorCannotConnect;
570
		break;
571
	case 502:
572
		msg = i18n ( "It is no longer possible to perform this operation. The MSN server does not allow it anymore." );
573
		type = MSNSocket::ErrorServerError;
574
		break;
575
	case 600:
576
	case 910:
577
	case 912:
578
	case 921:
579
	case 922:
580
		msg = i18n ( "The MSN server is busy. Please try again later." );
581
		type = MSNSocket::ErrorConnectionError;
582
		break;
583
	case 601:
584
	case 604:
585
	case 605:
586
	case 914:
587
	case 915:
588
	case 916:
589
	case 917:
590
		msg = i18n ( "The server is not available at the moment. Please try again later." );
591
		type = MSNSocket::ErrorCannotConnect;
592
		break;
593
	// Server error
594
	default:
595
		// FIXME: if the error causes a disconnect, it will crash, but we can't disconnect every time
596
		msg = i18n( "Unhandled MSN error code %1 \n"
597
			"Please fill a bug report with a detailed description and if possible the last console debug output." ).arg( code );
598
			// "See http://www.hypothetic.org/docs/msn/basics.php for a description of all error codes."
599
		break;
600
	}
601
602
	if ( !msg.isEmpty() )
603
		emit errorMessage( type, msg );
604
605
	return;
606
}
607
608
int MSNSocket::sendCommand( const TQString &cmd, const TQString &args, bool addId, const TQByteArray &body, bool binary )
609
{
610
	if ( !m_socket )
611
	{
612
		kdWarning( 14140 ) << k_funcinfo << "m_socket == NULL!" << endl;
613
		return -1;
614
	}
615
616
	TQCString data = cmd.utf8();
617
	if ( addId )
618
		data += " " + TQString::number( m_id ).utf8();
619
620
	if ( !args.isEmpty() )
621
		data += " " + args.utf8();
622
623
	// Add length in bytes, not characters
624
	if ( !body.isEmpty() )
625
		data += " " + TQString::number( body.size() - (binary ? 0 : 1 ) ).utf8();
626
627
	data += "\r\n";
628
629
630
	// the command will be sent in slotReadyWrite
631
	TQByteArray bytes;
632
	const uint length = data.length();
633
	bytes.duplicate(data.data(), length);
634
	if(!body.isEmpty())
635
	{
636
		uint l = body.size() - (binary ? 0 : 1);
637
		bytes.resize(length + l);
638
		for(uint i=0; i < l; i++)
639
			bytes[length + i] = body[i];
640
	}
641
642
	// Add the request to the queue.
643
	m_sendQueue.append(bytes);
644
	m_socket->enableWrite(true);
645
646
	if ( addId )
647
	{
648
		++m_id;
649
		return m_id - 1;
650
	}
651
652
	return 0;
653
}
654
655
void MSNSocket::slotReadyWrite()
656
{
657
	if ( !m_sendQueue.isEmpty() )
658
	{
659
		// If the command queue is not empty, retrieve the first command.
660
		TQValueList<TQByteArray>::Iterator it = m_sendQueue.begin();
661
662
		if(m_useHttp)
663
		{
664
			// If web response data is not pending, send the http request.
665
			if(!m_pending)
666
			{
667
				m_pending = true;
668
				// Temporarily disable http polling.
669
				m_bCanPoll = false;
670
				// Set the host to the msn gateway by default.
671
				TQString host = m_gateway;
672
				TQString query; // Web request query string.
673
674
				if(m_bIsFirstInTransaction)
675
				{
676
					query.append("Action=open&Server=");
677
					query.append(m_type);
678
679
					query += "&IP=" + m_server;
680
681
					m_bIsFirstInTransaction = false;
682
				}
683
				else
684
				{
685
					// If this is not the first request sent in the transaction,
686
					// only add the session Id.
687
					host = m_gwip;
688
					query += "SessionID=" + m_sessionId;
689
				}
690
691
				// Create the web request headers.
692
				TQString s = makeHttpRequestString(host, query, (*it).size());
693
694
				uint length = s.length();
695
				// Create the web request bytes.
696
				TQByteArray bytes(length + (*it).size());
697
698
				// Copy the request headers into the request bytes.
699
				for(uint i=0; i < length; i++)
700
					bytes[i] = s.ascii()[i];
701
				// Copy the request body into the request bytes.
702
				for(uint i=0; i < (*it).size(); i++)
703
					bytes[length + i] = (*it)[i];
704
705
				kdDebug( 14141 ) << k_funcinfo << "Sending http command: " << TQString(*it).stripWhiteSpace() << endl;
706
707
				// Write the request bytes to the socket.
708
				m_socket->writeBlock(bytes.data(), bytes.size());
709
710
				// Remove the request from the request queue.
711
				m_sendQueue.remove(it);
712
713
				if(m_sendQueue.isEmpty())
714
				{
715
					// Disable sending requests.
716
					m_socket->enableWrite(false);
717
					// If the request queue is empty, poll the server.
718
					m_bCanPoll = true;
719
				}
720
			}
721
		}
722
		else
723
		{
724
			// Otherwise, send the command normally.
725
726
			// Simple check to avoid dumping the binary data from the icons and emoticons to kdDebug:
727
			// When sending an MSN-P2P packet, strip off anything after the P2P header.
728
			TQString debugData = TQString( *it ).stripWhiteSpace().replace(
729
				TQRegExp( "(P2P-Dest:.[a-zA-Z@.]*).*" ), "\\1\n\n(Stripped binary data)" );
730
			kdDebug( 14141 ) << k_funcinfo << "Sending command: " << debugData << endl;
731
732
			m_socket->writeBlock( *it, ( *it ).size() );
733
			m_sendQueue.remove( it );
734
735
			// If the queue is empty agalin stop waiting for readyWrite signals
736
			// because of the CPU usage
737
			if ( m_sendQueue.isEmpty() )
738
				m_socket->enableWrite( false );
739
		}
740
	}
741
	else
742
	{
743
		m_socket->enableWrite( false );
744
745
		if(m_useHttp)
746
		{
747
			// If the request queue is empty, poll the server.
748
			m_bCanPoll = true;
749
		}
750
	}
751
}
752
753
TQString MSNSocket::escape( const TQString &str )
754
{
755
	//return ( KURL::encode_string( str, 106 ) );
756
	//It's not needed to encode everything. The official msn client only encode spaces and %
757
	//If we encode more, the size can be longer than excepted.
758
759
	int old_length= str.length();
760
	TQChar *new_segment = new TQChar[ old_length * 3 + 1 ];
761
	int new_length = 0;
762
763
	for	( int i = 0; i < old_length; i++ )
764
	{
765
		unsigned short character = str[i].unicode();
766
767
		if( character <= 32 || character == '%' )
768
		{
769
			new_segment[ new_length++ ] = '%';
770
771
			unsigned int c = character / 16;
772
			c += (c > 9) ? ('A' - 10) : '0';
773
			new_segment[ new_length++ ] = c;
774
775
			c = character % 16;
776
			c += (c > 9) ? ('A' - 10) : '0';
777
			new_segment[ new_length++ ] = c;
778
		}
779
		else
780
			new_segment[ new_length++ ] = str[i];
781
	}
782
783
	TQString result = TQString(new_segment, new_length);
784
	delete [] new_segment;
785
	return result;
786
787
}
788
789
TQString MSNSocket::unescape( const TQString &str )
790
{
791
	TQString str2 = KURL::decode_string( str, 106 );
792
	//remove msn+ colors code
793
	str2 = str2.replace( TQRegExp("[\\x1-\\x8]"), "" ); // old msn+ colors
794
	// added by kaoul <erwin.kwolek at gmail.com>
795
	str2 = str2.replace( TQRegExp("\\xB7[&@\'#0]"),""); // dot ...
796
	str2 = str2.replace( TQRegExp("\\xB7\\$,?\\d{1,2}"),""); // dot dollar (comma)? 0-99
797
798
	return str2;
799
}
800
801
void MSNSocket::slotConnectionSuccess()
802
{
803
	if(m_useHttp)
804
	{
805
		// If we are connected, set the data pending flag to false,
806
		// and disable http polling.
807
		m_pending  = false;
808
		m_bCanPoll = false;
809
		// If we are connected, start the timer.
810
		m_timer->start(2000, false);
811
	}
812
813
	//kdDebug( 14140 ) << k_funcinfo << endl;
814
	doneConnect();
815
}
816
817
void MSNSocket::slotHostFound()
818
{
819
        // nothing to do
820
}
821
822
void MSNSocket::slotSocketClosed()
823
{
824
    kdDebug( 14140 ) << k_funcinfo << "Socket closed. " << endl;
825
826
	if ( !m_socket ||  m_onlineStatus == Disconnected )
827
	{
828
		kdDebug( 14140 ) << k_funcinfo << "Socket already deleted or already disconnected" << endl;
829
		return;
830
	}
831
832
	doneDisconnect();
833
834
	m_buffer = Buffer( 0 );
835
	//delete m_socket;
836
	m_socket->deleteLater();
837
	m_socket = 0L;
838
839
	emit socketClosed();
840
}
841
842
void MSNSocket::slotHttpPoll()
843
{
844
	if(m_pending || !m_bCanPoll){
845
		// If data is pending or poll has been temporary disabled, return.
846
		return;
847
	}
848
849
	// Create the http request headers.
850
	const TQCString headers = makeHttpRequestString(m_gwip, "Action=poll&SessionID=" + m_sessionId, 0).utf8();
851
	m_socket->writeBlock(headers, headers.length());
852
	// Wait for the response.
853
	m_pending = true;
854
	m_socket->enableWrite(true);
855
}
856
857
// Used in MSNFileTransferSocket
858
// FIXME: Why is this here if it's only used for file transfer? - Martijn
859
void MSNSocket::bytesReceived( const TQByteArray & /* data */ )
860
{
861
	kdWarning( 14140 ) << k_funcinfo << "Unknown bytes were received" << endl;
862
}
863
864
void MSNSocket::sendBytes( const TQByteArray &data )
865
{
866
	if ( !m_socket )
867
	{
868
		kdWarning( 14140 ) << k_funcinfo << "Not yet connected" << endl;
869
		return;
870
	}
871
872
	m_socket->writeBlock( data, data.size() );
873
	m_socket->enableWrite( true );
874
}
875
876
bool MSNSocket::setUseHttpMethod( bool useHttp )
877
{
878
	if( m_useHttp == useHttp )
879
		return true;
880
881
	if( useHttp ) {
882
		TQString s = TQString( this->className() ).lower();
883
		if( s == "msnnotifysocket" )
884
			m_type = "NS";
885
		else if( s == "msnswitchboardsocket" )
886
			m_type = "SB";
887
		else
888
			m_type = TQString();
889
890
		if( m_type.isNull() )
891
			return false;
892
893
		m_bCanPoll = false;
894
		m_bIsFirstInTransaction = true;
895
		m_pending = false;
896
		m_remaining = 0;
897
		m_gateway = "gateway.messenger.hotmail.com";
898
	}
899
900
	if ( m_onlineStatus != Disconnected )
901
		disconnect();
902
903
	m_useHttp = useHttp;
904
905
	return true;
906
}
907
908
bool MSNSocket::useHttpMethod() const
909
{
910
	return m_useHttp;
911
}
912
913
bool MSNSocket::accept( TDEServerSocket *server )
914
{
915
	if ( m_socket )
916
	{
917
		kdWarning( 14140 ) << k_funcinfo << "Socket already exists!" << endl;
918
		return false;
919
	}
920
921
	m_socket = static_cast<TDEBufferedSocket*>(server->accept());
922
923
	if ( !m_socket )
924
	{
925
//		kdWarning( 14140 ) << k_funcinfo << "Socket not created.  Error nb" << server->error() << " : " << server->errorString() << endl;
926
		return false;
927
	}
928
929
	kdDebug( 14140 ) << k_funcinfo << "incoming connection accepted" << endl;
930
931
	setOnlineStatus( Connecting );
932
933
	m_id = 0;
934
	//m_lastId = 0;
935
	m_waitBlockSize = 0;
936
937
	m_socket->setBlocking( false );
938
	m_socket->enableRead( true );
939
	m_socket->enableWrite( true );
940
941
	TQObject::connect( m_socket, TQT_SIGNAL( readyRead() ),             this, TQT_SLOT( slotDataReceived() ) );
942
	TQObject::connect( m_socket, TQT_SIGNAL( readyWrite() ),            this, TQT_SLOT( slotReadyWrite() ) );
943
	TQObject::connect( m_socket, TQT_SIGNAL( closed() ),                this, TQT_SLOT( slotSocketClosed() ) );
944
	TQObject::connect( m_socket, TQT_SIGNAL( gotError( int ) ),         this, TQT_SLOT( slotSocketError( int ) ) );
945
946
	doneConnect();
947
	return true;
948
}
949
950
TQString MSNSocket::getLocalIP()
951
{
952
	if ( !m_socket )
953
		return TQString();
954
955
	const TDESocketAddress address = m_socket->localAddress();
956
957
	TQString ip = address.nodeName();
958
959
	kdDebug( 14140 ) << k_funcinfo << "IP: " << ip  <<endl;
960
	//delete address;
961
	return ip;
962
}
963
964
MSNSocket::Buffer::Buffer( unsigned int sz )
965
: TQByteArray( sz )
966
{
967
}
968
969
MSNSocket::Buffer::~Buffer()
970
{
971
}
972
973
void MSNSocket::Buffer::add( char *str, unsigned int sz )
974
{
975
	char *b = new char[ size() + sz ];
976
	for ( uint f = 0; f < size(); f++ )
977
		b[ f ] = data()[ f ];
978
	for ( uint f = 0; f < sz; f++ )
979
		b[ size() + f ] = str[ f ];
980
981
	duplicate( b, size() + sz );
982
	delete[] b;
983
}
984
985
TQByteArray MSNSocket::Buffer::take( unsigned blockSize )
986
{
987
	if ( size() < blockSize )
988
	{
989
		kdWarning( 14140 ) << k_funcinfo << "Buffer size " << size() << " < asked size " << blockSize << "!" << endl;
990
		return TQByteArray();
991
	}
992
993
	TQByteArray rep( blockSize );
994
	for( uint i = 0; i < blockSize; i++ )
995
		rep[ i ] = data()[ i ];
996
997
	char *str = new char[ size() - blockSize ];
998
	for ( uint i = 0; i < size() - blockSize; i++ )
999
		str[ i ] = data()[ blockSize + i ];
1000
	duplicate( str, size() - blockSize );
1001
	delete[] str;
1002
1003
	return rep;
1004
}
1005
1006
TQString MSNSocket::makeHttpRequestString(const TQString& host, const TQString& query, uint contentLength)
1007
{
1008
	TQString s(
1009
		"POST http://" + host + "/gateway/gateway.dll?" + query + " HTTP/1.1\r\n" +
1010
		"Accept: */*\r\n" +
1011
		"Accept-Language: en-us\r\n" +
1012
		"User-Agent: MSMSGS\r\n" +
1013
		"Host: " + host + "\r\n" +
1014
		"Proxy-Connection: Keep-Alive\r\n" +
1015
		"Connection: Keep-Alive\r\n" +
1016
		"Pragma: no-cache\r\n" +
1017
		"Content-Type: application/x-msn-messenger\r\n" +
1018
		"Content-Length: " + TQString::number(contentLength) + "\r\n" +
1019
		"\r\n");
1020
	return s;
1021
}
1022
1023
MSNSocket::WebResponse::WebResponse(const TQByteArray& bytes)
1024
{
1025
	m_statusCode = 0;
1026
	m_stream     = 0;
1027
1028
	int     headerEnd;
1029
  	TQString header;
1030
	TQString data(TQCString(bytes, bytes.size() + 1));
1031
1032
	// Parse the HTTP status header
1033
	TQRegExp re("HTTP/\\d\\.\\d (\\d+) ([^\r\n]+)");
1034
	headerEnd  = data.find("\r\n");
1035
	header     = data.left( (headerEnd == -1) ? 20 : headerEnd );
1036
1037
	re.search(header);
1038
	m_statusCode = re.cap(1).toInt();
1039
	m_statusDescription = re.cap(2);
1040
1041
	// Remove the web response status header.
1042
	data = data.mid(headerEnd + 2, (data.find("\r\n\r\n") + 2) - (headerEnd + 2));
1043
	// Create a MimeMessage, removing the HTTP status header
1044
	m_headers = new MimeMessage(data);
1045
1046
	// Retrieve the contentlength header.
1047
	header = m_headers->getValue("Content-Length");
1048
	if(!header.isNull())
1049
	{
1050
		bool valid;
1051
		int length = header.toInt(&valid);
1052
		if(valid && length > 0)
1053
		{
1054
			// If the content length is valid, and not zero,
1055
			// copy the web response content bytes.
1056
			int offset = bytes.size() - length;
1057
1058
			TQByteArray content(length);
1059
			for(int i=0; i < length; i++)
1060
				content[i] = bytes[offset + i];
1061
			// Create the web response stream from the response content bytes.
1062
			m_stream = new TQDataStream(content, IO_ReadOnly);
1063
		}
1064
	}
1065
}
1066
1067
MSNSocket::WebResponse::~WebResponse()
1068
{
1069
	delete m_headers;
1070
	m_headers = 0;
1071
	delete m_stream;
1072
	m_stream = 0;
1073
}
1074
1075
MimeMessage* MSNSocket::WebResponse::getHeaders()
1076
{
1077
	return m_headers;
1078
}
1079
1080
TQDataStream* MSNSocket::WebResponse::getResponseStream()
1081
{
1082
	return m_stream;
1083
}
1084
1085
int MSNSocket::WebResponse::getStatusCode()
1086
{
1087
	return m_statusCode;
1088
}
1089
1090
TQString MSNSocket::WebResponse::getStatusDescription()
1091
{
1092
	return m_statusDescription;
1093
}
1094
1095
1096
#include "msnsocket.moc"
1097
1098
// vim: set noet ts=4 sts=4 sw=4:
1099
(-)tdenetwork.ori/kopete/protocols/msn/msnsocket.h (-363 lines)
Lines 1-363 Link Here
1
/*
2
    msnsocket.h - Base class for the sockets used in MSN
3
4
    Copyright (c) 2002      by Martijn Klingens       <klingens@kde.org>
5
    Copyright (c) 2002-2004 by Olivier Goffart        <ogoffart @ kde.org>
6
    Copyright (c) 2005		by Gregg Edghill 		  <gregg.edghill@gmail.com>
7
    Kopete    (c) 2002      by the Kopete developers  <kopete-devel@kde.org>
8
9
    Portions of this code are taken from KMerlin,
10
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>
11
12
    *************************************************************************
13
    *                                                                       *
14
    * This program is free software; you can redistribute it and/or modify  *
15
    * it under the terms of the GNU General Public License as published by  *
16
    * the Free Software Foundation; either version 2 of the License, or     *
17
    * (at your option) any later version.                                   *
18
    *                                                                       *
19
    *************************************************************************
20
*/
21
22
#ifndef MSNSOCKET_H
23
#define MSNSOCKET_H
24
25
#include <tqobject.h>
26
#include <tqdatastream.h>
27
#include <tqstringlist.h>
28
#include <tqtimer.h>
29
#include <tqvaluelist.h>
30
31
#include "kopete_export.h"
32
33
namespace KNetwork {
34
  class TDEBufferedSocket;
35
  class TDEServerSocket;
36
}
37
38
class MimeMessage;
39
40
/**
41
 * @author Martijn Klingens <klingens@kde.org>
42
 *
43
 * MSNSocket encapsulates the common functionality shared by the Dispatch
44
 * Server, the Notification Server and the Switchboard Server. It is
45
 * inherited by the various specialized classes.
46
 */
47
class KOPETE_EXPORT MSNSocket : public TQObject
48
{
49
	Q_OBJECT
50
  
51
52
public:
53
	MSNSocket(TQObject* parent=0l);
54
	~MSNSocket();
55
56
	/**
57
	 * Asynchronously read a block of data of the specified size. When the
58
	 * data is available, the blockRead() signal will be emitted with the
59
	 * data as parameter.
60
	 *
61
	 * NOTE: As the block queue takes precedence over the line-based
62
	 *       command-processing this method can effectively block all
63
	 *       communications when passed a wrong length!
64
	 */
65
	void readBlock( uint len );
66
67
	/**
68
	 * OnlineStatus encapsulates the 4 states a connection can be in,
69
	 * Connecting, Connected, Disconnecting, Disconnected. Connecting
70
	 * and Disconnecting are in the default implementation not used,
71
	 * because the socket connect is an atomic operation and not yet
72
	 * performed asynchronously.
73
	 * In derived classes, like the Notification Server, this state is
74
	 * actively used, because merely having a socket connection established
75
	 * by no means indicates we're actually online - the rest of the
76
	 * handshake likely has to follow first.
77
	 */
78
	enum OnlineStatus { Connecting, Connected, Disconnecting, Disconnected };
79
	enum LookupStatus { Processing, Success, Failed };
80
	enum Transport { TcpTransport, HttpTransport };
81
	enum ErrorType { ErrorConnectionLost, ErrorConnectionError, ErrorCannotConnect, ErrorServerError, ErrorInformation};
82
83
	OnlineStatus onlineStatus() { return m_onlineStatus; }
84
85
	/*
86
	 * return the local ip.
87
	 * Used for filetransfer
88
	 */
89
	TQString getLocalIP();
90
91
	//BEGIN Http
92
93
	virtual bool setUseHttpMethod( bool useHttp );
94
	bool useHttpMethod() const;
95
96
	//END
97
98
public slots:
99
	void connect( const TQString &server, uint port );
100
	virtual void disconnect();
101
102
103
	/**
104
	 * Send an MSN command to the socket
105
	 *
106
	 * For debugging it's convenient to have this method public, but using
107
	 * it outside this class is deprecated for any other use!
108
	 *
109
	 * The size of the body (if any) is automatically added to the argument
110
	 * list and shouldn't be explicitly specified! This size is in bytes
111
	 * instead of characters to reflect what actually goes over the wire.
112
	 *
113
	 * if the param binary is set to true, then, the body is send as a binary message
114
	 *
115
	 * return the id
116
	 */
117
	int sendCommand( const TQString &cmd, const TQString &args = TQString(),
118
		bool addId = true, const TQByteArray &body = TQByteArray() , bool binary=false );
119
120
signals:
121
	/**
122
	 * A block read is ready.
123
	 * After this the normal line-based reads go on again
124
	 */
125
	void blockRead( const TQByteArray &block );
126
127
	/**
128
	 * The online status has changed
129
	 */
130
	void onlineStatusChanged( MSNSocket::OnlineStatus status );
131
132
	/**
133
	 * The connection failed
134
	 */
135
	void connectionFailed();
136
137
	/**
138
	 * The connection was closed
139
	 */
140
	void socketClosed();
141
142
	/**
143
	 * A error has occured. Handle the display of the message.
144
	 */
145
	void errorMessage( int type, const TQString &msg );
146
147
protected:
148
	/**
149
	 * Convenience method: escape spaces with '%20' for use in the protocol.
150
	 * Doesn't escape any other sequence.
151
	 */
152
	TQString escape( const TQString &str );
153
154
	/**
155
	 * And the other way round...
156
	 */
157
	TQString unescape( const TQString &str );
158
159
	/**
160
	 * Set the online status. Emits onlineStatusChanged.
161
	 */
162
	void setOnlineStatus( OnlineStatus status );
163
164
	/**
165
	 * This method is called directly before the socket will actually connect.
166
	 * Override in derived classes to setup whatever is needed before connect.
167
	 */
168
	virtual void aboutToConnect();
169
170
	/**
171
	 * Directly after the connect, this method is called. The default
172
	 * implementation sets the OnlineStatus to Connected, be sure to override
173
	 * this if a handshake is required.
174
	 */
175
	virtual void doneConnect();
176
177
	/**
178
	 * Directly after the disconnect, this method is called before the actual
179
	 * cleanup takes place. The socket is close here. Cleanup internal
180
	 * variables here.
181
	 */
182
	virtual void doneDisconnect();
183
184
	/**
185
	 * Handle an MSN error condition.
186
	 * The default implementation displays a generic error message and
187
	 * closes the connection. Override to allow more graceful handling and
188
	 * possibly recovery.
189
	 */
190
	virtual void handleError( uint code, uint id );
191
192
	/**
193
	 * Handle an MSN command response line.
194
	 * This method is pure virtual and *must* be overridden in derived
195
	 * classes.
196
	 */
197
	virtual void parseCommand( const TQString &cmd, uint id,
198
		const TQString &data ) = 0;
199
200
	/**
201
	 * Used in MSNFileTransferSocket
202
	 */
203
	virtual void bytesReceived( const TQByteArray & );
204
	bool accept( KNetwork::TDEServerSocket * );
205
	void sendBytes( const TQByteArray &data );
206
207
	const TQString &server() { return m_server; }
208
	uint port() { return m_port; }
209
210
	/**
211
	 * The last confirmed ID by the server
212
	 */
213
	//uint m_lastId;
214
215
private slots:
216
	void slotDataReceived();
217
	/**
218
	 * If the socket emits a connectionFailed() then this slot is called
219
	 * to handle the error.
220
	 */
221
	void slotSocketError( int error );
222
223
	/*
224
	 * Calls connectDone() when connection is successfully established.
225
	 */
226
	void slotConnectionSuccess();
227
228
	/**
229
	 * Sets m_lookupProgress to 'Finished' if count > 0 or 'Failed' if count = 0.
230
	 */
231
	void slotHostFound( );
232
233
	/**
234
	 * Check if new lines of data are available and process the first line
235
	 */
236
	void slotReadLine();
237
238
	void slotSocketClosed();
239
240
	//BEGIN Http
241
242
	/**
243
	 * Sends a poll request to the msn gateway when using HttpTransport.
244
	 * equivalent to sending a PNG command over TcpTransport.
245
	 */
246
	void slotHttpPoll();
247
248
	//END
249
250
protected slots:
251
	virtual void slotReadyWrite();
252
253
private:
254
	/**
255
	 * Check if we're waiting for a block of raw data. Emits blockRead()
256
	 * when the data is available.
257
	 * Returns true when still waiting and false when there is no pending
258
	 * read, or when the read is successfully handled.
259
	 */
260
	bool pollReadBlock();
261
262
	/**
263
	 * The id of the message sent to the MSN server. This ID will increment
264
	 * for each subsequent message sent.
265
	 */
266
	uint m_id;
267
268
	/**
269
	 * Queue of pending commands (should be mostly empty, but is needed to
270
	 * send more than one command to the server)
271
	 */
272
	TQValueList<TQByteArray> m_sendQueue;
273
274
	/**
275
	 * Parse a single line of data.
276
	 * Will call either parseCommand or handleError depending on the type of
277
	 * data received.
278
	 */
279
	void parseLine( const TQString &str );
280
281
	KNetwork::TDEBufferedSocket *m_socket;
282
	OnlineStatus m_onlineStatus;
283
284
	TQString m_server;
285
	uint m_port;
286
287
	/**
288
	 * The size of the requested block for block-based reads
289
	 */
290
	uint m_waitBlockSize;
291
292
	class Buffer : public TQByteArray
293
	{
294
	public:
295
		Buffer( unsigned size = 0 );
296
		~Buffer();
297
		void add( char *str, unsigned size );
298
		TQByteArray take( unsigned size );
299
	};
300
301
	Buffer m_buffer;
302
303
	//BEGIN Http
304
305
	/**
306
	 * Makes a http request headers string using the specified, host, query, and content length.
307
	 * return: The string containing the http request headers.
308
	 */
309
	TQString makeHttpRequestString(const TQString& host, const TQString& query, uint contentLength);
310
311
	bool m_useHttp; 			// Indicates whether to use the msn http gateway to connect to the msn service.
312
	bool m_bCanPoll; 			// Indicates whether polling of the http server is allowed.
313
	bool m_bIsFirstInTransaction; 		// Indicates whether pending message to be sent is the first in the transaction.
314
						// If so, the gateway is used.
315
						// Use the gateway only for initial connected state; Otherwise, use the host.
316
	TQString m_gateway;			// Msn http gateway domain name.
317
	TQString m_gwip;				// The ip address of the msn gateway.
318
	TQString m_sessionId; 			// session id.
319
	TQTimer *m_timer; 			// Msn http poll timer.
320
	TQString m_type;				// Indicates the type of socket being used.  NS or SB
321
	bool m_pending; 			// Indicates whether a http response is pending.
322
	int m_remaining;			// Indicates how many bytes of content data remain
323
						// to be received if the content bytes are sent in
324
						// a seperate packet(s).
325
326
	/**
327
	 * Provides access to information returned from a URI request.
328
	 */
329
	class WebResponse
330
	{
331
	public:
332
		 WebResponse(const TQByteArray& bytes);
333
		~WebResponse();
334
335
		/**
336
		 * Gets the headers associated with this response from the server.
337
		 */
338
		MimeMessage* getHeaders();
339
		/**
340
		 * Gets the data stream used to read the body of the response from the server.
341
		 */
342
		TQDataStream* getResponseStream();
343
		/**
344
		 * Gets the status code of the response.
345
		 */
346
		int getStatusCode();
347
		/**
348
		 * Gets the status description returned with the response.
349
		 */
350
		TQString getStatusDescription();
351
352
	private:
353
		MimeMessage *m_headers;
354
		TQDataStream *m_stream;
355
		int m_statusCode;
356
		TQString m_statusDescription;
357
	};
358
359
	//END
360
};
361
362
#endif
363
(-)tdenetwork.ori/kopete/protocols/msn/msnswitchboardsocket.cpp (-1142 lines)
Lines 1-1142 Link Here
1
/*
2
    msnswitchboardsocket.cpp - switch board connection socket
3
4
    Copyright (c) 2002      by Martijn Klingens       <klingens@kde.org>
5
    Copyright (c) 2002-2006 by Olivier Goffart        <ogoffart@ kde.org>
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    Portions of this code are taken from KMerlin,
9
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>
10
11
    *************************************************************************
12
    *                                                                       *
13
    * This program is free software; you can redistribute it and/or modify  *
14
    * it under the terms of the GNU General Public License as published by  *
15
    * the Free Software Foundation; either version 2 of the License, or     *
16
    * (at your option) any later version.                                   *
17
    *                                                                       *
18
    *************************************************************************
19
*/
20
21
22
#include "msnswitchboardsocket.h"
23
24
#include <stdlib.h>
25
#include <time.h>
26
#include <cmath>
27
28
// qt
29
#include <tqstylesheet.h>
30
#include <tqregexp.h>
31
#include <tqimage.h>
32
#include <tqtimer.h>
33
#include <tqfile.h>
34
#include <tqfileinfo.h>
35
36
// kde
37
#include <kdebug.h>
38
#include <tdemessagebox.h>
39
#include <tdeapplication.h>
40
#include <tdeaboutdata.h>
41
#include <tdetempfile.h>
42
#include <tdeconfig.h>
43
#include <kmdcodec.h>
44
#include <kstandarddirs.h>
45
#include <tdetempfile.h>
46
47
// for the display picture
48
#include <msncontact.h>
49
#include "msnnotifysocket.h"
50
51
//kopete
52
#include "msnaccount.h"
53
#include "msnprotocol.h"
54
#include "kopetemessage.h"
55
#include "kopetecontact.h"
56
#include "kopeteuiglobal.h"
57
#include "kopeteemoticons.h"
58
//#include "kopeteaccountmanager.h"
59
//#include "kopeteprotocol.h"
60
61
#include "sha1.h"
62
63
#include "dispatcher.h"
64
using P2P::Dispatcher;
65
66
MSNSwitchBoardSocket::MSNSwitchBoardSocket( MSNAccount *account , TQObject *parent )
67
: MSNSocket( parent )
68
{
69
	m_account = account;
70
	m_recvIcons=0;
71
	m_emoticonTimer=0L;
72
	m_chunks=0;
73
	m_clientcapsSent=false;
74
	m_dispatcher = 0l;
75
	m_keepAlive = 0l;
76
	m_keepAliveNb=0;
77
}
78
79
MSNSwitchBoardSocket::~MSNSwitchBoardSocket()
80
{
81
	kdDebug(14140) << k_funcinfo << endl;
82
83
	TQMap<TQString , TQPair<TQString , KTempFile*> >::Iterator it;
84
	for ( it = m_emoticons.begin(); it != m_emoticons.end(); ++it )
85
	{
86
		delete it.data().second;
87
	}
88
}
89
90
void MSNSwitchBoardSocket::connectToSwitchBoard(TQString ID, TQString address, TQString auth)
91
{
92
	// we need these for the handshake later on (when we're connected)
93
	m_ID = ID;
94
	m_auth = auth;
95
96
	TQString server = address.left( address.find( ":" ) );
97
	uint port = address.right( address.length() - address.findRev( ":" ) - 1 ).toUInt();
98
99
	TQObject::connect( this, TQT_SIGNAL( blockRead( const TQByteArray & ) ),
100
		this, TQT_SLOT(slotReadMessage( const TQByteArray & ) ) );
101
102
	TQObject::connect( this, TQT_SIGNAL( onlineStatusChanged( MSNSocket::OnlineStatus ) ),
103
		this, TQT_SLOT( slotOnlineStatusChanged( MSNSocket::OnlineStatus ) ) );
104
105
	TQObject::connect( this, TQT_SIGNAL( socketClosed( ) ),
106
		this, TQT_SLOT( slotSocketClosed( ) ) );
107
108
	connect( server, port );
109
}
110
111
void MSNSwitchBoardSocket::handleError( uint code, uint id )
112
{
113
	kdDebug(14140) << k_funcinfo << endl;
114
115
	TQString msg;
116
	MSNSocket::ErrorType type;
117
118
	switch( code )
119
	{
120
		case 208:
121
		{
122
			msg = i18n( "Invalid user:\n"
123
				"this MSN user does not exist; please check the MSN ID." );
124
			type = MSNSocket::ErrorServerError;
125
126
			userLeftChat(m_msgHandle , i18n("user never joined"));
127
			break;
128
		}
129
		case 215:
130
		{
131
			msg = i18n( "The user %1 is already in this chat." ).arg( m_msgHandle );
132
			type = MSNSocket::ErrorServerError;
133
134
			//userLeftChat(m_msgHandle , i18n("user was twice in this chat") ); //(the user shouln't join there
135
			break;
136
		}
137
		case 216:
138
		{
139
			msg = i18n( "The user %1 is online but has blocked you:\nyou can not talk to this user." ).arg( m_msgHandle );
140
			type = MSNSocket::ErrorInformation;
141
142
			userLeftChat(m_msgHandle, i18n("user blocked you"));
143
			break;
144
		}
145
		case 217:
146
		{
147
			// TODO: we need to know the nickname instead of the handle.
148
			msg = i18n( "The user %1 is currently not signed in.\n" "Messages will not be delivered." ).arg( m_msgHandle );
149
			type = MSNSocket::ErrorServerError;
150
151
			userLeftChat(m_msgHandle, i18n("user disconnected"));
152
			break;
153
		}
154
		case 713:
155
		{
156
			TQString msg = i18n( "You are trying to invite too many contacts to this chat at the same time" ).arg( m_msgHandle );
157
			type = MSNSocket::ErrorInformation;
158
159
			userLeftChat(m_msgHandle, i18n("user blocked you"));
160
			break;
161
		}
162
		case 911:
163
		{
164
			msg = i18n("Kopete MSN plugin has trouble authenticating with switchboard server.");
165
			type = MSNSocket::ErrorServerError;
166
167
			break;
168
		}
169
		default:
170
			MSNSocket::handleError( code, id );
171
			break;
172
	}
173
174
	if( !msg.isEmpty() )
175
		emit errorMessage( type, msg );
176
}
177
178
void MSNSwitchBoardSocket::parseCommand( const TQString &cmd, uint  id ,
179
	const TQString &data )
180
{
181
	if( cmd == "NAK" )
182
	{
183
		emit msgAcknowledgement(id, false);    // msg was not accepted
184
	}
185
	else if( cmd == "ACK" )
186
	{
187
		emit msgAcknowledgement(id, true);   // msg has received
188
	}
189
	else if( cmd == "JOI" )
190
	{
191
		// new user joins the chat, update user in chat list
192
		TQString handle = data.section( ' ', 0, 0 );
193
		TQString screenname = unescape(data.section( ' ', 1, 1 ));
194
		if( !m_chatMembers.contains( handle ) )
195
			m_chatMembers.append( handle );
196
		emit userJoined( handle, screenname, false );
197
	}
198
	else if( cmd == "IRO" )
199
	{
200
		// we have joined a multi chat session- this are the users in this chat
201
		TQString handle = data.section( ' ', 2, 2 );
202
		if( !m_chatMembers.contains( handle ) )
203
			m_chatMembers.append( handle );
204
205
		TQString screenname = unescape(data.section( ' ', 3, 3));
206
		emit userJoined( handle, screenname, true );
207
	}
208
	else if( cmd == "USR" )
209
	{
210
		slotInviteContact(m_msgHandle);
211
	}
212
	else if( cmd == "BYE" )
213
	{
214
		// some has disconnect from chat, update user in chat list
215
		cleanQueue(); //in case some message are waiting their emoticons, never mind, send them
216
217
		TQString handle = data.section( ' ', 0, 0 ).replace( "\r\n" , "" );
218
		userLeftChat( handle,  (data.section( ' ', 1, 1 ) == "1" ) ? i18n("timeout") : TQString()   );
219
	}
220
	else if( cmd == "MSG" )
221
	{
222
		TQString len = data.section( ' ', 2, 2 );
223
224
		// we need to know who's sending is the block...
225
		m_msgHandle = data.section( ' ', 0, 0 );
226
227
		/*//This is WRONG! the displayName is never updated on the switchboeardsocket
228
		  //so we can't trust it.
229
		  //that's why the official client does not uptade alaws the nickname immediately.
230
		if(m_account->contacts()[ m_msgHandle ])
231
		{
232
			TQString displayName=data.section( ' ', 1, 1 );
233
			if(m_account->contacts()[ m_msgHandle ]->displayName() != displayName)
234
				m_account->contacts()[ m_msgHandle ]->rename(displayName);
235
		}*/
236
237
		readBlock(len.toUInt());
238
	}
239
}
240
241
void MSNSwitchBoardSocket::slotReadMessage( const TQByteArray &bytes )
242
{
243
	TQString msg = TQString::fromUtf8(bytes, bytes.size());
244
245
	TQRegExp rx("Content-Type: ([A-Za-z0-9/\\-]*)");
246
	rx.search(msg);
247
	TQString type=rx.cap(1);
248
249
	rx=TQRegExp("User-Agent: ([A-Za-z0-9./\\-]*)");
250
	rx.search(msg);
251
	TQString clientStr=rx.cap(1);
252
253
	if( !clientStr.isNull() && !m_msgHandle.isNull())
254
	{
255
		Kopete::Contact *c=m_account->contacts()[m_msgHandle];
256
		if(c)
257
			c->setProperty(  MSNProtocol::protocol()->propClient , clientStr );
258
	}
259
260
	// incoming message for File-transfer
261
	if( type== "text/x-msmsgsinvite"  )
262
	{
263
		emit invitation(m_msgHandle,msg);
264
	}
265
	else if( type== "text/x-msmsgscontrol" )
266
	{
267
		TQString message;
268
		message = msg.right( msg.length() - msg.findRev( " " ) - 1 );
269
		message = message.replace(  "\r\n" ,"" );
270
		emit receivedTypingMsg( message.lower(), true );
271
	}
272
	else if(type == "text/x-msnmsgr-datacast")
273
	{
274
		if(msg.contains("ID:"))
275
		{
276
			TQRegExp rx("ID: ([0-9]*)");
277
			rx.search(msg);
278
			uint dataCastId = rx.cap(1).toUInt();
279
			if( dataCastId == 1 )
280
			{
281
				kdDebug(14140) << k_funcinfo << "Received a nudge !" << endl;
282
				emit nudgeReceived(m_msgHandle);
283
			}
284
		}
285
	}
286
	else if(type=="text/plain" /*  || type.isEmpty()*/ )
287
	{
288
		// Some MSN Clients (like CCMSN) don't like to stick to the rules.
289
		// In case of CCMSN, it doesn't send what the content type is when
290
		// sending a text message. So if it's not supplied, we'll just
291
		// assume its that.
292
293
		TQColor fontColor;
294
		TQFont font;
295
296
		if ( msg.contains( "X-MMS-IM-Format" ) )
297
		{
298
			TQString fontName;
299
			TQString fontInfo;
300
			TQString color;
301
302
			rx=TQRegExp("X-MMS-IM-Format: ([^\r\n]*)");
303
			rx.search(msg);
304
			fontInfo =rx.cap(1);
305
306
			color = parseFontAttr(fontInfo, "CO");
307
308
			// FIXME: this is so BAAAAAAAAAAAAD :(
309
			if (!color.isEmpty() && color.toInt(0,16)!=0)
310
			{
311
				if ( color.length() == 2) // only #RR (red color) given
312
					fontColor.setRgb(
313
						color.mid(0,2).toInt(0,16),
314
						0,
315
						0);
316
				else if ( color.length() == 4) // #GGRR (green, red) given.
317
				{
318
					fontColor.setRgb(
319
						color.mid(2,2).toInt(0,16),
320
						color.mid(0,2).toInt(0,16),
321
						0);
322
				}
323
				else if ( color.length() == 6) // full #BBGGRR given
324
				{
325
					fontColor.setRgb(
326
						color.mid(4,2).toInt(0, 16),
327
						color.mid(2,2).toInt(0,16),
328
						color.mid(0,2).toInt(0,16));
329
				}
330
			}
331
332
			fontName = parseFontAttr(fontInfo, "FN").replace(  "%20" , " " );
333
334
			// Some clients like Trillian and Kopete itself send a font
335
			// name of 'MS Serif' since MS changed the server to
336
			// _require_ a font name specified in june 2002.
337
			// MSN's own client defaults to 'MS Sans Serif', which also
338
			// has issues.
339
			// Handle 'MS Serif' and 'MS Sans Serif' as an empty font name
340
			if( !fontName.isEmpty() && fontName != "MS Serif" && fontName != "MS Sans Serif" )
341
			{
342
				TQString ef=parseFontAttr( fontInfo, "EF" );
343
344
				font = TQFont( fontName,
345
					parseFontAttr( fontInfo, "PF" ).toInt(), // font size
346
					ef.contains( 'B' ) ? TQFont::Bold : TQFont::Normal,
347
					ef.contains( 'I' ) );
348
				font.setUnderline(ef.contains( 'U' ));
349
				font.setStrikeOut(ef.contains( 'S' ));
350
			}
351
		}
352
353
		TQPtrList<Kopete::Contact> others;
354
		others.append( m_account->myself() );
355
		TQStringList::iterator it2;
356
		for( it2 = m_chatMembers.begin(); it2 != m_chatMembers.end(); ++it2 )
357
		{
358
			if( *it2 != m_msgHandle )
359
				others.append( m_account->contacts()[ *it2 ] );
360
		}
361
362
		TQString message=msg.right( msg.length() - msg.find("\r\n\r\n") - 4 );
363
364
		//Stupid MSN PLUS colors code. message with incorrect charactere are not showed correctly in the chatwindow.
365
		//TODO: parse theses one to show the color too in Kopete
366
		message.replace("\3","").replace("\4","").replace("\2","").replace("\5","").replace("\6","").replace("\7","");
367
368
		if(!m_account->contacts()[m_msgHandle])
369
		{
370
			//this may happens if the contact has been deleted.
371
			kdDebug(14140) << k_funcinfo <<"WARNING: contact is null, adding it" <<endl;
372
			if( !m_chatMembers.contains( m_msgHandle ) )
373
				m_chatMembers.append( m_msgHandle );
374
			emit userJoined( m_msgHandle , m_msgHandle , false);
375
		}
376
377
		Kopete::Message kmsg( m_account->contacts()[ m_msgHandle ], others,
378
			message,
379
			Kopete::Message::Inbound , Kopete::Message::PlainText );
380
381
		kmsg.setFg( fontColor );
382
		kmsg.setFont( font );
383
384
		rx=TQRegExp("Chunks: ([0-9]*)");
385
		rx.search(msg);
386
		unsigned int chunks=rx.cap(1).toUInt();
387
		rx=TQRegExp("Chunk: ([0-9]*)");
388
		rx.search(msg);
389
		unsigned int chunk=rx.cap(1).toUInt();
390
391
		if(chunk != 0 && !m_msgQueue.isEmpty())
392
		{
393
			TQString msg=m_msgQueue.last().plainBody();
394
    		m_msgQueue.pop_back(); //removes the last item
395
    		kmsg.setBody( msg+ message, Kopete::Message::PlainText );
396
		}
397
398
    	if(chunk == 0 )
399
			m_chunks=chunks;
400
		else if(chunk+1 >=  m_chunks)
401
			m_chunks=0;
402
403
		if ( m_recvIcons > 0  || m_chunks > 0)
404
		{ //Some custom emoticons are waiting to be received. so append the message to the queue
405
		  //Or the message has not been fully received, so same thing
406
			kdDebug(14140) << k_funcinfo << "Message not fully received => append to queue.  Emoticon left: " << m_recvIcons << "  chunks: " << chunk+1 << " of " << m_chunks   <<endl;
407
			m_msgQueue.append( kmsg );
408
			if(!m_emoticonTimer) //to be sure no message will be lost, we will appends message to
409
			{                    // the queue in 15 secondes even if we have not received emoticons
410
				m_emoticonTimer=new TQTimer(this);
411
				TQObject::connect(m_emoticonTimer , TQT_SIGNAL(timeout()) , this, TQT_SLOT(cleanQueue()));
412
				m_emoticonTimer->start( 15000 , true );
413
			}
414
		}
415
		else
416
			emit msgReceived( parseCustomEmoticons( kmsg ) );
417
418
	}
419
	else if( type== "text/x-mms-emoticon" || type== "text/x-mms-animemoticon")
420
	{
421
		// TODO remove Displatcher.
422
		TDEConfig *config = TDEGlobal::config();
423
		config->setGroup( "MSN" );
424
		if ( config->readBoolEntry( "useCustomEmoticons", true ) )
425
		{
426
			TQRegExp rx("([^\\s]*)[\\s]*(<msnobj [^>]*>)");
427
			rx.setMinimal(true);
428
			int pos = rx.search(msg);
429
			while( pos != -1)
430
			{
431
				TQString msnobj=rx.cap(2);
432
				TQString txt=rx.cap(1);
433
				kdDebug(14140) << k_funcinfo << "emoticon: " <<  txt << "    msnobj: " << msnobj<<  endl;
434
435
				if( !m_emoticons.contains(msnobj) || !m_emoticons[msnobj].second )
436
				{
437
					m_emoticons.insert(msnobj, tqMakePair(txt,(KTempFile*)0L));
438
					MSNContact *c=static_cast<MSNContact*>(m_account->contacts()[m_msgHandle]);
439
					if(!c)
440
						return;
441
442
					// we are receiving emoticons, so delay message display until received signal
443
					m_recvIcons++;
444
					PeerDispatcher()->requestDisplayIcon(m_msgHandle, msnobj);
445
				}
446
				pos=rx.search(msg, pos+rx.matchedLength());
447
			}
448
		}
449
	}
450
	else if( type== "application/x-msnmsgrp2p" )
451
	{
452
		PeerDispatcher()->slotReadMessage(m_msgHandle, bytes);
453
	}
454
	else if( type == "text/x-clientcaps" )
455
	{
456
		rx=TQRegExp("Client-Name: ([A-Za-z0-9.$!*/% \\-]*)");
457
		rx.search(msg);
458
		clientStr=unescape( rx.cap(1) );
459
460
		if( !clientStr.isNull() && !m_msgHandle.isNull())
461
		{
462
			Kopete::Contact *c=m_account->contacts()[m_msgHandle];
463
			if(c)
464
				c->setProperty(  MSNProtocol::protocol()->propClient , clientStr );
465
		}
466
467
		if(!m_clientcapsSent)
468
		{
469
			TDEConfig *config = TDEGlobal::config();
470
			config->setGroup( "MSN" );
471
472
			TQString JabberID;
473
			if(config->readBoolEntry("SendJabber", true))
474
				JabberID=config->readEntry("JabberAccount");
475
476
			if(!JabberID.isEmpty())
477
				JabberID="JabberID: "+JabberID +"\r\n";
478
479
			if( config->readBoolEntry("SendClientInfo", true)   ||  !JabberID.isEmpty())
480
			{
481
482
				TQCString message = TQString( "MIME-Version: 1.0\r\n"
483
						"Content-Type: text/x-clientcaps\r\n"
484
						"Client-Name: Kopete/"+escape(kapp->aboutData()->version())+"\r\n"
485
						+JabberID+
486
						"\r\n" ).utf8();
487
488
				TQString args = "U";
489
				sendCommand( "MSG", args, true, message );
490
			}
491
			m_clientcapsSent=true;
492
		}
493
494
495
	}
496
	else if(type == "image/gif" || msg.contains("Message-ID:"))
497
	{
498
		// Incoming inkformatgif.
499
		TQRegExp regex("Message-ID: \\{([0-9A-F\\-]*)\\}");
500
		regex.search(msg);
501
		TQString messageId = regex.cap(1);
502
		regex = TQRegExp("Chunks: (\\d+)");
503
		regex.search(msg);
504
		TQString chunks = regex.cap(1);
505
		regex = TQRegExp("Chunk: (\\d+)");
506
		regex.search(msg);
507
		TQString chunk = regex.cap(1);
508
509
		if(!messageId.isNull())
510
		{
511
			bool valid = true;
512
			// Retrieve the nmber of data chunks.
513
			TQ_UINT32 numberOfChunks = chunks.toUInt(&valid);
514
			if(valid && (numberOfChunks > 1))
515
			{
516
				regex = TQRegExp("base64:([0-9a-zA-Z+/=]+)");
517
				regex.search(msg);
518
				// Retrieve the first chunk of the ink format gif.
519
				TQString base64 = regex.cap(1);
520
				// More chunks are expected, buffer the chunk received.
521
				InkMessage inkMessage;
522
				inkMessage.chunks = numberOfChunks;
523
				inkMessage.data += base64;
524
				m_inkMessageBuffer.insert(messageId, inkMessage);
525
			}
526
		}
527
		else
528
		{
529
			// There is only one chunk of data.
530
			regex = TQRegExp("base64:([0-9a-zA-Z+/=]*)");
531
			regex.search(msg);
532
			// Retrieve the base64 encoded ink data.
533
			TQString data = regex.cap(1);
534
			DispatchInkMessage(data);
535
		}
536
537
		if(!messageId.isNull())
538
		{
539
			if(m_inkMessageBuffer.contains(messageId))
540
			{
541
				if(chunks.isNull())
542
				{
543
					InkMessage inkMessage = m_inkMessageBuffer[messageId];
544
					inkMessage.data += msg.section("\r\n\r\n", -1);
545
					if(inkMessage.chunks == chunk.toUInt() + 1)
546
					{
547
						DispatchInkMessage(inkMessage.data);
548
						// Remove the ink message from the buffer.
549
						m_inkMessageBuffer.remove(messageId);
550
					}
551
				}
552
			}
553
		}
554
	}
555
	else
556
	{
557
		kdDebug(14140) << k_funcinfo <<" Unknown type '" << type << "' message: \n"<< msg <<endl;
558
	}
559
}
560
561
void MSNSwitchBoardSocket::DispatchInkMessage(const TQString& base64String)
562
{
563
	TQByteArray image;
564
	// Convert from base64 encoded string to byte array.
565
	KCodecs::base64Decode(base64String.utf8() , image);
566
	KTempFile *inkImage = new KTempFile(locateLocal( "tmp", "inkformatgif-" ), ".gif");
567
	inkImage->setAutoDelete(true);
568
	inkImage->file()->writeBlock(image.data(), image.size());
569
	inkImage->file()->close();
570
571
	slotEmoticonReceived(inkImage , "inkformatgif");
572
	inkImage = 0l;
573
}
574
575
void MSNSwitchBoardSocket::sendTypingMsg( bool isTyping )
576
{
577
	if( !isTyping )
578
		return;
579
580
	if ( onlineStatus() != Connected || m_chatMembers.empty())
581
	{
582
		//we are not yet in a chat.
583
		//if we send that command now, we may get disconnected.
584
		return;
585
	}
586
587
588
	TQCString message = TQString( "MIME-Version: 1.0\r\n"
589
		"Content-Type: text/x-msmsgscontrol\r\n"
590
		"TypingUser: " + m_myHandle + "\r\n"
591
		"\r\n" ).utf8();
592
593
	// Length is appended by sendCommand()
594
	TQString args = "U";
595
	sendCommand( "MSG", args, true, message );
596
}
597
598
// this Invites an Contact
599
void MSNSwitchBoardSocket::slotInviteContact(const TQString &handle)
600
{
601
	m_msgHandle=handle;
602
	sendCommand( "CAL", handle );
603
}
604
//
605
// Send a custum emoticon
606
//
607
int MSNSwitchBoardSocket::sendCustomEmoticon(const TQString &name, const TQString &filename)
608
{
609
	TQString picObj;
610
611
	//try to find it in the cache.
612
	const TQMap<TQString, TQString> objectList = PeerDispatcher()->objectList;
613
	for (TQMap<TQString,TQString>::ConstIterator it = objectList.begin(); it != objectList.end(); ++it )
614
	{
615
		if(it.data() == filename)
616
		{
617
			picObj=it.key();
618
			break;
619
		}
620
	}
621
622
	if(picObj.isNull())
623
	{ //if not found in the cache, generate the picture object
624
		TQFileInfo fi(filename);
625
		// open the icon file
626
		TQFile pictFile(fi.filePath());
627
		if (pictFile.open(IO_ReadOnly)) {
628
629
			TQByteArray ar = pictFile.readAll();
630
			pictFile.close();
631
632
			TQString sha1d = TQString(KCodecs::base64Encode(SHA1::hash(ar)));
633
			TQString size = TQString::number( pictFile.size() );
634
			TQString all = "Creator" + m_account->accountId() +	"Size" + size + "Type2Location" + fi.fileName() + "FriendlyAAA=SHA1D" + sha1d;
635
			TQString sha1c = TQString(KCodecs::base64Encode(SHA1::hashString(all.utf8())));
636
			picObj = "<msnobj Creator=\"" + m_account->accountId() + "\" Size=\"" + size  + "\" Type=\"2\" Location=\""+ fi.fileName() + "\" Friendly=\"AAA=\" SHA1D=\""+sha1d+ "\" SHA1C=\""+sha1c+"\"/>";
637
638
			PeerDispatcher()->objectList.insert(picObj, filename);
639
		}
640
		else
641
			return 0;
642
	}
643
644
	TQString msg = "MIME-Version: 1.0\r\n"
645
				"Content-Type: text/x-mms-emoticon\r\n"
646
				"\r\n" +
647
				name + "\t" + picObj + "\t\r\n";
648
649
	return sendCommand("MSG", "A", true, msg.utf8());
650
651
}
652
653
// this sends a short message to the server
654
int MSNSwitchBoardSocket::sendMsg( const Kopete::Message &msg )
655
{
656
	if ( onlineStatus() != Connected || m_chatMembers.empty())
657
	{
658
//		m_messagesQueue.append(msg);
659
		return -1;
660
	}
661
662
#if 0   //this is to test webcam
663
	if(msg.plainBody().contains("/webcam"))
664
	{
665
		PeerDispatcher()->startWebcam( m_myHandle , m_msgHandle);
666
		return -3;
667
	}
668
#endif
669
670
	TDEConfig *config = TDEGlobal::config();
671
	config->setGroup( "MSN" );
672
	if ( config->readBoolEntry( "exportEmoticons", false ) )
673
	{
674
		TQMap<TQString, TQStringList> emap = Kopete::Emoticons::self()->emoticonAndPicList();
675
676
		// Check the list for any custom emoticons
677
		for (TQMap<TQString, TQStringList>::const_iterator itr = emap.begin(); itr != emap.end(); itr++)
678
		{
679
			for ( TQStringList::const_iterator itr2 = itr.data().constBegin(); itr2 != itr.data().constEnd(); ++itr2 )
680
			{
681
				if ( msg.plainBody().contains( *itr2 ) )
682
					sendCustomEmoticon( *itr2, itr.key() );
683
			}
684
		}
685
	}
686
687
	if( msg.format() & Kopete::Message::RichText )
688
	{
689
		TQRegExp regex("^\\s*<img src=\"([^>\"]+)\"[^>]*>\\s*$");
690
		if(regex.search(msg.escapedBody()) != -1)
691
		{
692
			// FIXME why are we sending the images.. the contact should request them.
693
			PeerDispatcher()->sendImage(regex.cap(1), m_msgHandle);
694
			return -3;
695
		}
696
	}
697
698
	// User-Agent is not a official flag, but PIDGIN has it
699
	TQString UA;
700
	if( config->readBoolEntry("SendClientInfo", true) )
701
	{
702
		UA="User-Agent: Kopete/"+escape(kapp->aboutData()->version())+"\r\n";
703
	}
704
705
	TQString head =
706
		"MIME-Version: 1.0\r\n"
707
		"Content-Type: text/plain; charset=UTF-8\r\n"
708
		+UA+
709
		"X-MMS-IM-Format: ";
710
711
	if(msg.font() != TQFont() )
712
	{
713
		//It's verry strange that if the font name is bigger than 31 char, the _server_ close the socket and don't deliver the message.
714
		//  the real question is why ?   my guess is that MS patched the server because a bug in their client,  but that's just a guess.
715
		//      - Olivier   06-2005
716
		head += "FN=" + escape( msg.font().family().left(31));
717
		head += "; EF=";
718
		if(msg.font().bold())
719
			head += "B";
720
		if(msg.font().italic())
721
			head += "I";
722
		if(msg.font().strikeOut())
723
			head += "S";
724
		if(msg.font().underline())
725
			head += "U";
726
		head += "; ";
727
	}
728
	else head+="FN=; EF=; ";
729
	/*
730
	 * I don't know what to set by default, so i decided to set nothing.  CF Bug 82734
731
	 * (but don't forgeto to add an empty FN= and EF= ,  or webmessenger will break. (CF Bug 102371) )
732
	else head+="FN=MS%20Serif; EF=; ";
733
	 */
734
735
	// Color support
736
	if (msg.fg().isValid())
737
	{
738
		TQString colorCode = TQColor(msg.fg().blue(),msg.fg().green(),msg.fg().red()).name().remove(0,1);  //colors aren't sent in RGB but in BGR (O.G.)
739
		head += "CO=" + colorCode;
740
	}
741
	else
742
	{
743
		head += "CO=0";
744
	}
745
746
	head += "; CS=0; PF=0";
747
	if (msg.plainBody().isRightToLeft())
748
		head += "; RL=1";
749
	head += "\r\n";
750
751
	TQString message= msg.plainBody().replace(  "\n" , "\r\n" );
752
753
	//-- Check if the message isn't too big,  TODO: do that at the libkopete level.
754
	int len_H=head.utf8().length();	// != head.length()  because i need the size in butes and
755
	int len_M=message.utf8().length();	//    some utf8 char may be longer than one byte
756
	if( len_H+len_M >= 1660 ) //1664 is the maximum size of messages allowed by the server
757
	{
758
		//We will certenly split the message in several ones.
759
		//It's possible to made the opposite client join them, as explained in this MS Word document
760
		//http://www.bot-depot.com/forums/index.php?act=Attach&type=post&id=35110
761
762
		head+="Message-ID: {7B7B34E6-7A8D-44FF-926C-1799156B58"+TQString::number( rand()%10)+TQString::number( rand()%10)+"}\r\n";
763
		int len_H=head.utf8().length()+ 14;   //14 is the size of "Chunks: x"
764
		//this is the size of each part of the message (excluding the header)
765
		int futurmessages_size=1400;  //1400 is a common good size
766
		//int futurmessages_size=1664-len_H;
767
768
		int nb=(int)ceil((float)(len_M)/(float)(futurmessages_size));
769
770
		if(KMessageBox::warningContinueCancel(0L /* FIXME: we should try to find a parent somewere*/ ,
771
			i18n("The message you are trying to send is too long; it will be split into %1 messages.").arg(nb) ,
772
			i18n("Message too big - MSN Plugin" ), KStdGuiItem::cont() , "SendLongMessages" )
773
				== KMessageBox::Continue )
774
		{
775
			int place=0;
776
			int result;
777
			int chunk=0;
778
			do
779
			{
780
				TQString m=message.mid(place, futurmessages_size);
781
				place += futurmessages_size;
782
783
				//make sure the size is not too big because of utf8
784
				int d=m.utf8().length() + len_H -1664;
785
				if( d > 0 )
786
				{//it contains some utf8 chars, so we strip the string a bit.
787
					m=m.left( futurmessages_size - d );
788
					place -= d;
789
				}
790
791
				//try to snip on space if possible
792
				int len=m.length();
793
				d=0;
794
				while(d<200 && !m[len-d].isSpace() )
795
					d++;
796
				if(d<200)
797
				{
798
					m=m.left(len-d);
799
					place -= d;
800
				}
801
				TQString chunk_str;
802
				if(chunk==0)
803
					chunk_str="Chunks: "+TQString::number(nb)+"\r\n";
804
				else if(chunk<nb)
805
					chunk_str="Chunk: "+TQString::number(chunk)+"\r\n";
806
				else
807
				{
808
					kdDebug(14140) << k_funcinfo <<"The message is slit in more than initially estimated" <<endl;
809
				}
810
				result=sendCommand( "MSG", "A", true, (head+chunk_str+"\r\n"+m).utf8() );
811
				chunk++;
812
			}
813
			while(place < len_M) ;
814
815
			while(chunk<nb)
816
			{
817
				kdDebug(14140) << k_funcinfo <<"The message is plit in less than initially estimated.  Sending empty message to complete" <<endl;
818
				TQString chunk_str="Chunk: "+TQString::number(chunk);
819
				sendCommand( "MSG", "A", true, (head+chunk_str+"\r\n").utf8() );
820
				chunk++;
821
			}
822
			return result;
823
		}
824
		return -2;  //the message hasn't been sent.
825
	}
826
	
827
	if(!m_keepAlive)
828
	{
829
		m_keepAliveNb=20;
830
		m_keepAlive=new TQTimer(this);
831
		TQObject::connect(m_keepAlive, TQT_SIGNAL(timeout()) , this , TQT_SLOT(slotKeepAliveTimer()));
832
		m_keepAlive->start(50*1000);
833
	}
834
835
	
836
	return sendCommand( "MSG", "A", true, (head+"\r\n"+message).utf8() );
837
}
838
839
void MSNSwitchBoardSocket::slotSocketClosed( )
840
{
841
	for( TQStringList::Iterator it = m_chatMembers.begin(); it != m_chatMembers.end(); ++it )
842
	{
843
		emit userLeft( (*it), i18n("connection closed"));
844
	}
845
846
	// we have lost the connection, send a message to chatwindow (this will not displayed)
847
//	emit switchBoardIsActive(false);
848
	emit switchBoardClosed( );
849
}
850
851
void MSNSwitchBoardSocket::slotCloseSession()
852
{
853
	sendCommand( "OUT", TQString(), false );
854
	disconnect();
855
}
856
857
// Check if we are connected. If so, then send the handshake.
858
void MSNSwitchBoardSocket::slotOnlineStatusChanged( MSNSocket::OnlineStatus status )
859
{
860
	if (status == Connected)
861
	{
862
		TQCString command;
863
		TQString args;
864
865
		if( !m_ID ) // we're inviting
866
		{
867
			command = "USR";
868
			args = m_myHandle + " " + m_auth;
869
		}
870
		else // we're invited
871
		{
872
			command = "ANS";
873
			args = m_myHandle + " " + m_auth + " " + m_ID;
874
		}
875
		sendCommand( command, args );
876
		
877
		if(!m_keepAlive)
878
		{
879
			m_keepAliveNb=20;
880
			m_keepAlive=new TQTimer(this);
881
			TQObject::connect(m_keepAlive, TQT_SIGNAL(timeout()) , this , TQT_SLOT(slotKeepAliveTimer()));
882
			m_keepAlive->start(50*1000);
883
		}
884
	}
885
}
886
887
void MSNSwitchBoardSocket::userLeftChat(const TQString& handle , const TQString &reason)
888
{
889
	emit userLeft( handle,  reason );
890
891
	if( m_chatMembers.contains( handle ) )
892
		m_chatMembers.remove( handle );
893
894
	if(m_chatMembers.isEmpty())
895
		disconnect();
896
}
897
898
void MSNSwitchBoardSocket::requestDisplayPicture()
899
{
900
	MSNContact *contact = static_cast<MSNContact*>(m_account->contacts()[m_msgHandle]);
901
	if(!contact) return;
902
903
	PeerDispatcher()->requestDisplayIcon(m_msgHandle, contact->object());
904
}
905
906
void  MSNSwitchBoardSocket::slotEmoticonReceived( KTempFile *file, const TQString &msnObj )
907
{
908
	kdDebug(14141) << k_funcinfo << msnObj << endl;
909
910
	if(m_emoticons.contains(msnObj))
911
	{ //it's an emoticon
912
		m_emoticons[msnObj].second=file;
913
914
		if( m_recvIcons > 0 )
915
			m_recvIcons--;
916
		kdDebug(14140) << k_funcinfo << "emoticons received queue is now: " << m_recvIcons << endl;
917
918
		if ( m_recvIcons <= 0 )
919
			cleanQueue();
920
	}
921
	else if(msnObj == "inkformatgif")
922
	{
923
		TQString msg=i18n("<img src=\"%1\" alt=\"Typewrited message\" />" ).arg( file->name() );
924
925
		kdDebug(14140) << k_funcinfo << file->name()  <<endl;
926
927
		m_typewrited.append(file);
928
		m_typewrited.setAutoDelete(true);
929
930
		TQPtrList<Kopete::Contact> others;
931
		others.append( m_account->myself() );
932
933
		TQStringList::iterator it2;
934
		for( it2 = m_chatMembers.begin(); it2 != m_chatMembers.end(); ++it2 )
935
		{
936
			if( *it2 != m_msgHandle )
937
				others.append( m_account->contacts()[ *it2 ] );
938
		}
939
940
		if(!m_account->contacts()[m_msgHandle])
941
		{
942
			//this may happens if the contact has been deleted.
943
			kdDebug(14140) << k_funcinfo <<"WARNING: contact is null, adding it" <<endl;
944
			if( !m_chatMembers.contains( m_msgHandle ) )
945
				m_chatMembers.append( m_msgHandle );
946
			emit userJoined( m_msgHandle , m_msgHandle , false);
947
		}
948
949
		Kopete::Message kmsg( m_account->contacts()[ m_msgHandle ], others,
950
			msg, Kopete::Message::Inbound , Kopete::Message::RichText );
951
952
		emit msgReceived(  kmsg  );
953
	}
954
	else //if it is not an emoticon,
955
	{    // it's certenly the displaypicture.
956
		MSNContact *c=static_cast<MSNContact*>(m_account->contacts()[m_msgHandle]);
957
		if(c && c->object()==msnObj)
958
			c->setDisplayPicture(file);
959
		else
960
			delete file;
961
	}
962
}
963
964
void MSNSwitchBoardSocket::slotIncomingFileTransfer(const TQString& from, const TQString& /*fileName*/, TQ_INT64 /*fileSize*/)
965
{
966
	TQPtrList<Kopete::Contact> others;
967
	others.append( m_account->myself() );
968
	TQStringList::iterator it2;
969
	for( it2 = m_chatMembers.begin(); it2 != m_chatMembers.end(); ++it2 )
970
	{
971
		if( *it2 != m_msgHandle )
972
			others.append( m_account->contacts()[ *it2 ] );
973
	}
974
975
	if(!m_account->contacts()[m_msgHandle])
976
	{
977
		//this may happens if the contact has been deleted.
978
		kdDebug(14140) << k_funcinfo <<"WARNING: contact is null, adding it" <<endl;
979
		if( !m_chatMembers.contains( m_msgHandle ) )
980
			m_chatMembers.append( m_msgHandle );
981
		emit userJoined( m_msgHandle , m_msgHandle , false);
982
	}
983
	TQString invite = "Incoming file transfer.";
984
	Kopete::Message msg =
985
		Kopete::Message(m_account->contacts()[from], others, invite, Kopete::Message::Internal, Kopete::Message::PlainText);
986
	emit msgReceived(msg);
987
}
988
989
void MSNSwitchBoardSocket::cleanQueue()
990
{
991
	if(m_emoticonTimer)
992
	{
993
		m_emoticonTimer->stop();
994
		m_emoticonTimer->deleteLater();
995
		m_emoticonTimer=0L;
996
	}
997
	kdDebug(14141) << k_funcinfo << m_msgQueue.count() << endl;
998
999
	TQValueList<const Kopete::Message>::Iterator it_msg;
1000
	for ( it_msg = m_msgQueue.begin(); it_msg != m_msgQueue.end(); ++it_msg )
1001
	{
1002
	 	Kopete::Message kmsg = (*it_msg);
1003
	 	emit msgReceived( parseCustomEmoticons( kmsg ) );
1004
	}
1005
	m_msgQueue.clear();
1006
}
1007
1008
Kopete::Message &MSNSwitchBoardSocket::parseCustomEmoticons(Kopete::Message &kmsg)
1009
{
1010
	TQString message=kmsg.escapedBody();
1011
	TQMap<TQString , TQPair<TQString , KTempFile*> >::Iterator it;
1012
	for ( it = m_emoticons.begin(); it != m_emoticons.end(); ++it )
1013
	{
1014
		TQString es=TQStyleSheet::escape(it.data().first);
1015
		KTempFile *f=it.data().second;
1016
		if(message.contains(es) && f)
1017
		{
1018
			TQString imgPath = f->name();
1019
			TQImage iconImage(imgPath);
1020
			/* We don't use a comple algoritm (like the one in the #if)  because the msn client shows
1021
		     * emoticons like that. So, in that case, we show like the MSN client */
1022
			#if 0
1023
			TQString em = TQRegExp::escape( es );
1024
			message.replace( TQRegExp(TQString::fromLatin1( "(^|[\\W\\s]|%1)(%2)(?!\\w)" ).arg(em).arg(em)),
1025
								TQString::fromLatin1("\\1<img align=\"center\" width=\"") +
1026
			#endif
1027
			//match any occurence which is not in a html tag.
1028
			message.replace( TQRegExp(TQString::fromLatin1("%1(?![^><]*>)").arg(TQRegExp::escape(es))),
1029
						TQString::fromLatin1("<img align=\"center\" width=\"") +
1030
						TQString::number(iconImage.width()) +
1031
						TQString::fromLatin1("\" height=\"") +
1032
						TQString::number(iconImage.height()) +
1033
						TQString::fromLatin1("\" src=\"") + imgPath +
1034
						TQString::fromLatin1("\" title=\"") + es +
1035
						TQString::fromLatin1("\" alt=\"") + es +
1036
						TQString::fromLatin1( "\"/>" ) );
1037
			kmsg.setBody(message, Kopete::Message::RichText);
1038
		}
1039
	}
1040
	return kmsg;
1041
}
1042
1043
int MSNSwitchBoardSocket::sendNudge()
1044
{
1045
	TQCString message = TQString( "MIME-Version: 1.0\r\n"
1046
			"Content-Type: text/x-msnmsgr-datacast\r\n"
1047
			"\r\n"
1048
			"ID: 1\r\n"
1049
			"\r\n\r\n" ).utf8();
1050
1051
	TQString args = "U";
1052
	return sendCommand( "MSG", args, true, message );
1053
}
1054
1055
1056
1057
// FIXME: This is nasty... replace with a regexp or so.
1058
TQString MSNSwitchBoardSocket::parseFontAttr(TQString str, TQString attr)
1059
{
1060
	TQString tmp;
1061
	int pos1=0, pos2=0;
1062
1063
	pos1 = str.find(attr + "=");
1064
1065
	if (pos1 == -1)
1066
		return "";
1067
1068
	pos2 = str.find(";", pos1+3);
1069
1070
	if (pos2 == -1)
1071
		tmp = str.mid(pos1+3, str.length() - pos1 - 3);
1072
	else
1073
		tmp = str.mid(pos1+3, pos2 - pos1 - 3);
1074
1075
	return tmp;
1076
}
1077
1078
Dispatcher* MSNSwitchBoardSocket::PeerDispatcher()
1079
{
1080
	if(!m_dispatcher)
1081
	{
1082
		// Create a new msnslp dispatcher to handle
1083
		// all peer to peer requests.
1084
		TQStringList ip;
1085
		if(m_account->notifySocket())
1086
		{
1087
			ip << m_account->notifySocket()->localIP();
1088
			if(m_account->notifySocket()->localIP() != m_account->notifySocket()->getLocalIP())
1089
				ip << m_account->notifySocket()->getLocalIP();
1090
		}
1091
		m_dispatcher = new Dispatcher(this, m_account->accountId(),ip );
1092
1093
// 		TQObject::connect(this, TQT_SIGNAL(blockRead(const TQByteArray&)), m_dispatcher, TQT_SLOT(slotReadMessage(const TQByteArray&)));
1094
// 		TQObject::connect(m_dispatcher, TQT_SIGNAL(sendCommand(const TQString&, const TQString&, bool, const TQByteArray&, bool)), this, TQT_SLOT(sendCommand(const TQString&, const TQString&, bool, const TQByteArray&, bool)));
1095
		TQObject::connect(m_dispatcher, TQT_SIGNAL(incomingTransfer(const TQString&, const TQString&, TQ_INT64)), this, TQT_SLOT(slotIncomingFileTransfer(const TQString&, const TQString&, TQ_INT64)));
1096
		TQObject::connect(m_dispatcher, TQT_SIGNAL(displayIconReceived(KTempFile *, const TQString&)), this, TQT_SLOT(slotEmoticonReceived( KTempFile *, const TQString&)));
1097
		TQObject::connect(this, TQT_SIGNAL(msgAcknowledgement(unsigned int, bool)), m_dispatcher, TQT_SLOT(messageAcknowledged(unsigned int, bool)));
1098
		m_dispatcher->m_pictureUrl = m_account->pictureUrl();
1099
	}
1100
	return m_dispatcher;
1101
}
1102
1103
void MSNSwitchBoardSocket::slotKeepAliveTimer( )
1104
{
1105
	/*
1106
	This is a workaround against the bug 113425
1107
	The problem:  the P2P::Webcam class is parent of us, and when we get deleted, it get deleted.
1108
			the correct solution would be to change that.
1109
	The second problem: after one minute of inactivity, the official client close the chat socket.
1110
	the workaround: we simulate the activity by sending small packet each 50 seconds
1111
	the nice side effect:  the "xxx has closed the chat" is now meaningfull
1112
	the bad side effect:  some switchboard connection may be maintained for really long time!
1113
	 */
1114
	
1115
	if ( onlineStatus() != Connected || m_chatMembers.empty())
1116
	{
1117
		//we are not yet in a chat.
1118
		//if we send that command now, we may get disconnected.
1119
		return;
1120
	}
1121
1122
1123
	TQCString message = TQString( "MIME-Version: 1.0\r\n"
1124
			"Content-Type: text/x-keepalive\r\n"
1125
			"\r\n" ).utf8();
1126
1127
	// Length is appended by sendCommand()
1128
	TQString args = "U";
1129
	sendCommand( "MSG", args, true, message );
1130
	
1131
	m_keepAliveNb--;
1132
	if(m_keepAliveNb <= 0)
1133
	{
1134
		m_keepAlive->deleteLater();
1135
		m_keepAlive=0L;
1136
	}
1137
}
1138
1139
#include "msnswitchboardsocket.moc"
1140
1141
// vim: set noet ts=4 sts=4 sw=4:
1142
(-)tdenetwork.ori/kopete/protocols/msn/msnswitchboardsocket.h (-167 lines)
Lines 1-167 Link Here
1
/*
2
    msnswitchboardsocket.h - switch board connection socket
3
4
    Copyright (c) 2002      by Martijn Klingens       <klingens@kde.org>
5
    Copyright (c) 2002-2006 by Olivier Goffart        <ogoffart@ kde.org>
6
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
7
8
    Portions of this code are taken from KMerlin,
9
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>
10
11
    *************************************************************************
12
    *                                                                       *
13
    * This program is free software; you can redistribute it and/or modify  *
14
    * it under the terms of the GNU General Public License as published by  *
15
    * the Free Software Foundation; either version 2 of the License, or     *
16
    * (at your option) any later version.                                   *
17
    *                                                                       *
18
    *************************************************************************
19
*/
20
21
#ifndef MSNSWITCHBOARDSOCKET_H
22
#define MSNSWITCHBOARDSOCKET_H
23
24
#include <tqobject.h>
25
#include <tqstrlist.h>
26
#include <tqvaluevector.h>
27
28
#include <kstringhandler.h>
29
30
#include "msnsocket.h"
31
32
namespace Kopete { class Message; }
33
class MSNAccount;
34
class TQTimer;
35
36
class MSNP2PDisplatcher;
37
class KTempFile;
38
39
namespace P2P { class Dispatcher; }
40
41
#include "dispatcher.h"
42
43
class KOPETE_EXPORT MSNSwitchBoardSocket : public MSNSocket
44
{
45
	Q_OBJECT
46
  
47
48
public:
49
	/**
50
	 * Contructor: id is the KopeteMessageMangager's id
51
	 */
52
	MSNSwitchBoardSocket( MSNAccount * account , TQObject *parent);
53
	~MSNSwitchBoardSocket();
54
55
private:
56
	P2P::Dispatcher *m_dispatcher;
57
	MSNAccount *m_account;
58
59
	TQString m_myHandle; // our handle
60
61
	// contains the handle of the last person that msg'ed us.
62
	// since we receive the actual message by readBlock(), we need
63
	// to remember what the handle was of the person sending us the message.
64
	TQString m_msgHandle;
65
66
	TQString m_ID;
67
	TQString m_auth;
68
	TQStringList m_chatMembers;
69
70
	//used for emoticons
71
	TQValueList<const Kopete::Message> m_msgQueue;
72
	unsigned  m_recvIcons;
73
	TQMap<TQString , TQPair<TQString , KTempFile*> >  m_emoticons;
74
	Kopete::Message &parseCustomEmoticons(Kopete::Message &msg);
75
	TQTimer *m_emoticonTimer;
76
	TQPtrList<KTempFile> m_typewrited;
77
78
	struct InkMessage{
79
		TQ_UINT32 chunks;
80
		TQString data;
81
	};
82
	TQMap<TQString, InkMessage> m_inkMessageBuffer;
83
84
	/** the number of chunk for currents messages */
85
	unsigned int m_chunks;
86
87
	/** true is we already sent the x-clientcaps message */
88
	bool m_clientcapsSent;
89
90
private:
91
	void DispatchInkMessage(const TQString &base64String);
92
93
protected:
94
	/**
95
	 * Handle an MSN command response line.
96
	 */
97
	virtual void parseCommand( const TQString &cmd, uint id,
98
		const TQString &data );
99
100
	/**
101
	 * Handle exceptions that might occur during a chat.
102
	 */
103
	virtual void handleError( uint code, uint id );
104
105
	TQString parseFontAttr( TQString str, TQString attr );
106
107
108
public:
109
	void connectToSwitchBoard( TQString ID, TQString address, TQString auth );
110
	void setHandle( TQString handle ) { m_myHandle = handle; }
111
	void setMsgHandle( TQString handle ) { m_msgHandle = handle; }
112
113
	const TQStringList &chatMembers() { return m_chatMembers; }
114
115
	void userLeftChat( const TQString &handle , const TQString &reason );
116
	int  sendMsg( const Kopete::Message &msg );
117
    int  sendCustomEmoticon(const TQString &name, const TQString &filename);
118
119
	int sendNudge();
120
121
	P2P::Dispatcher* PeerDispatcher();
122
123
public slots:
124
	void slotCloseSession();
125
	void slotInviteContact(const TQString &handle);
126
127
	/**
128
	 * Notify the server that the user is typing a message
129
	 */
130
	void sendTypingMsg( bool isTyping );
131
132
	void requestDisplayPicture();
133
	
134
	/** workaround Bug 113425 . see slotKeepAliveTimer() **/
135
	TQTimer *m_keepAlive;
136
	int m_keepAliveNb;
137
	
138
139
140
private slots:
141
	void slotOnlineStatusChanged( MSNSocket::OnlineStatus status );
142
	void slotSocketClosed(  );
143
	void slotReadMessage( const TQByteArray &bytes );
144
	void slotEmoticonReceived( KTempFile *, const TQString& );
145
	void slotIncomingFileTransfer(const TQString& from, const TQString& fileName, TQ_INT64 fileSize);
146
	void cleanQueue();
147
	
148
	/** workaround Bug 113425 . see comment inside the function **/
149
	void slotKeepAliveTimer();
150
151
signals:
152
	void msgReceived( Kopete::Message &msg );
153
	void receivedTypingMsg( const TQString &contactId, bool isTyping );
154
	void msgAcknowledgement(unsigned int, bool);
155
	void userJoined(const TQString& handle , const TQString &publicName , bool IRO);
156
	void userLeft(const TQString& handle , const TQString &reason);
157
	void nudgeReceived(const TQString &handle);
158
159
	void switchBoardClosed(  );
160
	void invitation(const TQString& handle, const TQString& msg);
161
162
};
163
164
#endif
165
166
// vim: set noet ts=4 sts=4 sw=4:
167
(-)tdenetwork.ori/kopete/protocols/msn/outgoingtransfer.cpp (-432 lines)
Lines 1-432 Link Here
1
/*
2
    outgoingtransfer.cpp - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include "outgoingtransfer.h"
18
19
#include <stdlib.h>
20
21
// Kde includes
22
#include <kbufferedsocket.h>
23
#include <kdebug.h>
24
#include <tdelocale.h>
25
#include <kmdcodec.h>
26
using namespace KNetwork;
27
28
// TQt includes
29
#include <tqfile.h>
30
#include <tqregexp.h>
31
#include <tqtimer.h>
32
33
// Kopete includes
34
#include <kopetetransfermanager.h>
35
36
#include <netinet/in.h> // For htonl
37
using P2P::TransferContext;
38
using P2P::Dispatcher;
39
using P2P::OutgoingTransfer;
40
using P2P::Message;
41
42
OutgoingTransfer::OutgoingTransfer(const TQString& to, P2P::Dispatcher *dispatcher, TQ_UINT32 sessionId)
43
: TransferContext(to,dispatcher,sessionId)
44
{
45
	m_direction = Outgoing;
46
	m_handshake = 0x01;
47
}
48
49
OutgoingTransfer::~OutgoingTransfer()
50
{
51
	kdDebug(14140) << k_funcinfo << endl;
52
}
53
54
void OutgoingTransfer::sendImage(const TQByteArray& image)
55
{
56
57
// 	TODO TQByteArray base64 = KCodecs::base64Encode(image);
58
//
59
// 	TQCString body = "MIME-Version: 1.0\r\n"
60
// 		"Content-Type: image/gif\r\n"
61
// 		"\r\n"
62
// 		"base64:" +
63
//
64
// 	Message outbound;
65
// 	outbound.header.sessionId  = m_sessionId;
66
// 	outbound.header.identifier = m_baseIdentifier;
67
// 	outbound.header.dataOffset = 0;
68
// 	outbound.header.totalDataSize = 4;
69
// 	outbound.header.dataSize = 4;
70
// 	outbound.header.flag = 0;
71
// 	outbound.header.ackSessionIdentifier = rand()%0x8FFFFFF0 + 4;
72
// 	outbound.header.ackUniqueIdentifier  = 0;
73
// 	outbound.header.ackDataSize   = 0l;
74
// 	TQByteArray bytes(4);
75
// 	bytes.fill('\0');
76
// 	outbound.body = bytes;
77
// 	outbound.applicationIdentifier = 0;
78
// 	outbound.attachApplicationId = false;
79
// 	outbound.destination = m_recipient;
80
//
81
// 	sendMessage(outbound, body);
82
}
83
84
void OutgoingTransfer::slotSendData()
85
{
86
	TQ_INT32 bytesRead = 0;
87
	TQByteArray buffer(1202);
88
	if(!m_file)
89
		return;
90
91
	// Read a chunk from the source file.
92
	bytesRead = m_file->readBlock(buffer.data(), buffer.size());
93
	
94
	if (bytesRead < 0) {
95
		m_file->close();
96
                // ### error handling
97
        }
98
	else {
99
100
		if(bytesRead < 1202){
101
			buffer.resize(bytesRead);
102
		}
103
104
		kdDebug(14140) << k_funcinfo << TQString("Sending, %1 bytes").arg(bytesRead) << endl;
105
106
		if((m_offset + bytesRead) < m_file->size())
107
		{
108
			sendData(buffer);
109
			m_offset += bytesRead;
110
		}
111
		else
112
		{
113
			m_isComplete = true;
114
			// Send the last chunk of the file.
115
			sendData(buffer);
116
			m_offset += buffer.size();
117
			// Close the file.
118
			m_file->close();
119
		}
120
	}
121
122
	if(m_transfer){
123
		m_transfer->slotProcessed(m_offset);
124
		if(m_isComplete){
125
			// The transfer is complete.
126
			m_transfer->slotComplete();
127
		}
128
	}
129
}
130
131
void OutgoingTransfer::acknowledged()
132
{
133
	kdDebug(14140) << k_funcinfo << endl;
134
135
	switch(m_state)
136
	{
137
		case Invitation:
138
		{
139
			if(m_type == UserDisplayIcon)
140
			{
141
				m_state = Negotiation;
142
				// Send data preparation message.
143
				sendDataPreparation();
144
			}
145
			break;
146
		}
147
148
		case Negotiation:
149
		{
150
			if(m_type == UserDisplayIcon)
151
			{
152
				// <<< Data preparation acknowledge message.
153
				m_state = DataTransfer;
154
				m_identifier++;
155
				// Start sending data.
156
				slotSendData();
157
			}
158
			break;
159
		}
160
161
		case DataTransfer:
162
			// NOTE <<< Data acknowledged message.
163
			// <<< Bye message should follow.
164
			if(m_type == File)
165
			{
166
				if(m_handshake == 0x01)
167
				{
168
					// Data handshake acknowledge message.
169
					// Start sending data.
170
					slotSendData();
171
				}
172
				else if(m_handshake == 0x02)
173
				{
174
					// Data acknowledge message.
175
					// Send the recipient a BYE message.
176
					m_state = Finished;
177
					sendMessage(BYE, "\r\n");
178
				}
179
			}
180
181
			break;
182
183
		case Finished:
184
			if(m_type == File)
185
			{
186
				// BYE acknowledge message.
187
				m_dispatcher->detach(this);
188
			}
189
190
			break;
191
	}
192
}
193
194
void OutgoingTransfer::processMessage(const Message& message)
195
{
196
	TQString body =
197
		TQCString(message.body.data(), message.header.dataSize);
198
	kdDebug(14140) << k_funcinfo << "received, " << body << endl;
199
200
	if(body.startsWith("BYE"))
201
	{
202
		m_state = Finished;
203
		// Send the recipient an acknowledge message.
204
		acknowledge(message);
205
		if(!m_isComplete)
206
		{
207
			// The peer cancelled the transfer.
208
			if(m_transfer)
209
			{
210
				// Inform the user of the file transfer cancelation.
211
				m_transfer->slotError(TDEIO::ERR_ABORTED, i18n("File transfer canceled."));
212
			}
213
		}
214
		// Dispose of this transfer context.
215
		m_dispatcher->detach(this);
216
	}
217
	else if(body.startsWith("MSNSLP/1.0 200 OK"))
218
	{
219
		// Retrieve the message content type.
220
		TQRegExp regex("Content-Type: ([A-Za-z0-9$!*/\\-]*)");
221
		regex.search(body);
222
		TQString contentType = regex.cap(1);
223
224
		if(contentType == "application/x-msnmsgr-sessionreqbody")
225
		{
226
			// Recipient has accepted the file transfer.
227
			// Acknowledge the recipient.
228
			acknowledge(message);
229
230
			// Try to open the file for reading.
231
			// If an error occurs, send an internal
232
			// error message to the recipient.
233
			if(!m_file->open(IO_ReadOnly)){
234
				error();
235
				return;
236
			}
237
238
			// Retrieve the receiving client's contact.
239
			Kopete::Contact *contact = m_dispatcher->getContactByAccountId(m_recipient);
240
			if(contact == 0l)
241
			{
242
				error();
243
				return;
244
			}
245
246
			m_transfer =
247
				Kopete::TransferManager::transferManager()->addTransfer(contact, m_file->name(), m_file->size(), m_recipient, Kopete::FileTransferInfo::Outgoing);
248
249
			TQObject::connect(m_transfer , TQT_SIGNAL(transferCanceled()), this, TQT_SLOT(abort()));
250
251
			m_state = Negotiation;
252
253
			m_branch = P2P::Uid::createUid();
254
255
			// Send the direct connection invitation message.
256
			TQString content = "Bridges: TRUDPv1 TCPv1\r\n" +
257
				TQString("NetID: %1\r\n").arg("-123657987") +
258
				TQString("Conn-Type: %1\r\n").arg("Restrict-NAT") +
259
				"UPnPNat: false\r\n"
260
				"ICF: false\r\n" +
261
				TQString("Hashed-Nonce: {%1}\r\n").arg(P2P::Uid::createUid()) +
262
				"\r\n";
263
			sendMessage(INVITE, content);
264
		}
265
		else if(contentType == "application/x-msnmsgr-transrespbody")
266
		{
267
			// Determine whether the recipient created
268
			// a listening endpoint.
269
			regex = TQRegExp("Listening: ([^\r\n]+)\r\n");
270
			regex.search(body);
271
			bool isListening = (regex.cap(1) == "true");
272
273
			// Send the recipient an acknowledge message.
274
			acknowledge(message);
275
276
			m_state = DataTransfer;
277
278
#if 1
279
			isListening = false; // TODO complete direct connection.
280
#endif
281
			if(isListening)
282
			{
283
				// Retrieve the hashed nonce for this direct connection instance.
284
				regex = TQRegExp("Hashed-Nonce: \\{([0-9A-F\\-]*)\\}\r\n");
285
				regex.search(body);
286
				m_nonce = regex.cap(1);
287
				// Retrieve the listening endpoints of the receiving client.
288
				regex = TQRegExp("IPv4Internal-Addrs: ([^\r\n]+)\r\n");
289
				regex.search(body);
290
				m_peerEndpoints = TQStringList::split(" ", regex.cap(1));
291
				m_endpointIterator = m_peerEndpoints.begin();
292
				// Retrieve the listening port of the receiving client.
293
				regex = TQRegExp("IPv4Internal-Port: ([^\r\n]+)\r\n");
294
				regex.search(body);
295
				m_remotePort = regex.cap(1);
296
297
				// Try to connect to the receiving client's
298
				// listening endpoint.
299
				connectToEndpoint(*m_endpointIterator);
300
			}
301
			else
302
			{
303
				m_handshake = 0x02;
304
				// Otherwise, send data through the already
305
				// existing session.
306
				slotSendData();
307
			}
308
		}
309
	}
310
	else if(body.startsWith("MSNSLP/1.0 603 Decline"))
311
	{
312
		// File transfer has been cancelled remotely.
313
		// Send an acknowledge message
314
		acknowledge(message);
315
		if(m_transfer)
316
		{
317
			// Inform the user of the file transfer cancelation.
318
			m_transfer->slotError(TDEIO::ERR_ABORTED, i18n("File transfer canceled."));
319
		}
320
321
		if(m_file && m_file->isOpen()){
322
			// Close the file.
323
			m_file->close();
324
		}
325
		m_dispatcher->detach(this);
326
	}
327
}
328
329
void OutgoingTransfer::readyToSend()
330
{
331
	if(m_isComplete){
332
		// Ignore, do nothing.
333
		return;
334
	}
335
336
	slotSendData();
337
}
338
339
void OutgoingTransfer::connectToEndpoint(const TQString& hostName)
340
{
341
	m_socket = new TDEBufferedSocket(hostName, m_remotePort);
342
	m_socket->setBlocking(false);
343
	m_socket->enableRead(true);
344
	// Disable write signal for now.  Only enable
345
	// when we are ready to sent data.
346
	// NOTE readyWrite consumes too much cpu usage.
347
	m_socket->enableWrite(false);
348
	TQObject::connect(m_socket, TQT_SIGNAL(readyRead()), this, TQT_SLOT(slotRead()));
349
	TQObject::connect(m_socket, TQT_SIGNAL(connected(const KResolverEntry&)), this, TQT_SLOT(slotConnected()));
350
	TQObject::connect(m_socket, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int)));
351
	TQObject::connect(m_socket, TQT_SIGNAL(closed()), this, TQT_SLOT(slotSocketClosed()));
352
	// Try to connect to the endpoint.
353
	m_socket->connect();
354
}
355
356
void OutgoingTransfer::slotConnected()
357
{
358
	kdDebug(14140) << k_funcinfo << endl;
359
	// Check if connection is ok.
360
	TQ_UINT32 bytesWritten = m_socket->writeBlock(TQCString("foo").data(), 4);
361
	if(bytesWritten != 4)
362
	{
363
		// Not all data was written, close the socket.
364
		m_socket->closeNow();
365
		// Schedule the data to be sent through the existing session.
366
		TQTimer::singleShot(2000, this, TQT_SLOT(slotSendData()));
367
		return;
368
	}
369
370
	// Send data handshake message.
371
	P2P::Message handshake;
372
	handshake.header.sessionId  = 0;
373
	handshake.header.identifier = ++m_identifier;
374
	handshake.header.dataOffset = 0l;
375
	handshake.header.totalDataSize = 0l;
376
	handshake.header.dataSize = 0;
377
	// Set the flag to indicate that this is
378
	// a direct connection handshake message.
379
	handshake.header.flag = 0x100;
380
	TQString nonce = m_nonce.remove('-');
381
	handshake.header.ackSessionIdentifier = nonce.mid(0, 8).toUInt(0, 16);
382
	handshake.header.ackUniqueIdentifier  =
383
		nonce.mid(8, 4).toUInt(0, 16) | (nonce.mid(12, 4).toUInt(0, 16) << 16);
384
	const TQ_UINT32 lo = nonce.mid(16, 8).toUInt(0, 16);
385
	const TQ_UINT32 hi = nonce.mid(24, 8).toUInt(0, 16);
386
	handshake.header.ackDataSize =
387
		((TQ_INT64)htonl(lo)) | (((TQ_INT64)htonl(hi)) << 32);
388
389
	TQByteArray stream;
390
	// Write the message to the memory stream.
391
	m_messageFormatter.writeMessage(handshake, stream, true);
392
	// Send the byte stream over the wire.
393
	m_socket->writeBlock(stream.data(), stream.size());
394
}
395
396
void OutgoingTransfer::slotRead()
397
{
398
	TQ_INT32 bytesAvailable = m_socket->bytesAvailable();
399
	kdDebug(14140) << k_funcinfo << bytesAvailable << ", bytes available." << endl;
400
}
401
402
void OutgoingTransfer::slotSocketError(int)
403
{
404
	kdDebug(14140) << k_funcinfo << m_socket->TDESocketBase::errorString() << endl;
405
	// If an error has occurred, try to connect
406
	// to another available peer endpoint.
407
	// If there are no more available endpoints,
408
	// send the data through the session.
409
	m_socket->closeNow();
410
411
	// Move to the next available endpoint.
412
	m_endpointIterator++;
413
	if(m_endpointIterator != m_peerEndpoints.end()){
414
		// Try to connect to the endpoint.
415
		connectToEndpoint(*m_endpointIterator);
416
	}
417
	else
418
	{
419
		// Otherwise, send the data through the session.
420
		m_identifier -= 1;
421
		TQTimer::singleShot(2000, this, TQT_SLOT(slotSendData()));
422
	}
423
}
424
425
void OutgoingTransfer::slotSocketClosed()
426
{
427
	kdDebug(14140) << k_funcinfo << endl;
428
	m_socket->deleteLater();
429
	m_socket = 0l;
430
}
431
432
#include "outgoingtransfer.moc"
(-)tdenetwork.ori/kopete/protocols/msn/outgoingtransfer.h (-60 lines)
Lines 1-60 Link Here
1
/*
2
    outgoingtransfer.h - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#ifndef OUTGOINGTRANSFER_H
18
#define OUTGOINGTRANSFER_H
19
20
#include "p2p.h"
21
#include "dispatcher.h"
22
#include <tqstringlist.h>
23
24
/**
25
@author Kopete Developers
26
*/
27
namespace P2P{
28
	class OutgoingTransfer : public TransferContext
29
	{	Q_OBJECT
30
  
31
		public:
32
			OutgoingTransfer(const TQString& to, P2P::Dispatcher *dispatcher, TQ_UINT32 sessionId);
33
			virtual ~OutgoingTransfer();
34
35
			void sendImage(const TQByteArray& image);
36
37
		private slots:
38
			void slotConnected();
39
			void slotRead();
40
			void slotSendData();
41
			void slotSocketError(int);
42
			void slotSocketClosed();
43
			
44
		private:
45
			virtual void acknowledged();
46
			void connectToEndpoint(const TQString& hostName);
47
			virtual void processMessage(const Message& message);
48
49
			TQStringList m_peerEndpoints;
50
			TQStringList::Iterator m_endpointIterator;
51
			TQString m_remotePort;
52
			TQString m_nonce;
53
			char m_handshake;
54
55
		protected:
56
			virtual void readyToSend();
57
	};
58
}
59
60
#endif
(-)tdenetwork.ori/kopete/protocols/msn/p2p.cpp (-412 lines)
Lines 1-412 Link Here
1
/*
2
    p2p.cpp - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include "p2p.h"
18
#include "dispatcher.h"
19
using P2P::TransferContext;
20
using P2P::Message;
21
using P2P::MessageType;
22
using P2P::TransferType;
23
24
#include <stdlib.h>
25
26
// Kde includes
27
#include <kbufferedsocket.h>
28
#include <kdebug.h>
29
// TQt includes
30
#include <tqfile.h>
31
32
// Kopete includes
33
#include <kopetetransfermanager.h>
34
35
TQString P2P::Uid::createUid()
36
{
37
	return (TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16)
38
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16) + "-"
39
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16) + "-"
40
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16) + "-"
41
			+ TQString::number(rand()%0xAAFF+0x1111, 16) + "-"
42
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16)
43
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16)
44
			+ TQString::number((unsigned long int)rand()%0xAAFF+0x1111, 16)).upper();
45
}
46
47
TransferContext::TransferContext(const TQString &contact, P2P::Dispatcher *dispatcher, TQ_UINT32 sessionId)
48
	: TQObject(dispatcher) ,
49
	   m_sessionId(sessionId) ,
50
	   m_identifier(0) ,
51
	   m_file(0) ,
52
	   m_transactionId (0),
53
	   m_ackSessionIdentifier (0) ,
54
	   m_ackUniqueIdentifier ( 0 ),
55
	   m_transfer ( 0l)  ,
56
57
	   m_baseIdentifier(rand()%0x0FFFFFF0 + 4),
58
	   m_dispatcher (dispatcher),
59
	   m_isComplete (false) ,
60
	   m_offset(0),
61
	   m_totalDataSize(0),
62
	   m_recipient(contact),
63
	   m_sender(dispatcher->localContact()),
64
	   m_socket(0),
65
	   m_state ( Invitation)
66
{
67
	m_type = File ;   //uh,  why??? -Olivier
68
}
69
70
TransferContext::~TransferContext()
71
{
72
	m_transfer = 0l;
73
74
	if(m_file){
75
		delete m_file;
76
		m_file = 0l;
77
	}
78
}
79
80
void TransferContext::acknowledge(const Message& message)
81
{
82
	kdDebug(14140) << k_funcinfo << m_dispatcher<< endl;
83
84
	Message outbound;
85
	outbound.header.sessionId = message.header.sessionId;
86
87
	if(m_identifier == 0){
88
		m_identifier = m_baseIdentifier;
89
	}
90
// 	else if(m_state == Finished && m_direction == Incoming){
91
// 		m_identifier = m_baseIdentifier - 1;
92
// 	}
93
	else if(m_state == Finished && m_direction == Outgoing){
94
		m_identifier = m_baseIdentifier + 1;
95
	}
96
	else
97
		++m_identifier;
98
99
	outbound.header.identifier    = m_identifier;
100
	outbound.header.dataOffset    = 0l;
101
	outbound.header.totalDataSize = message.header.totalDataSize;
102
	outbound.header.dataSize      = 0;
103
// 	if(m_type == UserDisplayIcon && m_state == Finished){
104
// 		if(m_direction == Outgoing){
105
// 			outbound.header.flag = 0x40;
106
// 		}
107
// 	}
108
// 	else
109
		outbound.header.flag = 2;
110
111
	outbound.header.ackSessionIdentifier = message.header.identifier;
112
	outbound.header.ackUniqueIdentifier  = message.header.ackSessionIdentifier;
113
	outbound.header.ackDataSize   = message.header.totalDataSize;
114
	// NOTE outbound.body is null by default
115
	outbound.applicationIdentifier = 0l;
116
	outbound.destination = m_recipient;
117
118
	TQByteArray stream;
119
	// Write the acknowledge message to the stream.
120
	m_messageFormatter.writeMessage(outbound, stream, (m_socket != 0l));
121
	if(!m_socket)
122
	{
123
		// Send the acknowledge message.
124
		m_dispatcher->callbackChannel()->send(stream);
125
	}
126
	else
127
	{
128
		// Send acknowledge message directly.
129
		m_socket->writeBlock(stream.data(), stream.size());
130
	}
131
}
132
133
void TransferContext::error()
134
{
135
	kdDebug(14140) << k_funcinfo << endl;
136
	sendMessage(ERROR);
137
	m_dispatcher->detach(this);
138
}
139
140
void TransferContext::sendData(const TQByteArray& bytes)
141
{
142
	Message outbound;
143
	outbound.header.sessionId  = m_sessionId;
144
	outbound.header.identifier = m_identifier;
145
	outbound.header.dataOffset = m_offset;
146
	if(m_file){
147
		outbound.header.totalDataSize = m_file->size();
148
	}
149
	else
150
		outbound.header.totalDataSize = m_totalDataSize;
151
152
	outbound.header.dataSize = bytes.size();
153
	if(m_type == UserDisplayIcon){
154
		outbound.header.flag = 0x20;
155
	}
156
	else if(m_type == P2P::File){
157
		outbound.header.flag = 0x01000030;
158
	}
159
	else  outbound.header.flag = 0;
160
161
	outbound.header.ackSessionIdentifier = rand()%0x8FFFFFF0 + 4;
162
	outbound.header.ackUniqueIdentifier  = 0;
163
	outbound.header.ackDataSize = 0l;
164
	outbound.body = bytes;
165
	outbound.applicationIdentifier = (uint)m_type;
166
167
	outbound.destination = m_recipient;
168
169
	TQByteArray stream;
170
	m_messageFormatter.writeMessage(outbound, stream, (m_socket != 0l));
171
	if(!m_socket)
172
	{
173
		// Send the data message.
174
 		m_transactionId = m_dispatcher->callbackChannel()->send(stream);
175
 	}
176
 	else
177
 	{
178
 		// Send data directly.
179
 		m_socket->writeBlock(stream.data(), stream.size());
180
 	}
181
}
182
183
void TransferContext::sendDataPreparation()
184
{
185
	kdDebug(14140) << k_funcinfo << endl;
186
187
	Message outbound;
188
	outbound.header.sessionId  = m_sessionId;
189
	outbound.header.identifier = ++m_identifier;
190
	outbound.header.dataOffset = 0;
191
	outbound.header.totalDataSize = 4;
192
	outbound.header.dataSize = 4;
193
	outbound.header.flag = 0;
194
	outbound.header.ackSessionIdentifier = rand()%0x8FFFFFF0 + 4;
195
	outbound.header.ackUniqueIdentifier  = 0;
196
	outbound.header.ackDataSize   = 0l;
197
	TQByteArray bytes(4);
198
	bytes.fill('\0');
199
	outbound.body = bytes;
200
	outbound.applicationIdentifier = 1;
201
	outbound.destination = m_recipient;
202
203
	TQByteArray stream;
204
	m_messageFormatter.writeMessage(outbound, stream);
205
	// Send the receiving client the data prepartion message.
206
 	m_dispatcher->callbackChannel()->send(stream);
207
}
208
209
void TransferContext::sendMessage(MessageType type, const TQString& content, TQ_INT32 flag, TQ_INT32 appId)
210
{
211
	Message outbound;
212
	if(appId != 0){
213
		outbound.header.sessionId = m_sessionId;
214
	}
215
	else
216
		outbound.header.sessionId = 0;
217
218
	if(m_identifier == 0){
219
		m_identifier = m_baseIdentifier;
220
	}
221
	else if(m_state == Invitation && m_direction == P2P::Outgoing && m_type == UserDisplayIcon)
222
	{
223
			m_identifier -= 3;
224
	}
225
	else if(m_state == Invitation && m_direction == P2P::Incoming && m_type == File)
226
	{
227
			m_identifier -= 3;
228
	}
229
	else
230
		++m_identifier;
231
232
	outbound.header.identifier = m_identifier;
233
	outbound.header.flag = flag;
234
	outbound.header.ackSessionIdentifier = m_ackSessionIdentifier;
235
	outbound.header.ackUniqueIdentifier  = m_ackUniqueIdentifier;
236
	outbound.header.ackDataSize = 0l;
237
	outbound.applicationIdentifier = appId;
238
	outbound.destination = m_recipient;
239
240
	TQString contentType, cSeq, method;
241
242
	switch(m_state)
243
	{
244
		case DataTransfer:
245
			contentType = "application/x-msnmsgr-transreqbody";
246
			if(m_type == File && m_direction == Incoming)
247
			{
248
				contentType = "application/x-msnmsgr-transrespbody";
249
			}
250
			break;
251
		case Finished:
252
			contentType = "application/x-msnmsgr-sessionclosebody";
253
			break;
254
		default:
255
			contentType = "application/x-msnmsgr-sessionreqbody";
256
			if(m_type == File && m_direction == Outgoing)
257
			{
258
				if(m_state == Negotiation){
259
					contentType = "application/x-msnmsgr-transreqbody";
260
				}
261
			}
262
			if(m_type == P2P::WebcamType && type==P2P::INVITE && m_state == Negotiation)
263
			{
264
				contentType = "application/x-msnmsgr-transreqbody";
265
			}
266
			break;
267
	}
268
269
	switch(type)
270
	{
271
		case BYE:
272
			method = "BYE MSNMSGR:" + m_recipient + " MSNSLP/1.0";
273
			cSeq   = "0";
274
			break;
275
276
		case DECLINE:
277
			method = "MSNSLP/1.0 603 DECLINE";
278
			cSeq   = "1";
279
			break;
280
281
		case ERROR:
282
			contentType = "null";
283
			method = "MSNSLP/1.0 500 Internal Error";
284
			cSeq   = "1";
285
			break;
286
287
		case INVITE:
288
			method = "INVITE MSNMSGR:" + m_recipient + " MSNSLP/1.0";
289
			cSeq   = "0";
290
			break;
291
292
		case OK:
293
			method = "MSNSLP/1.0 200 OK";
294
			cSeq   = "1";
295
			break;
296
	}
297
298
	TQCString body = TQString(method + "\r\n"
299
		"To: <msnmsgr:" + m_recipient + ">\r\n"
300
		"From: <msnmsgr:" + m_sender  + ">\r\n"
301
		"Via: MSNSLP/1.0/TLP ;branch={" + m_branch.upper() + "}\r\n"
302
		"CSeq: "+ cSeq +"\r\n"
303
		"Call-ID: {" + m_callId.upper() + "}\r\n"
304
		"Max-Forwards: 0\r\n"
305
		"Content-Type: " + contentType + "\r\n"
306
		"Content-Length: "+ TQString::number(content.length() + 1) + "\r\n"
307
		"\r\n" +
308
		content).utf8();
309
310
	// NOTE The body must have a null character at the end.
311
	// TQCString by chance automatically adds a \0 to the
312
	// end of the string.
313
314
	outbound.header.totalDataSize = body.size();
315
	// Send the outbound message.
316
	sendMessage(outbound, body);
317
}
318
319
void TransferContext::sendMessage(Message& outbound, const TQByteArray& body)
320
{
321
	TQ_INT64 offset = 0L, bytesLeft = outbound.header.totalDataSize;
322
	TQ_INT16 chunkLength = 1202;
323
324
	// Split the outbound message if necessary.
325
	while(bytesLeft > 0L)
326
	{
327
		if(bytesLeft < chunkLength)
328
		{
329
			// Copy the last chunk of the multipart message.
330
			outbound.body.duplicate(body.data() + offset, bytesLeft);
331
			outbound.header.dataSize = bytesLeft;
332
			outbound.header.dataOffset = offset;
333
			bytesLeft = 0L;
334
		}
335
		else
336
		{
337
			// Copy the next chunk of the multipart message in the sequence.
338
			outbound.body.duplicate(body.data() + offset, chunkLength);
339
			outbound.header.dataSize = chunkLength;
340
			outbound.header.dataOffset = offset;
341
			offset += chunkLength;
342
			bytesLeft -= offset;
343
		}
344
345
		kdDebug(14140) << k_funcinfo <<
346
			TQCString(outbound.body.data(), outbound.body.size())
347
			<< endl;
348
349
		TQByteArray stream;
350
		// Write the outbound message to the stream.
351
		m_messageFormatter.writeMessage(outbound, stream, (m_socket != 0l));
352
		if(!m_socket)
353
		{
354
			// Send the outbound message.
355
			m_dispatcher->callbackChannel()->send(stream);
356
		}
357
		else
358
		{
359
			// Send outbound message directly.
360
			m_socket->writeBlock(stream.data(), stream.size());
361
		}
362
	}
363
}
364
365
void TransferContext::setType(TransferType type)
366
{
367
	m_type = type;
368
}
369
370
void TransferContext::abort()
371
{
372
	kdDebug(14140) << k_funcinfo << endl;
373
	if(m_transfer)
374
	{
375
		if(m_transfer->error() == TDEIO::ERR_ABORTED)
376
		{
377
			switch(m_direction)
378
			{
379
				case P2P::Outgoing:
380
					if(m_type == File)
381
					{
382
						// Do nothing.
383
					}
384
					break;
385
386
				case P2P::Incoming:
387
					if(m_type == File)
388
					{
389
						// Do nothing.
390
					}
391
					break;
392
			}
393
		}
394
		else
395
		{
396
			m_state = Finished;
397
			sendMessage(BYE, "\r\n");
398
		}
399
	}
400
}
401
402
void TransferContext::readyWrite()
403
{
404
	if(m_direction == Outgoing && m_state == DataTransfer){
405
		readyToSend();
406
	}
407
}
408
409
void TransferContext::readyToSend()
410
{}
411
412
#include "p2p.moc"
(-)tdenetwork.ori/kopete/protocols/msn/p2p.h (-148 lines)
Lines 1-148 Link Here
1
/*
2
    p2p.h - msn p2p protocol
3
4
    Copyright (c) 2003-2005 by Olivier Goffart        <ogoffart@ kde.org>
5
    Copyright (c) 2005      by Gregg Edghill          <gregg.edghill@gmail.com>
6
7
    *************************************************************************
8
    *                                                                       *
9
    * This program is free software; you can redistribute it and/or modify  *
10
    * it under the terms of the GNU General Public License as published by  *
11
    * the Free Software Foundation; either version 2 of the License, or     *
12
    * (at your option) any later version.                                   *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#ifndef P2P_H
18
#define P2P_H
19
20
// TQt includes
21
#include <tqobject.h>
22
#include "messageformatter.h"
23
24
#include "kopete_export.h"
25
26
#include "config.h"
27
28
namespace Kopete { class Transfer; }
29
namespace Kopete { struct FileTransferInfo; }
30
namespace P2P { class Dispatcher; }
31
namespace KNetwork { class TDEBufferedSocket; }
32
class TQFile;
33
class KTempFile;
34
35
/**
36
@author Kopete Developers
37
*/
38
namespace System{
39
	class Guid
40
	{
41
		public:
42
			~Guid(){}
43
			static Guid newGuid();
44
			TQString toString();
45
46
		private:
47
			Guid(){}
48
	};
49
}
50
51
namespace P2P{
52
53
	enum TransferType { UserDisplayIcon = 1, File = 2, WebcamType=4};
54
	enum TransferDirection { Incoming = 1, Outgoing = 8};
55
	enum MessageType { BYE, OK, DECLINE, ERROR, INVITE };
56
57
	enum CommunicationState
58
	{
59
		Invitation   = 1,
60
		Negotiation  = 2,
61
		DataTransfer = 8,
62
		Finished     = 16
63
	};
64
65
	struct TransportHeader
66
	{
67
		TQ_UINT32 sessionId;
68
		TQ_UINT32 identifier;
69
		TQ_INT64  dataOffset;
70
		TQ_INT64  totalDataSize;
71
		TQ_UINT32 dataSize;
72
		TQ_UINT32 flag;
73
		TQ_UINT32 ackSessionIdentifier;
74
		TQ_UINT32 ackUniqueIdentifier;
75
		TQ_INT64  ackDataSize;
76
	};
77
78
	struct Message
79
	{
80
		public:
81
			TQString mimeVersion;
82
			TQString contentType;
83
			TQString destination;
84
			TQString source;
85
			TransportHeader header;
86
			TQByteArray body;
87
			TQ_INT32 applicationIdentifier;
88
			bool attachApplicationIdentifier;
89
	};
90
91
	class KOPETE_EXPORT Uid
92
	{
93
		public: static TQString createUid();
94
	};
95
96
	class KOPETE_EXPORT TransferContext : public TQObject
97
	{	Q_OBJECT
98
  
99
		public:
100
			virtual ~TransferContext();
101
102
			void acknowledge(const Message& message);
103
			virtual void acknowledged() = 0;
104
			void error();
105
			virtual void processMessage(const P2P::Message& message) = 0;
106
			void sendDataPreparation();
107
			void sendMessage(MessageType type, const TQString& content=TQString(), TQ_INT32 flag=0, TQ_INT32 appId=0);
108
			void setType(TransferType type);
109
110
		public:
111
			TQ_UINT32 m_sessionId;
112
			TQ_UINT32 m_identifier;
113
			TQFile   *m_file;
114
			TQ_UINT32 m_transactionId;
115
			TQ_UINT32 m_ackSessionIdentifier;
116
			TQ_UINT32 m_ackUniqueIdentifier;
117
			Kopete::Transfer *m_transfer;
118
			TQString  m_branch;
119
			TQString  m_callId;
120
			TQString  m_object;
121
122
123
		public slots:
124
			void abort();
125
			void readyWrite();
126
127
		protected:
128
			TransferContext(const TQString& contact, P2P::Dispatcher *dispatcher,TQ_UINT32 sessionId);
129
			void sendData(const TQByteArray& bytes);
130
			void sendMessage(P2P::Message& outbound, const TQByteArray& body);
131
			virtual void readyToSend();
132
133
			TQ_UINT32 m_baseIdentifier;
134
			TransferDirection m_direction;
135
			P2P::Dispatcher *m_dispatcher;
136
			bool m_isComplete;
137
			TQ_INT64 m_offset;
138
			TQ_INT64 m_totalDataSize;
139
			P2P::MessageFormatter m_messageFormatter;
140
			TQString m_recipient;
141
			TQString m_sender;
142
			KNetwork::TDEBufferedSocket *m_socket;
143
   			CommunicationState m_state;
144
   			TransferType m_type;
145
	};
146
}
147
148
#endif
(-)tdenetwork.ori/kopete/protocols/msn/ReleaseNotes (-31 lines)
Lines 1-31 Link Here
1
If you can bear with beta-quality code, we welcome you to try out this
2
highly improved plugin and use it as your primary instant messaging system!
3
Patches are always welcome on kopete-devel@kde.org. Trivial fixes can be
4
committed directly to KDE CVS if you have an account, but please coordinate
5
larger changes with us to avoid double work.
6
7
Thanks for your interest in Kopete!
8
9
                        October 2002, the Kopete team <kopete-devel@kde.org>
10
11
RELEASE NOTES FOR THE MSN PLUGIN IN KOPETE 0.5
12
13
Most of the MSN plugin has seen an enormous improvement since the previous
14
release, with many bugs fixed in all aspects of the plugin, most notably
15
the contact list handling and group chats. See the Changelog for a more
16
detailed description of what was changed in this release.
17
18
Some issues in MSN are still remaining though. We hope to fix them in the
19
next release, since we think they are not critical enough to delay this
20
release:
21
22
- MSN allows you to have multiple groups with the same name, because
23
  internally a group ID is used. Kopete currently uses the name as a unique
24
  identifier, however, and will likely get a bit confused by this. If you
25
  do experience problems, you could join both groups using another MSN
26
  client, like the official client, Trillian or Pidgin as a workaround.
27
28
- Kopete contacts can be at Top-Level and in no groups. MSN doesn't
29
  support this freature. The kopete's contact list can differe from server 
30
  if you have top-level contact
31
(-)tdenetwork.ori/kopete/protocols/msn/sha1.cpp (-192 lines)
Lines 1-192 Link Here
1
/*
2
 * sha1.cpp - Secure Hash Algorithm 1
3
 * Copyright (C) 2003  Justin Karneges
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
 *
19
 */
20
21
#include "sha1.h"
22
23
/****************************************************************************
24
  SHA1 - from a public domain implementation by Steve Reid (steve@edmweb.com)
25
****************************************************************************/
26
27
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
28
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15]^block->l[(i+2)&15]^block->l[i&15],1))
29
30
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
31
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
32
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
33
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
34
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
35
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
36
37
38
SHA1::SHA1()
39
{
40
	int wordSize;
41
42
	tqSysInfo(&wordSize, &bigEndian);
43
}
44
45
unsigned long SHA1::blk0(TQ_UINT32 i)
46
{
47
	if(bigEndian)
48
		return block->l[i];
49
	else
50
		return (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF));
51
}
52
53
// Hash a single 512-bit block. This is the core of the algorithm.
54
void SHA1::transform(TQ_UINT32 state[5], unsigned char buffer[64])
55
{
56
	TQ_UINT32 a, b, c, d, e;
57
58
	block = (CHAR64LONG16*)buffer;
59
60
	// Copy context->state[] to working vars
61
	a = state[0];
62
	b = state[1];
63
	c = state[2];
64
	d = state[3];
65
	e = state[4];
66
67
	// 4 rounds of 20 operations each. Loop unrolled.
68
	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
69
	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
70
	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
71
	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
72
	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
73
	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
74
	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
75
	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
76
	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
77
	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
78
	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
79
	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
80
	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
81
	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
82
	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
83
	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
84
	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
85
	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
86
	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
87
	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
88
89
	// Add the working vars back into context.state[]
90
	state[0] += a;
91
	state[1] += b;
92
	state[2] += c;
93
	state[3] += d;
94
	state[4] += e;
95
96
	// Wipe variables
97
	a = b = c = d = e = 0;
98
}
99
100
// SHA1Init - Initialize new context
101
void SHA1::init(SHA1_CONTEXT* context)
102
{
103
	// SHA1 initialization constants
104
	context->state[0] = 0x67452301;
105
	context->state[1] = 0xEFCDAB89;
106
	context->state[2] = 0x98BADCFE;
107
	context->state[3] = 0x10325476;
108
	context->state[4] = 0xC3D2E1F0;
109
	context->count[0] = context->count[1] = 0;
110
}
111
112
// Run your data through this
113
void SHA1::update(SHA1_CONTEXT* context, unsigned char* data, TQ_UINT32 len)
114
{
115
	TQ_UINT32 i, j;
116
117
	j = (context->count[0] >> 3) & 63;
118
	if((context->count[0] += len << 3) < (len << 3))
119
		context->count[1]++;
120
121
	context->count[1] += (len >> 29);
122
123
	if((j + len) > 63) {
124
		memcpy(&context->buffer[j], data, (i = 64-j));
125
		transform(context->state, context->buffer);
126
		for ( ; i + 63 < len; i += 64) {
127
			transform(context->state, &data[i]);
128
		}
129
		j = 0;
130
	}
131
	else i = 0;
132
		memcpy(&context->buffer[j], &data[i], len - i);
133
}
134
135
// Add padding and return the message digest
136
void SHA1::final(unsigned char digest[20], SHA1_CONTEXT* context)
137
{
138
	TQ_UINT32 i, j;
139
	unsigned char finalcount[8];
140
141
	for (i = 0; i < 8; i++) {
142
		finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
143
		>> ((3-(i & 3)) * 8) ) & 255);  // Endian independent
144
	}
145
	update(context, (unsigned char *)"\200", 1);
146
	while ((context->count[0] & 504) != 448) {
147
		update(context, (unsigned char *)"\0", 1);
148
	}
149
	update(context, finalcount, 8);  // Should cause a transform()
150
	for (i = 0; i < 20; i++) {
151
		digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
152
	}
153
154
	// Wipe variables
155
	i = j = 0;
156
	memset(context->buffer, 0, 64);
157
	memset(context->state, 0, 20);
158
	memset(context->count, 0, 8);
159
	memset(&finalcount, 0, 8);
160
}
161
162
TQByteArray SHA1::hash(const TQByteArray &a)
163
{
164
	SHA1_CONTEXT context;
165
	TQByteArray b(20);
166
167
	SHA1 s;
168
	s.init(&context);
169
	s.update(&context, (unsigned char *)a.data(), (unsigned int)a.size());
170
	s.final((unsigned char *)b.data(), &context);
171
	return b;
172
}
173
174
TQByteArray SHA1::hashString(const TQCString &cs)
175
{
176
	TQByteArray a(cs.length());
177
	memcpy(a.data(), cs.data(), a.size());
178
	return SHA1::hash(a);
179
}
180
181
TQString SHA1::digest(const TQString &in)
182
{
183
	TQByteArray a = SHA1::hashString(in.utf8());
184
	TQString out;
185
	for(int n = 0; n < (int)a.size(); ++n) {
186
		TQString str;
187
		str.sprintf("%02x", (uchar)a[n]);
188
		out.append(str);
189
	}
190
191
	return out;
192
}
(-)tdenetwork.ori/kopete/protocols/msn/sha1.h (-59 lines)
Lines 1-59 Link Here
1
/*
2
 * sha1.h - Secure Hash Algorithm 1
3
 * Copyright (C) 2003  Justin Karneges
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
 *
19
 */
20
21
#ifndef CS_SHA1_H
22
#define CS_SHA1_H
23
24
#include <tqstring.h>
25
26
class SHA1
27
{
28
public:
29
	static TQByteArray hash(const TQByteArray &);
30
	static TQByteArray hashString(const TQCString &);
31
	static TQString digest(const TQString &);
32
33
private:
34
	SHA1();
35
36
	struct SHA1_CONTEXT
37
	{
38
		TQ_UINT32 state[5];
39
		TQ_UINT32 count[2];
40
		unsigned char buffer[64];
41
	};
42
43
	typedef union {
44
		unsigned char c[64];
45
		TQ_UINT32 l[16];
46
	} CHAR64LONG16;
47
48
	void transform(TQ_UINT32 state[5], unsigned char buffer[64]);
49
	void init(SHA1_CONTEXT* context);
50
	void update(SHA1_CONTEXT* context, unsigned char* data, TQ_UINT32 len);
51
	void final(unsigned char digest[20], SHA1_CONTEXT* context);
52
53
	unsigned long blk0(TQ_UINT32 i);
54
	bool bigEndian;
55
56
	CHAR64LONG16* block;
57
};
58
59
#endif
(-)tdenetwork.ori/kopete/protocols/msn/TODO (-5 lines)
Lines 1-5 Link Here
1
Some things to think about as of 2003/04/15
2
(according to Gof)
3
Adding 'search for user'
4
Adding MSN chatroom protocol
5
Add MSN alerts
(-)tdenetwork.ori/kopete/protocols/msn/transport.cpp (-356 lines)
Lines 1-356 Link Here
1
/*
2
    transport.cpp - Peer to peer transport
3
4
    Copyright (c) 2005 by Gregg Edghill     <gregg.edghill@gmail.com>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; version 2 of the License.               *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#include "transport.h"
18
#include "messageformatter.h"
19
20
//BEGIN QT Includes
21
//END
22
23
//BEGIN KDE Includes
24
#include <kclientsocketbase.h>
25
#include <kdebug.h>
26
#include <kstreamsocket.h>
27
//END
28
29
//BEGIN Using Directives
30
using namespace KNetwork;
31
//END
32
33
#include "msnswitchboardsocket.h"
34
35
namespace PeerToPeer {
36
37
Transport::Transport(TQObject* parent, const char* name)
38
 : TQObject(parent, name)
39
{
40
	mFormatter = new PeerToPeer::MessageFormatter(this);
41
}
42
43
44
Transport::~Transport()
45
{
46
}
47
48
//BEGIN Public Methods
49
50
TransportBridge* Transport::getBridge (const TQString& to, TQ_UINT16 port, TransportBridgeType type, const TQString& identifier)
51
{
52
	TransportBridge *bridge = 0l;
53
	KInetSocketAddress address;
54
	if (mAddresses.contains(to))
55
	{
56
		address = mAddresses[to];
57
	}
58
	else
59
	{
60
		address = KInetSocketAddress(KIpAddress(to), port);
61
		mAddresses[to] = address;
62
	}
63
64
	if (PeerToPeer::Tcp == type){
65
		bridge = new TcpTransportBridge(address, mFormatter, this, identifier.ascii());
66
	}
67
68
	if (PeerToPeer::Udp == type){
69
// TODO Add class UdpTransportBridge
70
// 		bridge = new UdpTransportBridge(address, this, mFormatter, identifier.ascii());
71
	}
72
73
	if (bridge != 0l)
74
	{
75
		TQObject::connect(bridge, TQT_SIGNAL(readyRead(const TQByteArray&)), TQT_SLOT(slotOnReceive(const TQByteArray&)));
76
	}
77
	
78
	return 0l;
79
}
80
81
void Transport::setDefaultBridge(MSNSwitchBoardSocket* mss)
82
{
83
	mDefaultBridge = mss;
84
	TQObject::connect((MSNSwitchBoardSocket*)mDefaultBridge, TQT_SIGNAL(messageReceived(const TQString&, const TQByteArray&)), TQT_SLOT(slotOnReceive(const TQString&, const TQByteArray&)));
85
}
86
87
//END
88
89
//BEGIN Private Slot Methods
90
91
// void Transport::slotOnReceive(Message& message)
92
// {
93
// }
94
95
void Transport::slotOnReceive(const TQString& contact, const TQByteArray& bytes)
96
{
97
	kdDebug (14140) << k_funcinfo << " >> RECEIVED " << bytes.size() << " bytes." << endl;
98
// 	Message message = mFormatter->readMessage(bytes);
99
}
100
101
//END
102
103
104
105
106
TransportBridge::TransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, TQObject* parent, const char* name)
107
: TQObject(parent, name)
108
{
109
	mAddress = to;
110
	mFormatter = formatter;
111
}
112
113
TransportBridge::TransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, TQObject* parent, const char* name)
114
: TQObject(parent, name)
115
{
116
	mSocket = socket;
117
	mAddress = mSocket->peerAddress();
118
}
119
120
TransportBridge::~TransportBridge()
121
{
122
}
123
124
//BEGIN Public Methods
125
126
void TransportBridge::connect()
127
{
128
	slotOnConnect();
129
}
130
131
void TransportBridge::disconnect()
132
{
133
	slotOnDisconnect();
134
}
135
136
//END
137
138
//BEGIN Protected Slot Methods
139
140
void TransportBridge::slotOnConnect()
141
{
142
}
143
144
void TransportBridge::slotOnDisconnect()
145
{
146
}
147
148
void TransportBridge::slotOnError(int)
149
{
150
}
151
152
void TransportBridge::slotOnSocketClose()
153
{
154
}
155
156
void TransportBridge::slotOnSocketConnect()
157
{
158
}
159
160
void TransportBridge::slotOnSocketReceive()
161
{
162
}
163
164
165
//END
166
167
168
169
TcpTransportBridge::TcpTransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, TQObject* parent, const char* name)
170
: TransportBridge(to, formatter, parent, name)
171
{	
172
	mSocket = new KStreamSocket(mAddress.ipAddress().toString(), TQString::number(mAddress.port()), this);
173
	mSocket->setBlocking(false);
174
	TQObject::connect(mSocket, TQT_SIGNAL(connected(const KResolverEntry&)), TQT_SLOT(slotOnSocketConnect()));
175
	TQObject::connect(mSocket, TQT_SIGNAL(gotError(int)), TQT_SLOT(slotOnError(int)));
176
	mConnected = false;
177
}
178
179
TcpTransportBridge::TcpTransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, TQObject* parent, const char* name)
180
: TransportBridge(socket, formatter, parent, name)
181
{
182
	mConnected = (mSocket->state() == KStreamSocket::Open) ? true : false;
183
	mSocket->setBlocking(false);
184
}
185
186
TcpTransportBridge::~TcpTransportBridge()
187
{
188
}
189
190
//BEGIN Protected Slot Methods
191
192
void TcpTransportBridge::slotOnConnect()
193
{
194
	if (mConnected)
195
	{
196
		kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") ALREADY CONNECTED " << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString() << endl;
197
		return;
198
	}
199
200
	KStreamSocket *socket = static_cast<KStreamSocket*>(mSocket);
201
	socket->setTimeout(5000);
202
	TQObject::connect(socket, TQT_SIGNAL(timeOut()), TQT_SLOT(slotOnSocketConnectTimeout()));
203
	mSocket->connect();
204
}
205
206
void TcpTransportBridge::slotOnDisconnect()
207
{
208
	if (mConnected){
209
		mSocket->close();
210
	}
211
}
212
213
void TcpTransportBridge::slotOnError(int errorCode)
214
{
215
	kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") ERROR occurred on {" << mSocket->localAddress().toString() << " <-> " << mSocket->peerAddress().toString() << "} - " << mSocket->errorString() << endl;
216
	emit bridgeError(TQString("Bridge ERROR %1: %2").arg(errorCode).arg(mSocket->errorString()));
217
	if (mConnected){
218
		mSocket->disconnect();
219
		mConnected = false;
220
	}
221
	mSocket->deleteLater();
222
	mSocket = 0l;
223
}
224
225
void TcpTransportBridge::slotOnSocketClose()
226
{
227
	mSocket->disconnect();
228
	kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") DISCONNECTED {" << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString() << "}" << endl;
229
	mConnected = false;
230
	mSocket->deleteLater();
231
	mSocket = 0l;
232
233
	emit bridgeDisconnect();
234
}
235
236
void TcpTransportBridge::slotOnSocketConnect()
237
{
238
	kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") CONNECTED to " << mSocket->peerAddress().toString() << " from "
239
		<< mSocket->localAddress().toString() << endl;
240
	mConnected = true;
241
242
	TQObject::connect(mSocket, TQT_SIGNAL(readyRead()), TQT_SLOT(slotOnSocketReceive()));
243
	TQObject::connect(mSocket, TQT_SIGNAL(closed()), TQT_SLOT(slotOnSocketClose()));
244
245
	mVerified = true;
246
	TQString foo = "foo\0";
247
	mSocket->writeBlock(foo.ascii(), foo.length());
248
	foo = TQString();
249
250
	emit bridgeConnect();
251
}
252
253
void TcpTransportBridge::slotOnSocketReceive()
254
{
255
	kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") RECEIVED " << mSocket->bytesAvailable() << " bytes." << endl;
256
	
257
	TQByteArray bytes(mSocket->bytesAvailable());
258
	mSocket->readBlock(bytes.data(), bytes.size());
259
	// Write the data to the buffer.
260
	mBuffer.write(bytes);
261
262
	if (mVerified == false && mBuffer.size() >= 4)
263
	{
264
		TQByteArray foo = mBuffer.read(4);
265
		if (TQString(foo) == "foo"){
266
			kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") CONNECTION verified." << endl;
267
			mVerified = true;
268
		}
269
	}
270
271
	while(mBuffer.size() > 0)
272
	{
273
		if (mBuffer.size() >= 4 && mLength == 0)
274
		{
275
			TQByteArray array = mBuffer.read(4);
276
			for (int i=0; i < 4; i++){
277
				((char*)mLength)[i] = array[i];
278
			}
279
		}
280
281
		if (mLength > 0 && mBuffer.size() >= mLength)
282
		{
283
			kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") read " << mLength << " bytes." << endl;
284
			bytes = mBuffer.read(mLength);
285
			mLength = 0;
286
// 			Message message = mFormatter->readMessage(bytes, true);
287
// 			emit messageReceived(message);
288
		}
289
		else
290
		{
291
			kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") waiting for " << mLength << " bytes." << endl;
292
			break;
293
		}
294
	}
295
}
296
297
//END
298
299
//BEGIN Private Slot Methods
300
301
void TcpTransportBridge::slotOnSocketConnectTimeout()
302
{
303
	kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") CONNECT timeout." << endl;
304
	emit bridgeConnectTimeout();
305
	mSocket->deleteLater();
306
	mSocket = 0l;
307
}
308
309
//END
310
311
312
313
314
TcpTransportBridge::Buffer::Buffer(TQ_UINT32 length)
315
: TQByteArray(length)
316
{
317
}
318
319
TcpTransportBridge::Buffer::~Buffer()
320
{
321
}
322
323
//BEGIN Public Methods
324
325
void TcpTransportBridge::Buffer::write(const TQByteArray& bytes)
326
{
327
	resize(size() + bytes.size());
328
	for (uint i=0; i < bytes.size(); i++){
329
		(*this)[size() + i] = bytes[i];
330
	}
331
}
332
333
TQByteArray TcpTransportBridge::Buffer::read(TQ_UINT32 length)
334
{
335
	if (length >= size()) return TQByteArray();
336
337
	TQByteArray buffer;
338
	buffer.duplicate(data(), length);
339
340
	char *bytes = new char[size() - length];
341
	for(uint i=0; i < size() - length; i++){
342
		bytes[i] = data()[length + i];
343
	}
344
345
	duplicate(bytes, size() - length);
346
	delete[] bytes;
347
	
348
	return buffer;
349
}
350
351
//END
352
353
}
354
355
#include "transport.moc"
356
(-)tdenetwork.ori/kopete/protocols/msn/transport.h (-170 lines)
Lines 1-170 Link Here
1
/*
2
    transport.h - Peer to peer transport
3
4
    Copyright (c) 2005 by Gregg Edghill     <gregg.edghill@gmail.com>
5
6
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
7
8
    *************************************************************************
9
    *                                                                       *
10
    * This program is free software; you can redistribute it and/or modify  *
11
    * it under the terms of the GNU General Public License as published by  *
12
    * the Free Software Foundation; version 2 of the License.               *
13
    *                                                                       *
14
    *************************************************************************
15
*/
16
17
#ifndef PEERTOPEERTRANSPORT_H
18
#define PEERTOPEERTRANSPORT_H
19
20
//BEGIN QT Includes
21
#include <tqobject.h>
22
#include <tqguardedptr.h>
23
#include <tqvaluelist.h>
24
//END
25
26
//BEGIN KDE Includes
27
#include <tdesocketaddress.h>
28
//END
29
30
namespace KNetwork {
31
class KClientSocketBase;
32
}
33
34
class MSNSwitchBoardSocket;
35
36
namespace PeerToPeer {
37
38
class MessageFormatter;
39
class TransportBridge;
40
41
enum TransportBridgeType
42
{
43
	Tcp = 1,
44
	Udp = 2
45
};
46
	
47
/**
48
 @author Gregg Edghill <gregg.edghill@gmail.com> */
49
/** @brief Represents the protocol used to send and receive message between peers. */
50
class Transport : public TQObject
51
{
52
	Q_OBJECT
53
  
54
public:
55
	/** @brief Creates a new instance of the class Transport. */
56
    Transport(TQObject* parent, const char* name = 0l);
57
    ~Transport();
58
	/** @brief Get a transport bridge with the specified address, port, type and identifier. */
59
    TransportBridge* getBridge(const TQString& address, TQ_UINT16 port, TransportBridgeType type, const TQString& identifier);
60
    /** @brief Sets the default transport bridge. */
61
	void setDefaultBridge(MSNSwitchBoardSocket* mss);
62
	
63
private slots:
64
	/** @brief Invokes when a message is received on a transport bridge. */
65
// 	void slotOnReceive(Message& message);
66
	/** @brief Invokes when a message is received on the default transport bridge (relay). */
67
	void slotOnReceive(const TQString& contact, const TQByteArray& bytes);
68
69
private:
70
	/** @brief Known SocketAddresses of peers. */
71
	TQMap<TQString, KNetwork::KInetSocketAddress> mAddresses;
72
	/** @brief The list the connected transport bridges. */
73
	TQValueList<TransportBridge*> mBridges;
74
	/** @brief The default transport bridge (relay). */
75
	TQGuardedPtr<MSNSwitchBoardSocket> mDefaultBridge;
76
	/** @brief Message formatter used to ser/deser message. */
77
	MessageFormatter *mFormatter;
78
};
79
80
/** @brief Represents the channel connecting two peers. */
81
class TransportBridge : public TQObject
82
{
83
	Q_OBJECT
84
  
85
public:
86
	virtual ~TransportBridge();
87
88
protected:
89
	/** @brief Creates a new instance of the class TransportBridge with the specified address and formatter. */
90
	TransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, TQObject* parent, const char* name = 0l);
91
	/** @brief Creates a new instance of the class TransportBridge with the specified socket and formatter. */
92
	TransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, TQObject* parent, const char* name = 0l);
93
94
public:
95
	/** @brief Creates a connection between two peers. */
96
	void connect();
97
	/** @brief Disconnects the connection between two peers. */
98
	void disconnect();
99
100
protected slots:
101
	virtual void slotOnConnect();
102
	virtual void slotOnDisconnect();
103
	virtual void slotOnError(int);
104
	virtual void slotOnSocketClose();
105
	virtual void slotOnSocketConnect();
106
	virtual void slotOnSocketReceive();
107
108
signals:
109
	void bridgeConnect();
110
	void bridgeDisconnect();
111
	void bridgeError(const TQString& e);
112
	void bytesReceived(const TQByteArray&);
113
	
114
protected:
115
	
116
	KNetwork::KInetSocketAddress mAddress;
117
	bool mConnected;
118
	MessageFormatter *mFormatter;
119
	TQ_UINT32 mLength;
120
	KNetwork::KClientSocketBase *mSocket;
121
	bool mVerified;
122
};
123
124
class TcpTransportBridge : public TransportBridge
125
{
126
	Q_OBJECT
127
  
128
	friend class Transport;
129
	
130
public:
131
	virtual ~TcpTransportBridge();
132
133
private:
134
	TcpTransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, TQObject* parent, const char* name = 0l);
135
	TcpTransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, TQObject* parent, const char* name = 0l);
136
	
137
protected slots:
138
	virtual void slotOnConnect();
139
	virtual void slotOnDisconnect();
140
	virtual void slotOnError(int);
141
	virtual void slotOnSocketClose();
142
	virtual void slotOnSocketConnect();
143
	virtual void slotOnSocketReceive();
144
	
145
private slots:
146
	void slotOnSocketConnectTimeout();
147
148
signals:
149
	void bridgeConnectTimeout();
150
	
151
private:
152
	class Buffer : public TQByteArray
153
	{
154
	public:
155
		Buffer(TQ_UINT32 length = 0);
156
		~Buffer();
157
		
158
	public:
159
		void write(const TQByteArray& bytes);
160
		TQByteArray read(TQ_UINT32 length);
161
	};
162
	
163
	Buffer mBuffer;
164
	TQ_UINT32 mLength;
165
};
166
167
168
}
169
170
#endif
(-)tdenetwork.ori/kopete/protocols/msn/ui/CMakeLists.txt (-29 lines)
Lines 1-29 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
include_directories(
13
  ${CMAKE_CURRENT_BINARY_DIR}
14
  ${CMAKE_CURRENT_SOURCE_DIR}/..
15
  ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
16
  ${CMAKE_SOURCE_DIR}/kopete/libkopete
17
  ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
18
  ${TDE_INCLUDE_DIR}
19
  ${TQT_INCLUDE_DIRS}
20
)
21
22
23
##### kopetemsnui (static) ######################
24
25
tde_add_library( kopetemsnui STATIC_PIC AUTOMOC
26
  SOURCES
27
    msnadd.ui msndebugrawcommand_base.ui msninfo.ui msneditaccountui.ui
28
    msneditaccountwidget.cpp
29
)
(-)tdenetwork.ori/kopete/protocols/msn/ui/Makefile.am (-12 lines)
Lines 1-12 Link Here
1
METASOURCES = AUTO
2
AM_CPPFLAGS = $(KOPETE_INCLUDES) \
3
    -I$(srcdir)/.. \
4
    $(all_includes)
5
6
noinst_LTLIBRARIES = libkopetemsnui.la
7
8
libkopetemsnui_la_SOURCES = msnadd.ui msndebugrawcommand_base.ui msninfo.ui \
9
	msneditaccountui.ui msneditaccountwidget.cpp
10
11
EXTRA_DIST = msnadd.ui msninfo.ui
12
(-)tdenetwork.ori/kopete/protocols/msn/ui/msnadd.ui (-97 lines)
Lines 1-97 Link Here
1
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
2
<class>msnAddUI</class>
3
<widget class="TQWidget">
4
    <property name="name">
5
        <cstring>msnAddUI</cstring>
6
    </property>
7
    <property name="geometry">
8
        <rect>
9
            <x>0</x>
10
            <y>0</y>
11
            <width>397</width>
12
            <height>347</height>
13
        </rect>
14
    </property>
15
    <vbox>
16
        <property name="name">
17
            <cstring>unnamed</cstring>
18
        </property>
19
        <property name="margin">
20
            <number>0</number>
21
        </property>
22
        <property name="spacing">
23
            <number>6</number>
24
        </property>
25
        <widget class="TQLayoutWidget">
26
            <property name="name">
27
                <cstring>layout21</cstring>
28
            </property>
29
            <hbox>
30
                <property name="name">
31
                    <cstring>unnamed</cstring>
32
                </property>
33
                <widget class="TQLabel">
34
                    <property name="name">
35
                        <cstring>TextLabel1</cstring>
36
                    </property>
37
                    <property name="text">
38
                        <string>&amp;MSN Passport ID:</string>
39
                    </property>
40
                    <property name="alignment">
41
                        <set>AlignTop</set>
42
                    </property>
43
                    <property name="buddy" stdset="0">
44
                        <cstring>addID</cstring>
45
                    </property>
46
                    <property name="toolTip" stdset="0">
47
                        <string>The user ID of the MSN contact you would like to add.</string>
48
                    </property>
49
                    <property name="whatsThis" stdset="0">
50
                        <string>The user ID of the MSN contact you would like to add.  This should be in the form of a valid E-mail address.</string>
51
                    </property>
52
                </widget>
53
                <widget class="TQLineEdit">
54
                    <property name="name">
55
                        <cstring>addID</cstring>
56
                    </property>
57
                    <property name="toolTip" stdset="0">
58
                        <string>The user ID of the MSN contact you would like to add.</string>
59
                    </property>
60
                    <property name="whatsThis" stdset="0">
61
                        <string>The user ID of the MSN contact you would like to add.  This should be in the form of a valid E-mail address.</string>
62
                    </property>
63
                </widget>
64
            </hbox>
65
        </widget>
66
        <widget class="TQLabel">
67
            <property name="name">
68
                <cstring>textLabel2</cstring>
69
            </property>
70
            <property name="text">
71
                <string>&lt;i&gt;(for example: joe@hotmail.com)&lt;/i&gt;</string>
72
            </property>
73
            <property name="alignment">
74
                <set>AlignVCenter|AlignRight</set>
75
            </property>
76
        </widget>
77
        <spacer>
78
            <property name="name">
79
                <cstring>spacer13</cstring>
80
            </property>
81
            <property name="orientation">
82
                <enum>Vertical</enum>
83
            </property>
84
            <property name="sizeType">
85
                <enum>Expanding</enum>
86
            </property>
87
            <property name="sizeHint">
88
                <size>
89
                    <width>20</width>
90
                    <height>160</height>
91
                </size>
92
            </property>
93
        </spacer>
94
    </vbox>
95
</widget>
96
<layoutdefaults spacing="6" margin="11"/>
97
</UI>
(-)tdenetwork.ori/kopete/protocols/msn/ui/msndebugrawcommand_base.ui (-107 lines)
Lines 1-107 Link Here
1
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
2
<class>MSNDebugRawCommand_base</class>
3
<widget class="TQWidget">
4
    <property name="name">
5
        <cstring>MSNDebugRawCommand_base</cstring>
6
    </property>
7
    <property name="geometry">
8
        <rect>
9
            <x>0</x>
10
            <y>0</y>
11
            <width>320</width>
12
            <height>201</height>
13
        </rect>
14
    </property>
15
    <grid>
16
        <property name="name">
17
            <cstring>unnamed</cstring>
18
        </property>
19
        <property name="margin">
20
            <number>0</number>
21
        </property>
22
        <property name="spacing">
23
            <number>6</number>
24
        </property>
25
        <widget class="TQLabel" row="1" column="0">
26
            <property name="name">
27
                <cstring>TextLabel2</cstring>
28
            </property>
29
            <property name="text">
30
                <string>&amp;Parameters:</string>
31
            </property>
32
            <property name="buddy" stdset="0">
33
                <cstring>m_params</cstring>
34
            </property>
35
        </widget>
36
        <widget class="TQLineEdit" row="0" column="1">
37
            <property name="name">
38
                <cstring>m_command</cstring>
39
            </property>
40
        </widget>
41
        <widget class="TQLabel" row="0" column="0">
42
            <property name="name">
43
                <cstring>TextLabel1</cstring>
44
            </property>
45
            <property name="text">
46
                <string>Co&amp;mmand:</string>
47
            </property>
48
            <property name="buddy" stdset="0">
49
                <cstring>m_command</cstring>
50
            </property>
51
        </widget>
52
        <widget class="TQLineEdit" row="1" column="1">
53
            <property name="name">
54
                <cstring>m_params</cstring>
55
            </property>
56
        </widget>
57
        <widget class="TQCheckBox" row="2" column="0" rowspan="1" colspan="2">
58
            <property name="name">
59
                <cstring>m_addId</cstring>
60
            </property>
61
            <property name="text">
62
                <string>Add &amp;ID</string>
63
            </property>
64
            <property name="checked">
65
                <bool>true</bool>
66
            </property>
67
        </widget>
68
        <widget class="TQCheckBox" row="3" column="0" rowspan="1" colspan="2">
69
            <property name="name">
70
                <cstring>m_addNewline</cstring>
71
            </property>
72
            <property name="text">
73
                <string>Add &amp;new line</string>
74
            </property>
75
            <property name="checked">
76
                <bool>true</bool>
77
            </property>
78
        </widget>
79
        <widget class="KTextEdit" row="5" column="0" rowspan="1" colspan="2">
80
            <property name="name">
81
                <cstring>m_msg</cstring>
82
            </property>
83
            <property name="textFormat">
84
                <enum>PlainText</enum>
85
            </property>
86
        </widget>
87
        <widget class="TQLabel" row="4" column="0" rowspan="1" colspan="2">
88
            <property name="name">
89
                <cstring>TextLabel3</cstring>
90
            </property>
91
            <property name="text">
92
                <string>Message:</string>
93
            </property>
94
        </widget>
95
    </grid>
96
</widget>
97
<tabstops>
98
    <tabstop>m_command</tabstop>
99
    <tabstop>m_params</tabstop>
100
    <tabstop>m_addId</tabstop>
101
    <tabstop>m_addNewline</tabstop>
102
</tabstops>
103
<layoutdefaults spacing="6" margin="11"/>
104
<includehints>
105
    <includehint>ktextedit.h</includehint>
106
</includehints>
107
</UI>
(-)tdenetwork.ori/kopete/protocols/msn/ui/msneditaccountui.ui (-1421 lines)
Lines 1-1421 Link Here
1
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
2
<class>MSNEditAccountUI</class>
3
<author>Olivier Goffart</author>
4
<widget class="TQWidget">
5
    <property name="name">
6
        <cstring>Form1</cstring>
7
    </property>
8
    <property name="geometry">
9
        <rect>
10
            <x>0</x>
11
            <y>0</y>
12
            <width>604</width>
13
            <height>437</height>
14
        </rect>
15
    </property>
16
    <property name="caption">
17
        <string>Account Preferences - MSN</string>
18
    </property>
19
    <vbox>
20
        <property name="name">
21
            <cstring>unnamed</cstring>
22
        </property>
23
        <property name="margin">
24
            <number>0</number>
25
        </property>
26
        <property name="spacing">
27
            <number>0</number>
28
        </property>
29
        <widget class="TQTabWidget">
30
            <property name="name">
31
                <cstring>tabWidget3</cstring>
32
            </property>
33
            <property name="tabShape">
34
                <enum>Rounded</enum>
35
            </property>
36
            <widget class="TQWidget">
37
                <property name="name">
38
                    <cstring>tab_connection</cstring>
39
                </property>
40
                <attribute name="title">
41
                    <string>&amp;Basic Setup</string>
42
                </attribute>
43
                <grid>
44
                    <property name="name">
45
                        <cstring>unnamed</cstring>
46
                    </property>
47
                    <spacer row="2" column="0">
48
                        <property name="name">
49
                            <cstring>spacer41</cstring>
50
                        </property>
51
                        <property name="orientation">
52
                            <enum>Vertical</enum>
53
                        </property>
54
                        <property name="sizeType">
55
                            <enum>Expanding</enum>
56
                        </property>
57
                        <property name="sizeHint">
58
                            <size>
59
                                <width>20</width>
60
                                <height>146</height>
61
                            </size>
62
                        </property>
63
                    </spacer>
64
                    <widget class="TQGroupBox" row="1" column="0">
65
                        <property name="name">
66
                            <cstring>groupBox5</cstring>
67
                        </property>
68
                        <property name="sizePolicy">
69
                            <sizepolicy>
70
                                <hsizetype>3</hsizetype>
71
                                <vsizetype>1</vsizetype>
72
                                <horstretch>0</horstretch>
73
                                <verstretch>0</verstretch>
74
                            </sizepolicy>
75
                        </property>
76
                        <property name="title">
77
                            <string>Registration</string>
78
                        </property>
79
                        <hbox>
80
                            <property name="name">
81
                                <cstring>unnamed</cstring>
82
                            </property>
83
                            <widget class="TQLabel">
84
                                <property name="name">
85
                                    <cstring>textLabel6</cstring>
86
                                </property>
87
                                <property name="sizePolicy">
88
                                    <sizepolicy>
89
                                        <hsizetype>3</hsizetype>
90
                                        <vsizetype>1</vsizetype>
91
                                        <horstretch>0</horstretch>
92
                                        <verstretch>0</verstretch>
93
                                    </sizepolicy>
94
                                </property>
95
                                <property name="minimumSize">
96
                                    <size>
97
                                        <width>0</width>
98
                                        <height>0</height>
99
                                    </size>
100
                                </property>
101
                                <property name="text">
102
                                    <string>To connect to the Microsoft network, you will need a Microsoft Passport.&lt;br&gt;&lt;br&gt;If you do not currently have a Passport, please click the button to create one.</string>
103
                                </property>
104
                                <property name="alignment">
105
                                    <set>WordBreak|AlignVCenter</set>
106
                                </property>
107
                            </widget>
108
                            <widget class="TQPushButton">
109
                                <property name="name">
110
                                    <cstring>buttonRegister</cstring>
111
                                </property>
112
                                <property name="text">
113
                                    <string>Re&amp;gister New Account</string>
114
                                </property>
115
                            </widget>
116
                        </hbox>
117
                    </widget>
118
                    <widget class="TQGroupBox" row="0" column="0">
119
                        <property name="name">
120
                            <cstring>m_accountInfo</cstring>
121
                        </property>
122
                        <property name="title">
123
                            <string>Account Information</string>
124
                        </property>
125
                        <grid>
126
                            <property name="name">
127
                                <cstring>unnamed</cstring>
128
                            </property>
129
                            <widget class="TQLayoutWidget" row="0" column="0">
130
                                <property name="name">
131
                                    <cstring>layout14</cstring>
132
                                </property>
133
                                <hbox>
134
                                    <property name="name">
135
                                        <cstring>unnamed</cstring>
136
                                    </property>
137
                                    <widget class="TQLabel">
138
                                        <property name="name">
139
                                            <cstring>TextLabel1_3</cstring>
140
                                        </property>
141
                                        <property name="sizePolicy">
142
                                            <sizepolicy>
143
                                                <hsizetype>1</hsizetype>
144
                                                <vsizetype>5</vsizetype>
145
                                                <horstretch>0</horstretch>
146
                                                <verstretch>0</verstretch>
147
                                            </sizepolicy>
148
                                        </property>
149
                                        <property name="text">
150
                                            <string>&amp;MSN Passport ID:</string>
151
                                        </property>
152
                                        <property name="buddy" stdset="0">
153
                                            <cstring>m_login</cstring>
154
                                        </property>
155
                                        <property name="toolTip" stdset="0">
156
                                            <string>The user ID of the MSN contact you would like to use.</string>
157
                                        </property>
158
                                        <property name="whatsThis" stdset="0">
159
                                            <string>The user ID of the MSN contact you would like to use.  This should be in the form of a valid E-mail address.</string>
160
                                        </property>
161
                                    </widget>
162
                                    <widget class="TQLineEdit">
163
                                        <property name="name">
164
                                            <cstring>m_login</cstring>
165
                                        </property>
166
                                        <property name="text">
167
                                            <string></string>
168
                                        </property>
169
                                        <property name="toolTip" stdset="0">
170
                                            <string>The user ID of the MSN contact you would like to use.</string>
171
                                        </property>
172
                                        <property name="whatsThis" stdset="0">
173
                                            <string>The user ID of the MSN contact you would like to use.  This should be in the form of a valid E-mail address.</string>
174
                                        </property>
175
                                    </widget>
176
                                </hbox>
177
                            </widget>
178
                            <widget class="Kopete::UI::PasswordWidget" row="1" column="0">
179
                                <property name="name">
180
                                    <cstring>m_password</cstring>
181
                                </property>
182
                            </widget>
183
                            <widget class="TQCheckBox" row="2" column="0">
184
                                <property name="name">
185
                                    <cstring>m_autologin</cstring>
186
                                </property>
187
                                <property name="text">
188
                                    <string>E&amp;xclude from connect all</string>
189
                                </property>
190
                                <property name="checked">
191
                                    <bool>false</bool>
192
                                </property>
193
                                <property name="whatsThis" stdset="0">
194
                                    <string>If you check this checkbox, the account will not be connected when you press the "Connect All" button, or at startup when automatic connection at startup is enabled.</string>
195
                                </property>
196
                            </widget>
197
                            <widget class="TQCheckBox" row="3" column="0">
198
                                <property name="name">
199
                                    <cstring>m_globalIdentity</cstring>
200
                                </property>
201
                                <property name="text">
202
                                    <string>Exclu&amp;de from Global Identity</string>
203
                                </property>
204
                            </widget>
205
                        </grid>
206
                    </widget>
207
                </grid>
208
            </widget>
209
            <widget class="TQWidget">
210
                <property name="name">
211
                    <cstring>TabPage</cstring>
212
                </property>
213
                <attribute name="title">
214
                    <string>MSN &amp;Settings</string>
215
                </attribute>
216
                <vbox>
217
                    <property name="name">
218
                        <cstring>unnamed</cstring>
219
                    </property>
220
                    <widget class="TQLabel">
221
                        <property name="name">
222
                            <cstring>textLabel1_3</cstring>
223
                        </property>
224
                        <property name="font">
225
                            <font>
226
                                <italic>1</italic>
227
                            </font>
228
                        </property>
229
                        <property name="text">
230
                            <string>&lt;qt&gt;&lt;b&gt;Note:&lt;/b&gt; These settings are applicable to all MSN accounts</string>
231
                        </property>
232
                        <property name="alignment">
233
                            <set>WordBreak|AlignCenter</set>
234
                        </property>
235
                    </widget>
236
                    <widget class="TQGroupBox">
237
                        <property name="name">
238
                            <cstring>global_settings_page</cstring>
239
                        </property>
240
                        <property name="title">
241
                            <string>Global MSN Options</string>
242
                        </property>
243
                        <vbox>
244
                            <property name="name">
245
                                <cstring>unnamed</cstring>
246
                            </property>
247
                            <widget class="TQCheckBox">
248
                                <property name="name">
249
                                    <cstring>NotifyNewChat</cstring>
250
                                </property>
251
                                <property name="sizePolicy">
252
                                    <sizepolicy>
253
                                        <hsizetype>1</hsizetype>
254
                                        <vsizetype>0</vsizetype>
255
                                        <horstretch>0</horstretch>
256
                                        <verstretch>0</verstretch>
257
                                    </sizepolicy>
258
                                </property>
259
                                <property name="text">
260
                                    <string>Au&amp;tomatically open a chat window when someone starts a conversation</string>
261
                                </property>
262
                                <property name="whatsThis" stdset="0">
263
                                    <string>This option will notify you when a contact starts typing their message, before the message is sent or finished.</string>
264
                                </property>
265
                            </widget>
266
                            <widget class="TQLayoutWidget">
267
                                <property name="name">
268
                                    <cstring>layout13_2</cstring>
269
                                </property>
270
                                <hbox>
271
                                    <property name="name">
272
                                        <cstring>unnamed</cstring>
273
                                    </property>
274
                                    <widget class="TQLabel">
275
                                        <property name="name">
276
                                            <cstring>textLabel1_4</cstring>
277
                                        </property>
278
                                        <property name="text">
279
                                            <string>Download the msn picture:</string>
280
                                        </property>
281
                                        <property name="whatsThis" stdset="0">
282
                                            <string>&lt;qt&gt;&lt;p&gt;Indicate when Kopete will download the display pictures of contacts&lt;/p&gt;
283
&lt;dl&gt;&lt;dt&gt;Only manually&lt;/dt&gt;&lt;dd&gt;The picture is not downloaded automatically. It is only downloaded when the user requests it&lt;/dd&gt;
284
&lt;dt&gt;When a chat is open&lt;/dt&gt;&lt;dd&gt;The picture is downloaded when a conversation socket is opened, i.e. when you open a chat window&lt;/dd&gt;
285
&lt;dt&gt;Automatically&lt;/dt&gt;&lt;dd&gt;Always try to download the picture if the contact has one.  &lt;b&gt;Note:&lt;/b&gt; this will open a socket, and let the user know you are downloading their picture.&lt;/dd&gt;&lt;/dl&gt;</string>
286
                                        </property>
287
                                    </widget>
288
                                    <widget class="TQComboBox">
289
                                        <item>
290
                                            <property name="text">
291
                                                <string>Only Manually</string>
292
                                            </property>
293
                                        </item>
294
                                        <item>
295
                                            <property name="text">
296
                                                <string>When a Chat is Open</string>
297
                                            </property>
298
                                        </item>
299
                                        <item>
300
                                            <property name="text">
301
                                                <string>Automatically</string>
302
                                            </property>
303
                                        </item>
304
                                        <property name="name">
305
                                            <cstring>DownloadPicture</cstring>
306
                                        </property>
307
                                        <property name="sizePolicy">
308
                                            <sizepolicy>
309
                                                <hsizetype>3</hsizetype>
310
                                                <vsizetype>0</vsizetype>
311
                                                <horstretch>0</horstretch>
312
                                                <verstretch>0</verstretch>
313
                                            </sizepolicy>
314
                                        </property>
315
                                        <property name="currentItem">
316
                                            <number>2</number>
317
                                        </property>
318
                                        <property name="whatsThis" stdset="0">
319
                                            <string>&lt;qt&gt;&lt;p&gt;Indicate when Kopete will download the pictures of contacts&lt;/p&gt;
320
&lt;dl&gt;&lt;dt&gt;Only manually&lt;/dt&gt;&lt;dd&gt;The picture is not downloaded automatically. It is only downloaded when the user requests it&lt;/dd&gt;
321
&lt;dt&gt;When a chat is open&lt;/dt&gt;&lt;dd&gt;The picture is downloaded when a conversation socket is opened, i.e. when you open a chat window&lt;/dd&gt;
322
&lt;dt&gt;Automatically&lt;/dt&gt;&lt;dd&gt;Always try to download the picture if the contact has one.  &lt;b&gt;Note:&lt;/b&gt; this will open a socket, and let the user know you are downloading their picture.&lt;/dd&gt;&lt;/dl&gt;</string>
323
                                        </property>
324
                                    </widget>
325
                                </hbox>
326
                            </widget>
327
                            <widget class="TQCheckBox">
328
                                <property name="name">
329
                                    <cstring>useCustomEmoticons</cstring>
330
                                </property>
331
                                <property name="text">
332
                                    <string>&amp;Download and show custom emoticons</string>
333
                                </property>
334
                                <property name="checked">
335
                                    <bool>true</bool>
336
                                </property>
337
                                <property name="whatsThis" stdset="0">
338
                                    <string>MSN Messenger allows users to download and use custom emoticons. If this option is enabled, Kopete will download these emoticons and show them.</string>
339
                                </property>
340
                            </widget>
341
                            <widget class="TQCheckBox">
342
                                <property name="name">
343
                                    <cstring>exportEmoticons</cstring>
344
                                </property>
345
                                <property name="text">
346
                                    <string>E&amp;xport the current emoticon theme to users</string>
347
                                </property>
348
                                <property name="toolTip" stdset="0">
349
                                    <string>Only work with emoticons in the PNG format</string>
350
                                </property>
351
                                <property name="whatsThis" stdset="0">
352
                                    <string>Export all the emoticon themes as custom emoticons.
353
Only works for emoticons in the PNG format.</string>
354
                                </property>
355
                            </widget>
356
                        </vbox>
357
                    </widget>
358
                    <widget class="TQGroupBox">
359
                        <property name="name">
360
                            <cstring>privacy_page</cstring>
361
                        </property>
362
                        <property name="title">
363
                            <string>Privacy</string>
364
                        </property>
365
                        <vbox>
366
                            <property name="name">
367
                                <cstring>unnamed</cstring>
368
                            </property>
369
                            <widget class="TQCheckBox">
370
                                <property name="name">
371
                                    <cstring>SendClientInfo</cstring>
372
                                </property>
373
                                <property name="enabled">
374
                                    <bool>true</bool>
375
                                </property>
376
                                <property name="text">
377
                                    <string>Send client information</string>
378
                                </property>
379
                                <property name="accel">
380
                                    <string></string>
381
                                </property>
382
                                <property name="checked">
383
                                    <bool>true</bool>
384
                                </property>
385
                                <property name="toolTip" stdset="0">
386
                                    <string>&lt;qt&gt;Make it possible for your contacts to detect if you are using Kopete.&lt;br&gt;We recommend leaving this checked.&lt;/qt&gt;</string>
387
                                </property>
388
                                <property name="whatsThis" stdset="0">
389
                                    <string>Third party MSN clients, such as Kopete, give users the ability to let other third party clients guess which client they are using. We recommend leaving this checkbox checked.</string>
390
                                </property>
391
                            </widget>
392
                            <widget class="TQCheckBox">
393
                                <property name="name">
394
                                    <cstring>SendTypingNotification</cstring>
395
                                </property>
396
                                <property name="enabled">
397
                                    <bool>true</bool>
398
                                </property>
399
                                <property name="text">
400
                                    <string>Send &amp;typing notifications</string>
401
                                </property>
402
                                <property name="checked">
403
                                    <bool>true</bool>
404
                                </property>
405
                                <property name="whatsThis" stdset="0">
406
                                    <string>&lt;qt&gt;Check this box to send &lt;b&gt;Typing notifications&lt;/b&gt; to your contacts. When you are composing a message, you might want your contact to know that you are typing so that he knows you are answering.&lt;/qt&gt;</string>
407
                                </property>
408
                            </widget>
409
                            <widget class="TQLayoutWidget">
410
                                <property name="name">
411
                                    <cstring>layout28</cstring>
412
                                </property>
413
                                <hbox>
414
                                    <property name="name">
415
                                        <cstring>unnamed</cstring>
416
                                    </property>
417
                                    <widget class="TQCheckBox">
418
                                        <property name="name">
419
                                            <cstring>SendJabber</cstring>
420
                                        </property>
421
                                        <property name="text">
422
                                            <string>Expose my Jabber account to Jabber users</string>
423
                                        </property>
424
                                        <property name="checked">
425
                                            <bool>true</bool>
426
                                        </property>
427
                                        <property name="whatsThis" stdset="0">
428
                                            <string>If you have a Jabber account, you may let Jabber users on an MSN gateway know that you are also using Jabber.</string>
429
                                        </property>
430
                                    </widget>
431
                                    <widget class="KComboBox">
432
                                        <property name="name">
433
                                            <cstring>JabberAccount</cstring>
434
                                        </property>
435
                                        <property name="editable">
436
                                            <bool>true</bool>
437
                                        </property>
438
                                        <property name="whatsThis" stdset="0">
439
                                            <string>If you have a Jabber account, you may let Jabber users on an MSN gateway know that you are also using Jabber.</string>
440
                                        </property>
441
                                    </widget>
442
                                    <spacer>
443
                                        <property name="name">
444
                                            <cstring>spacer26</cstring>
445
                                        </property>
446
                                        <property name="orientation">
447
                                            <enum>Horizontal</enum>
448
                                        </property>
449
                                        <property name="sizeType">
450
                                            <enum>Expanding</enum>
451
                                        </property>
452
                                        <property name="sizeHint">
453
                                            <size>
454
                                                <width>61</width>
455
                                                <height>21</height>
456
                                            </size>
457
                                        </property>
458
                                    </spacer>
459
                                </hbox>
460
                            </widget>
461
                            <spacer>
462
                                <property name="name">
463
                                    <cstring>spacer25</cstring>
464
                                </property>
465
                                <property name="orientation">
466
                                    <enum>Vertical</enum>
467
                                </property>
468
                                <property name="sizeType">
469
                                    <enum>Minimum</enum>
470
                                </property>
471
                                <property name="sizeHint">
472
                                    <size>
473
                                        <width>20</width>
474
                                        <height>21</height>
475
                                    </size>
476
                                </property>
477
                            </spacer>
478
                            <widget class="TQLabel">
479
                                <property name="name">
480
                                    <cstring>textLabel1_5</cstring>
481
                                </property>
482
                                <property name="text">
483
                                    <string>There are also privacy options in the "Contacts" tab</string>
484
                                </property>
485
                                <property name="alignment">
486
                                    <set>WordBreak|AlignCenter</set>
487
                                </property>
488
                            </widget>
489
                        </vbox>
490
                    </widget>
491
                    <spacer>
492
                        <property name="name">
493
                            <cstring>spacer20</cstring>
494
                        </property>
495
                        <property name="orientation">
496
                            <enum>Vertical</enum>
497
                        </property>
498
                        <property name="sizeType">
499
                            <enum>Expanding</enum>
500
                        </property>
501
                        <property name="sizeHint">
502
                            <size>
503
                                <width>31</width>
504
                                <height>40</height>
505
                            </size>
506
                        </property>
507
                    </spacer>
508
                </vbox>
509
            </widget>
510
            <widget class="TQWidget">
511
                <property name="name">
512
                    <cstring>tab_info</cstring>
513
                </property>
514
                <attribute name="title">
515
                    <string>User &amp;Info</string>
516
                </attribute>
517
                <vbox>
518
                    <property name="name">
519
                        <cstring>unnamed</cstring>
520
                    </property>
521
                    <widget class="TQLayoutWidget">
522
                        <property name="name">
523
                            <cstring>Layout22_2</cstring>
524
                        </property>
525
                        <hbox>
526
                            <property name="name">
527
                                <cstring>unnamed</cstring>
528
                            </property>
529
                            <property name="margin">
530
                                <number>0</number>
531
                            </property>
532
                            <property name="spacing">
533
                                <number>6</number>
534
                            </property>
535
                            <widget class="TQLabel">
536
                                <property name="name">
537
                                    <cstring>TextLabel2_2_2</cstring>
538
                                </property>
539
                                <property name="sizePolicy">
540
                                    <sizepolicy>
541
                                        <hsizetype>4</hsizetype>
542
                                        <vsizetype>4</vsizetype>
543
                                        <horstretch>0</horstretch>
544
                                        <verstretch>0</verstretch>
545
                                    </sizepolicy>
546
                                </property>
547
                                <property name="text">
548
                                    <string>&amp;Nickname:</string>
549
                                </property>
550
                                <property name="buddy" stdset="0">
551
                                    <cstring>m_displayName</cstring>
552
                                </property>
553
                                <property name="whatsThis" stdset="0">
554
                                    <string>The alias you would like to use on MSN.  You may change this at any time you wish.</string>
555
                                </property>
556
                            </widget>
557
                            <widget class="TQLineEdit">
558
                                <property name="name">
559
                                    <cstring>m_displayName</cstring>
560
                                </property>
561
                                <property name="readOnly">
562
                                    <bool>false</bool>
563
                                </property>
564
                                <property name="whatsThis" stdset="0">
565
                                    <string>The alias you would like to use on MSN.  You may change this at any time you wish.</string>
566
                                </property>
567
                            </widget>
568
                        </hbox>
569
                    </widget>
570
                    <widget class="TQGroupBox">
571
                        <property name="name">
572
                            <cstring>m_phones</cstring>
573
                        </property>
574
                        <property name="title">
575
                            <string>Phone Numbers</string>
576
                        </property>
577
                        <grid>
578
                            <property name="name">
579
                                <cstring>unnamed</cstring>
580
                            </property>
581
                            <widget class="TQLabel" row="1" column="0">
582
                                <property name="name">
583
                                    <cstring>TextLabel5</cstring>
584
                                </property>
585
                                <property name="text">
586
                                    <string>Hom&amp;e:</string>
587
                                </property>
588
                                <property name="buddy" stdset="0">
589
                                    <cstring>m_phh</cstring>
590
                                </property>
591
                            </widget>
592
                            <widget class="TQLabel" row="0" column="0">
593
                                <property name="name">
594
                                    <cstring>TextLabel6</cstring>
595
                                </property>
596
                                <property name="text">
597
                                    <string>&amp;Work:</string>
598
                                </property>
599
                                <property name="buddy" stdset="0">
600
                                    <cstring>m_phw</cstring>
601
                                </property>
602
                            </widget>
603
                            <widget class="TQLineEdit" row="0" column="1">
604
                                <property name="name">
605
                                    <cstring>m_phw</cstring>
606
                                </property>
607
                            </widget>
608
                            <widget class="TQLineEdit" row="1" column="1">
609
                                <property name="name">
610
                                    <cstring>m_phh</cstring>
611
                                </property>
612
                            </widget>
613
                            <widget class="TQLabel" row="2" column="0">
614
                                <property name="name">
615
                                    <cstring>TextLabel7</cstring>
616
                                </property>
617
                                <property name="text">
618
                                    <string>&amp;Mobile:</string>
619
                                </property>
620
                                <property name="buddy" stdset="0">
621
                                    <cstring>m_phm</cstring>
622
                                </property>
623
                            </widget>
624
                            <widget class="TQLineEdit" row="2" column="1">
625
                                <property name="name">
626
                                    <cstring>m_phm</cstring>
627
                                </property>
628
                            </widget>
629
                        </grid>
630
                    </widget>
631
                    <widget class="TQGroupBox">
632
                        <property name="name">
633
                            <cstring>groupBox2</cstring>
634
                        </property>
635
                        <property name="title">
636
                            <string>Display Picture</string>
637
                        </property>
638
                        <hbox>
639
                            <property name="name">
640
                                <cstring>unnamed</cstring>
641
                            </property>
642
                            <widget class="TQLayoutWidget">
643
                                <property name="name">
644
                                    <cstring>layout17</cstring>
645
                                </property>
646
                                <vbox>
647
                                    <property name="name">
648
                                        <cstring>unnamed</cstring>
649
                                    </property>
650
                                    <widget class="TQCheckBox">
651
                                        <property name="name">
652
                                            <cstring>m_useDisplayPicture</cstring>
653
                                        </property>
654
                                        <property name="text">
655
                                            <string>E&amp;xport a display picture</string>
656
                                        </property>
657
                                    </widget>
658
                                    <widget class="TQLabel">
659
                                        <property name="name">
660
                                            <cstring>textLabel1_2</cstring>
661
                                        </property>
662
                                        <property name="enabled">
663
                                            <bool>false</bool>
664
                                        </property>
665
                                        <property name="sizePolicy">
666
                                            <sizepolicy>
667
                                                <hsizetype>5</hsizetype>
668
                                                <vsizetype>5</vsizetype>
669
                                                <horstretch>0</horstretch>
670
                                                <verstretch>0</verstretch>
671
                                            </sizepolicy>
672
                                        </property>
673
                                        <property name="text">
674
                                            <string>Please select a square image. The image will be scaled to 96x96.</string>
675
                                        </property>
676
                                        <property name="alignment">
677
                                            <set>WordBreak|AlignVCenter</set>
678
                                        </property>
679
                                    </widget>
680
                                    <widget class="TQLayoutWidget">
681
                                        <property name="name">
682
                                            <cstring>layout13</cstring>
683
                                        </property>
684
                                        <hbox>
685
                                            <property name="name">
686
                                                <cstring>unnamed</cstring>
687
                                            </property>
688
                                            <widget class="TQPushButton">
689
                                                <property name="name">
690
                                                    <cstring>m_selectImage</cstring>
691
                                                </property>
692
                                                <property name="enabled">
693
                                                    <bool>false</bool>
694
                                                </property>
695
                                                <property name="text">
696
                                                    <string>&amp;Select Image...</string>
697
                                                </property>
698
                                            </widget>
699
                                            <spacer>
700
                                                <property name="name">
701
                                                    <cstring>spacer5</cstring>
702
                                                </property>
703
                                                <property name="orientation">
704
                                                    <enum>Horizontal</enum>
705
                                                </property>
706
                                                <property name="sizeType">
707
                                                    <enum>Expanding</enum>
708
                                                </property>
709
                                                <property name="sizeHint">
710
                                                    <size>
711
                                                        <width>61</width>
712
                                                        <height>21</height>
713
                                                    </size>
714
                                                </property>
715
                                            </spacer>
716
                                        </hbox>
717
                                    </widget>
718
                                    <spacer>
719
                                        <property name="name">
720
                                            <cstring>spacer7_2_2</cstring>
721
                                        </property>
722
                                        <property name="orientation">
723
                                            <enum>Vertical</enum>
724
                                        </property>
725
                                        <property name="sizeType">
726
                                            <enum>Minimum</enum>
727
                                        </property>
728
                                        <property name="sizeHint">
729
                                            <size>
730
                                                <width>20</width>
731
                                                <height>1</height>
732
                                            </size>
733
                                        </property>
734
                                    </spacer>
735
                                </vbox>
736
                            </widget>
737
                            <widget class="TQLayoutWidget">
738
                                <property name="name">
739
                                    <cstring>layout16</cstring>
740
                                </property>
741
                                <vbox>
742
                                    <property name="name">
743
                                        <cstring>unnamed</cstring>
744
                                    </property>
745
                                    <property name="spacing">
746
                                        <number>0</number>
747
                                    </property>
748
                                    <widget class="TQLabel">
749
                                        <property name="name">
750
                                            <cstring>m_displayPicture</cstring>
751
                                        </property>
752
                                        <property name="enabled">
753
                                            <bool>false</bool>
754
                                        </property>
755
                                        <property name="sizePolicy">
756
                                            <sizepolicy>
757
                                                <hsizetype>0</hsizetype>
758
                                                <vsizetype>0</vsizetype>
759
                                                <horstretch>0</horstretch>
760
                                                <verstretch>0</verstretch>
761
                                            </sizepolicy>
762
                                        </property>
763
                                        <property name="minimumSize">
764
                                            <size>
765
                                                <width>96</width>
766
                                                <height>96</height>
767
                                            </size>
768
                                        </property>
769
                                        <property name="maximumSize">
770
                                            <size>
771
                                                <width>96</width>
772
                                                <height>96</height>
773
                                            </size>
774
                                        </property>
775
                                        <property name="frameShape">
776
                                            <enum>GroupBoxPanel</enum>
777
                                        </property>
778
                                        <property name="scaledContents">
779
                                            <bool>true</bool>
780
                                        </property>
781
                                    </widget>
782
                                    <spacer>
783
                                        <property name="name">
784
                                            <cstring>spacer7_2</cstring>
785
                                        </property>
786
                                        <property name="orientation">
787
                                            <enum>Vertical</enum>
788
                                        </property>
789
                                        <property name="sizeType">
790
                                            <enum>Minimum</enum>
791
                                        </property>
792
                                        <property name="sizeHint">
793
                                            <size>
794
                                                <width>20</width>
795
                                                <height>1</height>
796
                                            </size>
797
                                        </property>
798
                                    </spacer>
799
                                </vbox>
800
                            </widget>
801
                        </hbox>
802
                    </widget>
803
                    <spacer>
804
                        <property name="name">
805
                            <cstring>spacer16</cstring>
806
                        </property>
807
                        <property name="orientation">
808
                            <enum>Vertical</enum>
809
                        </property>
810
                        <property name="sizeType">
811
                            <enum>Expanding</enum>
812
                        </property>
813
                        <property name="sizeHint">
814
                            <size>
815
                                <width>20</width>
816
                                <height>21</height>
817
                            </size>
818
                        </property>
819
                    </spacer>
820
                    <widget class="TQLabel">
821
                        <property name="name">
822
                            <cstring>m_warning_1</cstring>
823
                        </property>
824
                        <property name="paletteForegroundColor">
825
                            <color>
826
                                <red>255</red>
827
                                <green>0</green>
828
                                <blue>0</blue>
829
                            </color>
830
                        </property>
831
                        <property name="font">
832
                            <font>
833
                                <bold>1</bold>
834
                            </font>
835
                        </property>
836
                        <property name="text">
837
                            <string>WARNING: You need to be connected to modify this page.</string>
838
                        </property>
839
                        <property name="alignment">
840
                            <set>WordBreak|AlignVCenter</set>
841
                        </property>
842
                    </widget>
843
                </vbox>
844
            </widget>
845
            <widget class="TQWidget">
846
                <property name="name">
847
                    <cstring>tab_contacts</cstring>
848
                </property>
849
                <attribute name="title">
850
                    <string>Con&amp;tacts</string>
851
                </attribute>
852
                <vbox>
853
                    <property name="name">
854
                        <cstring>unnamed</cstring>
855
                    </property>
856
                    <widget class="TQLabel">
857
                        <property name="name">
858
                            <cstring>label_font</cstring>
859
                        </property>
860
                        <property name="text">
861
                            <string>&lt;i&gt;Italics&lt;/i&gt; contacts are not on your contact list.&lt;br&gt;
862
&lt;br&gt;
863
&lt;b&gt;Bold&lt;/b&gt; contacts are in your contact list but you are not in their contact list.</string>
864
                        </property>
865
                    </widget>
866
                    <widget class="TQLayoutWidget">
867
                        <property name="name">
868
                            <cstring>layout6</cstring>
869
                        </property>
870
                        <grid>
871
                            <property name="name">
872
                                <cstring>unnamed</cstring>
873
                            </property>
874
                            <widget class="TQLabel" row="0" column="2">
875
                                <property name="name">
876
                                    <cstring>textLabel2</cstring>
877
                                </property>
878
                                <property name="text">
879
                                    <string>Bloc&amp;ked contacts:</string>
880
                                </property>
881
                                <property name="buddy" stdset="0">
882
                                    <cstring>m_BL</cstring>
883
                                </property>
884
                            </widget>
885
                            <widget class="TQListBox" row="1" column="0">
886
                                <property name="name">
887
                                    <cstring>m_AL</cstring>
888
                                </property>
889
                            </widget>
890
                            <widget class="TQLayoutWidget" row="1" column="1">
891
                                <property name="name">
892
                                    <cstring>layout4</cstring>
893
                                </property>
894
                                <vbox>
895
                                    <property name="name">
896
                                        <cstring>unnamed</cstring>
897
                                    </property>
898
                                    <widget class="TQPushButton">
899
                                        <property name="name">
900
                                            <cstring>m_blockButton</cstring>
901
                                        </property>
902
                                        <property name="text">
903
                                            <string>&amp;&gt;</string>
904
                                        </property>
905
                                    </widget>
906
                                    <widget class="TQPushButton">
907
                                        <property name="name">
908
                                            <cstring>m_allowButton</cstring>
909
                                        </property>
910
                                        <property name="text">
911
                                            <string>&amp;&lt;</string>
912
                                        </property>
913
                                    </widget>
914
                                    <spacer>
915
                                        <property name="name">
916
                                            <cstring>spacer13</cstring>
917
                                        </property>
918
                                        <property name="orientation">
919
                                            <enum>Vertical</enum>
920
                                        </property>
921
                                        <property name="sizeType">
922
                                            <enum>Expanding</enum>
923
                                        </property>
924
                                        <property name="sizeHint">
925
                                            <size>
926
                                                <width>20</width>
927
                                                <height>20</height>
928
                                            </size>
929
                                        </property>
930
                                    </spacer>
931
                                </vbox>
932
                            </widget>
933
                            <widget class="TQLabel" row="0" column="0">
934
                                <property name="name">
935
                                    <cstring>textLabel1</cstring>
936
                                </property>
937
                                <property name="text">
938
                                    <string>Allo&amp;wed contacts:</string>
939
                                </property>
940
                                <property name="buddy" stdset="0">
941
                                    <cstring>m_AL</cstring>
942
                                </property>
943
                            </widget>
944
                            <widget class="TQListBox" row="1" column="2">
945
                                <property name="name">
946
                                    <cstring>m_BL</cstring>
947
                                </property>
948
                            </widget>
949
                        </grid>
950
                    </widget>
951
                    <widget class="TQLayoutWidget">
952
                        <property name="name">
953
                            <cstring>layout58</cstring>
954
                        </property>
955
                        <hbox>
956
                            <property name="name">
957
                                <cstring>unnamed</cstring>
958
                            </property>
959
                            <spacer>
960
                                <property name="name">
961
                                    <cstring>spacer47</cstring>
962
                                </property>
963
                                <property name="orientation">
964
                                    <enum>Horizontal</enum>
965
                                </property>
966
                                <property name="sizeType">
967
                                    <enum>Expanding</enum>
968
                                </property>
969
                                <property name="sizeHint">
970
                                    <size>
971
                                        <width>41</width>
972
                                        <height>20</height>
973
                                    </size>
974
                                </property>
975
                            </spacer>
976
                            <widget class="TQCheckBox">
977
                                <property name="name">
978
                                    <cstring>m_blp</cstring>
979
                                </property>
980
                                <property name="text">
981
                                    <string>Block all users not in 'Allowed' &amp;list</string>
982
                                </property>
983
                                <property name="whatsThis" stdset="0">
984
                                    <string>Checking this box will block all users not explicitly shown in the allowed list here, including any contacts not on your contact list.</string>
985
                                </property>
986
                            </widget>
987
                            <spacer>
988
                                <property name="name">
989
                                    <cstring>spacer50</cstring>
990
                                </property>
991
                                <property name="orientation">
992
                                    <enum>Horizontal</enum>
993
                                </property>
994
                                <property name="sizeType">
995
                                    <enum>Expanding</enum>
996
                                </property>
997
                                <property name="sizeHint">
998
                                    <size>
999
                                        <width>41</width>
1000
                                        <height>20</height>
1001
                                    </size>
1002
                                </property>
1003
                            </spacer>
1004
                        </hbox>
1005
                    </widget>
1006
                    <widget class="TQLayoutWidget">
1007
                        <property name="name">
1008
                            <cstring>layout59</cstring>
1009
                        </property>
1010
                        <hbox>
1011
                            <property name="name">
1012
                                <cstring>unnamed</cstring>
1013
                            </property>
1014
                            <spacer>
1015
                                <property name="name">
1016
                                    <cstring>spacer48</cstring>
1017
                                </property>
1018
                                <property name="orientation">
1019
                                    <enum>Horizontal</enum>
1020
                                </property>
1021
                                <property name="sizeType">
1022
                                    <enum>Expanding</enum>
1023
                                </property>
1024
                                <property name="sizeHint">
1025
                                    <size>
1026
                                        <width>81</width>
1027
                                        <height>20</height>
1028
                                    </size>
1029
                                </property>
1030
                            </spacer>
1031
                            <widget class="TQPushButton">
1032
                                <property name="name">
1033
                                    <cstring>m_RLButton</cstring>
1034
                                </property>
1035
                                <property name="maximumSize">
1036
                                    <size>
1037
                                        <width>200</width>
1038
                                        <height>32767</height>
1039
                                    </size>
1040
                                </property>
1041
                                <property name="text">
1042
                                    <string>View &amp;Reverse List</string>
1043
                                </property>
1044
                                <property name="toolTip" stdset="0">
1045
                                    <string>The reverse list is the list of contacts who added you to their own contact list.</string>
1046
                                </property>
1047
                                <property name="whatsThis" stdset="0">
1048
                                    <string>The reverse list is the list of contacts who added you to their own contact list.</string>
1049
                                </property>
1050
                            </widget>
1051
                            <spacer>
1052
                                <property name="name">
1053
                                    <cstring>spacer49</cstring>
1054
                                </property>
1055
                                <property name="orientation">
1056
                                    <enum>Horizontal</enum>
1057
                                </property>
1058
                                <property name="sizeType">
1059
                                    <enum>Expanding</enum>
1060
                                </property>
1061
                                <property name="sizeHint">
1062
                                    <size>
1063
                                        <width>111</width>
1064
                                        <height>20</height>
1065
                                    </size>
1066
                                </property>
1067
                            </spacer>
1068
                        </hbox>
1069
                    </widget>
1070
                    <widget class="TQLabel">
1071
                        <property name="name">
1072
                            <cstring>m_warning_2</cstring>
1073
                        </property>
1074
                        <property name="paletteForegroundColor">
1075
                            <color>
1076
                                <red>255</red>
1077
                                <green>0</green>
1078
                                <blue>0</blue>
1079
                            </color>
1080
                        </property>
1081
                        <property name="font">
1082
                            <font>
1083
                                <bold>1</bold>
1084
                            </font>
1085
                        </property>
1086
                        <property name="text">
1087
                            <string>WARNING: You need to be connected to modify this page</string>
1088
                        </property>
1089
                        <property name="alignment">
1090
                            <set>WordBreak|AlignVCenter</set>
1091
                        </property>
1092
                    </widget>
1093
                </vbox>
1094
            </widget>
1095
            <widget class="TQWidget">
1096
                <property name="name">
1097
                    <cstring>TabPage</cstring>
1098
                </property>
1099
                <attribute name="title">
1100
                    <string>Co&amp;nnection</string>
1101
                </attribute>
1102
                <vbox>
1103
                    <property name="name">
1104
                        <cstring>unnamed</cstring>
1105
                    </property>
1106
                    <widget class="TQGroupBox">
1107
                        <property name="name">
1108
                            <cstring>groupBox66</cstring>
1109
                        </property>
1110
                        <property name="title">
1111
                            <string>Connection Preferences (for advanced users)</string>
1112
                        </property>
1113
                        <vbox>
1114
                            <property name="name">
1115
                                <cstring>unnamed</cstring>
1116
                            </property>
1117
                            <widget class="TQCheckBox">
1118
                                <property name="name">
1119
                                    <cstring>optionOverrideServer</cstring>
1120
                                </property>
1121
                                <property name="text">
1122
                                    <string>&amp;Override default server information</string>
1123
                                </property>
1124
                            </widget>
1125
                            <widget class="TQLayoutWidget">
1126
                                <property name="name">
1127
                                    <cstring>layout20</cstring>
1128
                                </property>
1129
                                <hbox>
1130
                                    <property name="name">
1131
                                        <cstring>unnamed</cstring>
1132
                                    </property>
1133
                                    <widget class="TQLayoutWidget">
1134
                                        <property name="name">
1135
                                            <cstring>layout19</cstring>
1136
                                        </property>
1137
                                        <hbox>
1138
                                            <property name="name">
1139
                                                <cstring>unnamed</cstring>
1140
                                            </property>
1141
                                            <property name="spacing">
1142
                                                <number>3</number>
1143
                                            </property>
1144
                                            <widget class="TQLabel">
1145
                                                <property name="name">
1146
                                                    <cstring>labelServer</cstring>
1147
                                                </property>
1148
                                                <property name="enabled">
1149
                                                    <bool>false</bool>
1150
                                                </property>
1151
                                                <property name="text">
1152
                                                    <string>Ser&amp;ver /</string>
1153
                                                </property>
1154
                                                <property name="buddy" stdset="0">
1155
                                                    <cstring>m_serverName</cstring>
1156
                                                </property>
1157
                                            </widget>
1158
                                            <widget class="TQLabel">
1159
                                                <property name="name">
1160
                                                    <cstring>labelPort</cstring>
1161
                                                </property>
1162
                                                <property name="enabled">
1163
                                                    <bool>false</bool>
1164
                                                </property>
1165
                                                <property name="text">
1166
                                                    <string>po&amp;rt:</string>
1167
                                                </property>
1168
                                                <property name="buddy" stdset="0">
1169
                                                    <cstring>m_serverPort</cstring>
1170
                                                </property>
1171
                                            </widget>
1172
                                        </hbox>
1173
                                    </widget>
1174
                                    <widget class="TQLineEdit">
1175
                                        <property name="name">
1176
                                            <cstring>m_serverName</cstring>
1177
                                        </property>
1178
                                        <property name="enabled">
1179
                                            <bool>false</bool>
1180
                                        </property>
1181
                                        <property name="sizePolicy">
1182
                                            <sizepolicy>
1183
                                                <hsizetype>3</hsizetype>
1184
                                                <vsizetype>0</vsizetype>
1185
                                                <horstretch>0</horstretch>
1186
                                                <verstretch>0</verstretch>
1187
                                            </sizepolicy>
1188
                                        </property>
1189
                                        <property name="text">
1190
                                            <string>messenger.hotmail.com</string>
1191
                                        </property>
1192
                                        <property name="toolTip" stdset="0">
1193
                                            <string>Only modify these values if you want to use a special IM proxy server, like SIMP</string>
1194
                                        </property>
1195
                                        <property name="whatsThis" stdset="0">
1196
                                            <string>Only modify these values if you want to use a special IM proxy server, like SIMP</string>
1197
                                        </property>
1198
                                    </widget>
1199
                                    <widget class="TQSpinBox">
1200
                                        <property name="name">
1201
                                            <cstring>m_serverPort</cstring>
1202
                                        </property>
1203
                                        <property name="enabled">
1204
                                            <bool>false</bool>
1205
                                        </property>
1206
                                        <property name="maxValue">
1207
                                            <number>65535</number>
1208
                                        </property>
1209
                                        <property name="minValue">
1210
                                            <number>1</number>
1211
                                        </property>
1212
                                        <property name="value">
1213
                                            <number>1863</number>
1214
                                        </property>
1215
                                        <property name="toolTip" stdset="0">
1216
                                            <string>Only modify these values if you want to use a special IM proxy server, like SIMP</string>
1217
                                        </property>
1218
                                        <property name="whatsThis" stdset="0">
1219
                                            <string>Only modify these values if you want to use a special IM proxy server, like SIMP</string>
1220
                                        </property>
1221
                                    </widget>
1222
                                </hbox>
1223
                            </widget>
1224
                            <widget class="TQCheckBox">
1225
                                <property name="name">
1226
                                    <cstring>optionUseHttpMethod</cstring>
1227
                                </property>
1228
                                <property name="text">
1229
                                    <string>Use &amp;HTTP method</string>
1230
                                </property>
1231
                                <property name="whatsThis" stdset="0">
1232
                                    <string>Connect to MSN Messenger using an HTTP-like protocol on port 80.
1233
This may be used to connect on a network with a restrictive firewall.
1234
Only check this option if the normal connection doesn't work.</string>
1235
                                </property>
1236
                            </widget>
1237
                            <widget class="TQLayoutWidget">
1238
                                <property name="name">
1239
                                    <cstring>layout22</cstring>
1240
                                </property>
1241
                                <hbox>
1242
                                    <property name="name">
1243
                                        <cstring>unnamed</cstring>
1244
                                    </property>
1245
                                    <widget class="TQCheckBox">
1246
                                        <property name="name">
1247
                                            <cstring>m_useWebcamPort</cstring>
1248
                                        </property>
1249
                                        <property name="text">
1250
                                            <string>S&amp;pecify a base port for incoming webcam connections:</string>
1251
                                        </property>
1252
                                        <property name="whatsThis" stdset="0">
1253
                                            <string>If you are behind a firewall, you may specify a base port to use for the incoming connection, and configure your firewall to accept connections on a range of 10 ports, starting at this one. Incoming connections are used for the webcam. If you don't specify a port yourself, the operating system will choose an available port for you. It is recommended to leave the checkbox unchecked.</string>
1254
                                        </property>
1255
                                    </widget>
1256
                                    <widget class="TQSpinBox">
1257
                                        <property name="name">
1258
                                            <cstring>m_webcamPort</cstring>
1259
                                        </property>
1260
                                        <property name="enabled">
1261
                                            <bool>false</bool>
1262
                                        </property>
1263
                                        <property name="maxValue">
1264
                                            <number>65535</number>
1265
                                        </property>
1266
                                        <property name="minValue">
1267
                                            <number>1</number>
1268
                                        </property>
1269
                                        <property name="value">
1270
                                            <number>6891</number>
1271
                                        </property>
1272
                                        <property name="whatsThis" stdset="0">
1273
                                            <string>If you are behind a firewall, you may specify a base port to use for the incoming connection, and configure your firewall to accept connections on a range of 10 ports, starting at this one. Incoming connections are used for the webcam. If you don't specify a port yourself, the operating system will choose an available port for you. It is recommended to leave the checkbox unchecked.</string>
1274
                                        </property>
1275
                                    </widget>
1276
                                </hbox>
1277
                            </widget>
1278
                        </vbox>
1279
                    </widget>
1280
                    <spacer>
1281
                        <property name="name">
1282
                            <cstring>spacer7</cstring>
1283
                        </property>
1284
                        <property name="orientation">
1285
                            <enum>Vertical</enum>
1286
                        </property>
1287
                        <property name="sizeType">
1288
                            <enum>Expanding</enum>
1289
                        </property>
1290
                        <property name="sizeHint">
1291
                            <size>
1292
                                <width>21</width>
1293
                                <height>70</height>
1294
                            </size>
1295
                        </property>
1296
                    </spacer>
1297
                </vbox>
1298
            </widget>
1299
        </widget>
1300
        <widget class="TQLabel">
1301
            <property name="name">
1302
                <cstring>labelStatusMessage</cstring>
1303
            </property>
1304
            <property name="text">
1305
                <string></string>
1306
            </property>
1307
            <property name="alignment">
1308
                <set>AlignCenter</set>
1309
            </property>
1310
        </widget>
1311
    </vbox>
1312
</widget>
1313
<customwidgets>
1314
    <customwidget>
1315
        <class>Kopete::UI::PasswordWidget</class>
1316
        <header location="local">kopetepasswordwidget.h</header>
1317
        <sizehint>
1318
            <width>50</width>
1319
            <height>50</height>
1320
        </sizehint>
1321
        <container>0</container>
1322
        <sizepolicy>
1323
            <hordata>1</hordata>
1324
            <verdata>0</verdata>
1325
            <horstretch>0</horstretch>
1326
            <verstretch>0</verstretch>
1327
        </sizepolicy>
1328
        <pixmap>image0</pixmap>
1329
        <signal>changed()</signal>
1330
    </customwidget>
1331
</customwidgets>
1332
<images>
1333
    <image name="image0">
1334
        <data format="PNG" length="868">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032b49444154388db59531681b6714c77f32373c8186ef0305eea0050932f8201d944d493bc4d0a1a21e4427bb533a74299dbc25905288a7d0b9836932d58116eac1411932388ba421a5a7a17005174e83e00e2cb80f6ab83708d2e18bec8ada26d0f4c1c1ddbbf7fdeeff3efeefbbda70346419b76fdd7ecd3b88e16858ab2dc183c3c1ebee7a97a99b521515d969f65610e71cd971c6f8d7312ccef3c152e9b39f9e11351d36164acdb819d4a9b4c4362ce5a2c48a45162588253ff5cfe5a2c406862405d9138e5eea2a18609a4fb12d212d7ea42c334089ac92e6423113cab902826d4227568a002480a942780dead16a2767e0ca55949a81668023b2c2e8952139748c270e58aa115aebc2675b86b80b6143710aa1b9049ccd336e064a5979e8e039ec7f5f78544368af1b24807ca64cff50befba6a0b765d8be2b67f00bc1562c95e6441646afe40d54b9f36948af2fb4df078722440c0e2af6f70a064f0be2568beea6c5885b01af2d6f4a2db10dc8ff128e0edc19f4f32f8576dbe1707022fcf2b4647babce175f8780f0c31307a7e0162bdc55c5e52247e742fabbc31843af2f9886c32d40d4b0fb4849278ef20476ee59c62f7ced3831848d55f0aa62816ca6de11ad37ed2fa10f1ce9c4619ac2c647824a45dc1100f2a9e2542e067b9f82155f108adf539c61f781924efc0745c0be57273240b08409e62ac508d0f085c94c112c83e778a54608434331733cbc9f331a5bf2636f85a855bfda15f9694e27565ad785e99fcae0a062fb6e4479a2f43e16eacd3a0fef433175ec7e95a1aa98a6d0e95454f355f2bff65803e8f5bddbf7f70a0687393bf72ced2e74ba253bdfb631a1c139872e948d7e487c83ab15979a2301dcba033a373c7e52f0f851c1f885d0ed080ec88f7374ae672b7f3b72249b115143389fce7f4e5e91d11398cefd986e6c099816839fbd1bd2c9b91ad3147afd16a32387534580ac58957c0e3ece485230d77c5ba6a1f4fa42ef9398719253153e1f5f8f687f9013df80f16684c1e0161969b20aae0d47437fc007d0f950882210c19fad81bf24f04e399701a04820380769a2e485e28a0b14b380e4a5927059e85be67cac5dfae63fc61af87fd4ff027ed7f0e16858fb1ba5cd86c64770b2e90000000049454e44ae426082</data>
1335
    </image>
1336
</images>
1337
<connections>
1338
    <connection>
1339
        <sender>m_useDisplayPicture</sender>
1340
        <signal>toggled(bool)</signal>
1341
        <receiver>m_selectImage</receiver>
1342
        <slot>setEnabled(bool)</slot>
1343
    </connection>
1344
    <connection>
1345
        <sender>m_useDisplayPicture</sender>
1346
        <signal>toggled(bool)</signal>
1347
        <receiver>m_selectImage</receiver>
1348
        <slot>setEnabled(bool)</slot>
1349
    </connection>
1350
    <connection>
1351
        <sender>m_useDisplayPicture</sender>
1352
        <signal>toggled(bool)</signal>
1353
        <receiver>textLabel1_2</receiver>
1354
        <slot>setEnabled(bool)</slot>
1355
    </connection>
1356
    <connection>
1357
        <sender>optionOverrideServer</sender>
1358
        <signal>toggled(bool)</signal>
1359
        <receiver>labelServer</receiver>
1360
        <slot>setEnabled(bool)</slot>
1361
    </connection>
1362
    <connection>
1363
        <sender>optionOverrideServer</sender>
1364
        <signal>toggled(bool)</signal>
1365
        <receiver>m_serverName</receiver>
1366
        <slot>setEnabled(bool)</slot>
1367
    </connection>
1368
    <connection>
1369
        <sender>optionOverrideServer</sender>
1370
        <signal>toggled(bool)</signal>
1371
        <receiver>labelPort</receiver>
1372
        <slot>setEnabled(bool)</slot>
1373
    </connection>
1374
    <connection>
1375
        <sender>optionOverrideServer</sender>
1376
        <signal>toggled(bool)</signal>
1377
        <receiver>m_serverPort</receiver>
1378
        <slot>setEnabled(bool)</slot>
1379
    </connection>
1380
    <connection>
1381
        <sender>m_useDisplayPicture</sender>
1382
        <signal>toggled(bool)</signal>
1383
        <receiver>m_displayPicture</receiver>
1384
        <slot>setEnabled(bool)</slot>
1385
    </connection>
1386
    <connection>
1387
        <sender>m_useWebcamPort</sender>
1388
        <signal>toggled(bool)</signal>
1389
        <receiver>m_webcamPort</receiver>
1390
        <slot>setEnabled(bool)</slot>
1391
    </connection>
1392
</connections>
1393
<tabstops>
1394
    <tabstop>tabWidget3</tabstop>
1395
    <tabstop>optionOverrideServer</tabstop>
1396
    <tabstop>m_serverName</tabstop>
1397
    <tabstop>m_serverPort</tabstop>
1398
    <tabstop>optionUseHttpMethod</tabstop>
1399
    <tabstop>m_login</tabstop>
1400
    <tabstop>m_autologin</tabstop>
1401
    <tabstop>buttonRegister</tabstop>
1402
    <tabstop>m_displayName</tabstop>
1403
    <tabstop>m_phw</tabstop>
1404
    <tabstop>m_phh</tabstop>
1405
    <tabstop>m_phm</tabstop>
1406
    <tabstop>m_useDisplayPicture</tabstop>
1407
    <tabstop>m_selectImage</tabstop>
1408
    <tabstop>m_AL</tabstop>
1409
    <tabstop>m_blockButton</tabstop>
1410
    <tabstop>m_allowButton</tabstop>
1411
    <tabstop>m_BL</tabstop>
1412
    <tabstop>m_blp</tabstop>
1413
    <tabstop>m_RLButton</tabstop>
1414
</tabstops>
1415
<layoutdefaults spacing="6" margin="11"/>
1416
<includehints>
1417
    <includehint>kopetepasswordwidget.h</includehint>
1418
    <includehint>kcombobox.h</includehint>
1419
    <includehint>klineedit.h</includehint>
1420
</includehints>
1421
</UI>
(-)tdenetwork.ori/kopete/protocols/msn/ui/msneditaccountwidget.cpp (-369 lines)
Lines 1-369 Link Here
1
/*
2
    msneditaccountwidget.cpp - MSN Account Widget
3
4
    Copyright (c) 2003      by Olivier Goffart       <ogoffart @ kde.org>
5
    Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>
6
7
    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
8
9
    *************************************************************************
10
    *                                                                       *
11
    * This program is free software; you can redistribute it and/or modify  *
12
    * it under the terms of the GNU General Public License as published by  *
13
    * the Free Software Foundation; either version 2 of the License, or     *
14
    * (at your option) any later version.                                   *
15
    *                                                                       *
16
    *************************************************************************
17
*/
18
19
#include "msneditaccountwidget.h"
20
21
#include <tqcheckbox.h>
22
#include <tqgroupbox.h>
23
#include <tqimage.h>
24
#include <tqlabel.h>
25
#include <tqlayout.h>
26
#include <tqlineedit.h>
27
#include <tqlistbox.h>
28
#include <tqpushbutton.h>
29
#include <tqregexp.h>
30
#include <tqspinbox.h>
31
#include <kcombobox.h>
32
33
#include <kautoconfig.h>
34
#include <tdefiledialog.h>
35
#include <tdelocale.h>
36
#include <tdemessagebox.h>
37
#include <kstandarddirs.h>
38
#include <tdeio/netaccess.h>
39
#include <kdebug.h>
40
#include <kpassdlg.h>
41
#include <krun.h>
42
#include <tdeconfig.h>
43
#include <kpixmapregionselectordialog.h>
44
45
#include "kopeteuiglobal.h"
46
#include "kopeteglobal.h"
47
48
#include "kopetepasswordwidget.h"
49
#include "kopeteaccountmanager.h"
50
51
#include "msnaccount.h"
52
#include "msncontact.h"
53
#include "msneditaccountui.h"
54
#include "msnnotifysocket.h"
55
#include "msnprotocol.h"
56
57
class MSNEditAccountWidgetPrivate
58
{
59
public:
60
	MSNProtocol *protocol;
61
	KAutoConfig *autoConfig;
62
	MSNEditAccountUI *ui;
63
64
	TQString pictureUrl;
65
	TQImage pictureData;
66
};
67
68
MSNEditAccountWidget::MSNEditAccountWidget( MSNProtocol *proto, Kopete::Account *account, TQWidget *parent, const char * /* name */ )
69
: TQWidget( parent ), KopeteEditAccountWidget( account )
70
{
71
	d = new MSNEditAccountWidgetPrivate;
72
73
	d->protocol=proto;
74
75
	( new TQVBoxLayout( this, 0, 0 ) )->setAutoAdd( true );
76
77
	d->ui = new MSNEditAccountUI( this );
78
79
	d->autoConfig = new KAutoConfig( TQT_TQOBJECT(d->ui) );
80
	d->autoConfig->addWidget( d->ui->global_settings_page, "MSN" );
81
	d->autoConfig->addWidget( d->ui->privacy_page, "MSN" );
82
	//the JabberAccount need to be saved as text, and can't be handled by kautoconfig
83
	d->autoConfig->ignoreSubWidget( d->ui->JabberAccount );
84
	d->autoConfig->retrieveSettings( true );
85
	
86
	//Get a list of all jabber accounts
87
	TDEGlobal::config()->setGroup("MSN");
88
	TQString jab_account=TDEGlobal::config()->readEntry("JabberAccount");
89
	
90
	TQPtrList<Kopete::Account>  accounts = Kopete::AccountManager::self()->accounts();
91
	for(Kopete::Account *a=accounts.first() ; a; a=accounts.next() )
92
	{
93
		if(a->protocol()->pluginId()=="JabberProtocol")
94
		{
95
			d->ui->JabberAccount->insertItem(a->accountId());
96
			if( jab_account.isEmpty() )
97
				jab_account=a->accountId();
98
		}
99
	}
100
	d->ui->JabberAccount->setCurrentText(jab_account);
101
102
	// FIXME: actually, I don't know how to set fonts for qlistboxitem - Olivier
103
	d->ui->label_font->hide();
104
105
	// default fields
106
	if ( account )
107
	{
108
		TDEConfigGroup * config=account->configGroup();
109
	
110
		d->ui->m_login->setText( account->accountId() );
111
		d->ui->m_password->load( &static_cast<MSNAccount *>(account)->password() );
112
113
		//remove me after we can change account ids (Matt)
114
		d->ui->m_login->setDisabled( true );
115
		d->ui->m_autologin->setChecked( account->excludeConnect()  );
116
		if ( ( static_cast<MSNAccount*>(account)->serverName() != "messenger.hotmail.com" ) || ( static_cast<MSNAccount*>(account)->serverPort() != 1863) ) {
117
			d->ui->optionOverrideServer->setChecked( true );
118
		}
119
		
120
		d->ui->m_webcamPort->setDisabled(true);
121
		uint port=config->readNumEntry("WebcamPort" ,0);
122
		d->ui->m_useWebcamPort->setChecked( port != 0);
123
		d->ui->m_webcamPort->setValue( port != 0 ? port : 6891 );
124
125
		d->ui->optionUseHttpMethod->setChecked( static_cast<MSNAccount*>(account)->useHttpMethod() );
126
		
127
		MSNContact *myself = static_cast<MSNContact *>( account->myself() );
128
129
		d->ui->m_displayName->setText( myself->property( Kopete::Global::Properties::self()->nickName()).value().toString() );
130
		d->ui->m_phw->setText( config->readEntry("PHW") );
131
		d->ui->m_phm->setText( config->readEntry("PHM") );
132
		d->ui->m_phh->setText( config->readEntry("PHH") );
133
134
		bool connected = account->isConnected();
135
		if ( connected )
136
		{
137
			d->ui->m_warning_1->hide();
138
			d->ui->m_warning_2->hide();
139
		}
140
		d->ui->m_phones->setEnabled( connected );
141
		d->ui->m_displayName->setEnabled( connected );
142
		d->ui->m_allowButton->setEnabled( connected );
143
		d->ui->m_blockButton->setEnabled( connected );
144
145
		MSNAccount *m_account = static_cast<MSNAccount*>( account );
146
		d->ui->m_serverName->setText( m_account->serverName() );
147
		d->ui->m_serverPort->setValue( m_account->serverPort() );
148
149
		TQStringList blockList = config->readListEntry( "blockList" );
150
		TQStringList allowList = config->readListEntry( "allowList" );
151
		//TQStringList reverseList =  config->readListEntry("reverseList" );
152
153
		for ( TQStringList::Iterator it = blockList.begin(); it != blockList.end(); ++it )
154
			d->ui->m_BL->insertItem( *it );
155
156
		for ( TQStringList::Iterator it = allowList.begin(); it != allowList.end(); ++it )
157
			d->ui->m_AL->insertItem( *it );
158
159
		d->ui->m_blp->setChecked( config->readEntry( "BLP" ) == "BL" );
160
161
		d->pictureUrl = locateLocal( "appdata", "msnpicture-" +
162
			account->accountId().lower().replace( TQRegExp("[./~]" ), "-" ) + ".png" );
163
		d->ui->m_displayPicture->setPixmap( d->pictureUrl );
164
165
		d->ui->m_useDisplayPicture->setChecked( config->readBoolEntry( "exportCustomPicture" ));
166
167
		// Global Identity
168
		d->ui->m_globalIdentity->setChecked( config->readBoolEntry("ExcludeGlobalIdentity", false) );
169
	}
170
	else
171
	{
172
		d->ui->tab_contacts->setDisabled( true );
173
		d->ui->m_displayName->setDisabled( true );
174
		d->ui->m_phones->setDisabled( true );
175
	}
176
177
	connect( d->ui->m_allowButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotAllow() ) );
178
	connect( d->ui->m_blockButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotBlock() ) );
179
	connect( d->ui->m_selectImage, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotSelectImage() ) );
180
	connect( d->ui->m_RLButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotShowReverseList() ) );
181
	connect( d->ui->buttonRegister, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotOpenRegister()));
182
	TQWidget::setTabOrder( d->ui->m_login, d->ui->m_password->mRemembered );
183
	TQWidget::setTabOrder( d->ui->m_password->mRemembered, d->ui->m_password->mPassword );
184
	TQWidget::setTabOrder( d->ui->m_password->mPassword, d->ui->m_autologin );
185
}
186
187
MSNEditAccountWidget::~MSNEditAccountWidget()
188
{
189
	delete d;
190
}
191
192
Kopete::Account * MSNEditAccountWidget::apply()
193
{
194
	d->autoConfig->saveSettings();
195
	TDEGlobal::config()->setGroup("MSN");
196
	TDEGlobal::config()->writeEntry("JabberAccount", d->ui->JabberAccount->currentText());
197
198
	if ( !account() )
199
		setAccount( new MSNAccount( d->protocol, d->ui->m_login->text() ) );
200
	
201
	TDEConfigGroup *config=account()->configGroup();
202
203
	account()->setExcludeConnect( d->ui->m_autologin->isChecked() );
204
	d->ui->m_password->save( &static_cast<MSNAccount *>(account())->password() );
205
206
	config->writeEntry( "exportCustomPicture", d->ui->m_useDisplayPicture->isChecked() );
207
	if (d->ui->optionOverrideServer->isChecked() ) {
208
		config->writeEntry( "serverName", d->ui->m_serverName->text() );
209
		config->writeEntry( "serverPort", d->ui->m_serverPort->value()  );
210
	}
211
	else {
212
		config->writeEntry( "serverName", "messenger.hotmail.com" );
213
		config->writeEntry( "serverPort", "1863" );
214
	}
215
216
	config->writeEntry( "useHttpMethod", d->ui->optionUseHttpMethod->isChecked() );
217
	
218
	if(d->ui->m_useWebcamPort->isChecked())
219
		config->writeEntry( "WebcamPort" , d->ui->m_webcamPort->value() );
220
	else
221
		config->writeEntry( "WebcamPort" , 0 );
222
223
	// Global Identity
224
	config->writeEntry( "ExcludeGlobalIdentity", d->ui->m_globalIdentity->isChecked() );
225
226
	// Save the avatar image
227
	if( d->ui->m_useDisplayPicture->isChecked() && !d->pictureData.isNull() )
228
	{
229
		d->pictureUrl = locateLocal( "appdata", "msnpicture-" +
230
				account()->accountId().lower().replace( TQRegExp("[./~]" ), "-" ) + ".png" );
231
		if ( d->pictureData.save( d->pictureUrl, "PNG" ) )
232
		{
233
			static_cast<MSNAccount *>( account() )->setPictureUrl( d->pictureUrl );
234
		}
235
		else
236
		{
237
			KMessageBox::sorry( this, i18n( "<qt>An error occurred when trying to change the display picture.<br>"
238
					"Make sure that you have selected a correct image file</qt>" ), i18n( "MSN Plugin" ) );
239
		}
240
	}
241
242
	static_cast<MSNAccount *>( account() )->resetPictureObject();
243
244
	if ( account()->isConnected() )
245
	{
246
		MSNContact *myself = static_cast<MSNContact *>( account()->myself() );
247
		MSNNotifySocket *notify = static_cast<MSNAccount *>( account() )->notifySocket();
248
		if ( d->ui->m_displayName->text() != myself->property( Kopete::Global::Properties::self()->nickName()).value().toString() )
249
			static_cast<MSNAccount *>( account() )->setPublicName( d->ui->m_displayName->text() );
250
251
		if ( notify )
252
		{
253
			if ( d->ui->m_phw->text() != myself->phoneWork() && ( !d->ui->m_phw->text().isEmpty() || !myself->phoneWork().isEmpty() ) )
254
				notify->changePhoneNumber( "PHW", d->ui->m_phw->text() );
255
			if( d->ui->m_phh->text() != myself->phoneHome() && ( !d->ui->m_phh->text().isEmpty() || !myself->phoneHome().isEmpty() ) )
256
				notify->changePhoneNumber( "PHH", d->ui->m_phh->text() );
257
			if( d->ui->m_phm->text() != myself->phoneMobile() && ( !d->ui->m_phm->text().isEmpty() || !myself->phoneMobile().isEmpty() ) )
258
				notify->changePhoneNumber( "PHM", d->ui->m_phm->text() );
259
			// (the && .isEmpty is because one can be null and the other empty)
260
261
			if ( ( config->readEntry("BLP") == "BL" ) != d->ui->m_blp->isChecked() )
262
			{
263
				// Yes, I know, calling sendCommand here is not very clean - Olivier
264
				notify->sendCommand( "BLP", d->ui->m_blp->isChecked() ? "BL" : "AL" );
265
			}
266
		}
267
	}
268
	return account();
269
}
270
271
bool MSNEditAccountWidget::validateData()
272
{
273
	TQString userid = d->ui->m_login->text();
274
	if ( MSNProtocol::validContactId( userid ) )
275
		return true;
276
277
	KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry,
278
		i18n( "<qt>You must enter a valid email address.</qt>" ), i18n( "MSN Plugin" ) );
279
	return false;
280
}
281
282
void MSNEditAccountWidget::slotAllow()
283
{
284
	//TODO: play with multiple selection
285
	TQListBoxItem *item = d->ui->m_BL->selectedItem();
286
	if ( !item )
287
		return;
288
289
	TQString handle = item->text();
290
291
	MSNNotifySocket *notify = static_cast<MSNAccount *>( account() )->notifySocket();
292
	if ( !notify )
293
		return;
294
	notify->removeContact( handle, MSNProtocol::BL, TQString(), TQString() );
295
296
	d->ui->m_BL->takeItem( item );
297
	d->ui->m_AL->insertItem( item );
298
}
299
300
void MSNEditAccountWidget::slotBlock()
301
{
302
	//TODO: play with multiple selection
303
	TQListBoxItem *item = d->ui->m_AL->selectedItem();
304
	if ( !item )
305
		return;
306
307
	TQString handle = item->text();
308
309
	MSNNotifySocket *notify = static_cast<MSNAccount *>( account() )->notifySocket();
310
	if ( !notify )
311
		return;
312
313
	notify->removeContact( handle, MSNProtocol::AL, TQString(), TQString() );
314
315
	d->ui->m_AL->takeItem( item );
316
	d->ui->m_BL->insertItem( item );
317
}
318
319
void MSNEditAccountWidget::slotShowReverseList()
320
{
321
	TQStringList reverseList = account()->configGroup()->readListEntry( "reverseList" );
322
	KMessageBox::informationList( this, i18n( "Here you can see a list of contacts who added you to their contact list" ), reverseList,
323
		i18n( "Reverse List - MSN Plugin" ) );
324
}
325
326
void MSNEditAccountWidget::slotSelectImage()
327
{
328
	TQString path = 0;
329
	bool remoteFile = false;
330
	KURL filePath = KFileDialog::getImageOpenURL( TQString(), this, i18n( "MSN Display Picture" ) );
331
	if( filePath.isEmpty() )
332
		return;
333
334
	if( !filePath.isLocalFile() ) {
335
		if(!TDEIO::NetAccess::download( filePath, path, this )) {
336
			KMessageBox::sorry( this, i18n( "Downloading of display image failed" ), i18n( "MSN Plugin" ) );
337
			return;
338
		}
339
		remoteFile = true;
340
	}
341
	else path = filePath.path();
342
343
	TQImage img( path );
344
	img = KPixmapRegionSelectorDialog::getSelectedImage( TQPixmap(img), 96, 96, this );
345
346
	if(!img.isNull()) 
347
	{
348
		img = MSNProtocol::protocol()->scalePicture(img);
349
	
350
		d->ui->m_displayPicture->setPixmap( TQPixmap(img) );
351
		d->pictureData = img;
352
	}
353
	else
354
	{
355
		KMessageBox::sorry( this, i18n( "<qt>An error occurred when trying to change the display picture.<br>"
356
			"Make sure that you have selected a correct image file</qt>" ), i18n( "MSN Plugin" ) );
357
	}
358
	if( remoteFile ) TDEIO::NetAccess::removeTempFile( path );
359
}
360
361
void MSNEditAccountWidget::slotOpenRegister()
362
{
363
	KRun::runURL( "http://register.passport.net/", "text/html" );
364
}
365
366
#include "msneditaccountwidget.moc"
367
368
// vim: set noet ts=4 sts=4 sw=4:
369
(-)tdenetwork.ori/kopete/protocols/msn/ui/msneditaccountwidget.h (-60 lines)
Lines 1-60 Link Here
1
/*
2
    msneditaccountwidget.h - MSN Account Widget
3
4
    Copyright (c) 2003      by Olivier Goffart       <ogoffart @ kde.org>
5
    Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>
6
7
    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
8
9
    *************************************************************************
10
    *                                                                       *
11
    * This program is free software; you can redistribute it and/or modify  *
12
    * it under the terms of the GNU General Public License as published by  *
13
    * the Free Software Foundation; either version 2 of the License, or     *
14
    * (at your option) any later version.                                   *
15
    *                                                                       *
16
    *************************************************************************
17
*/
18
19
#ifndef MSNEDITACCOUNTWIDEGET_H
20
#define MSNEDITACCOUNTWIDEGET_H
21
22
#include <tqwidget.h>
23
24
#include "editaccountwidget.h"
25
26
namespace Kopete { class Account; }
27
28
class MSNProtocol;
29
30
class MSNEditAccountWidgetPrivate;
31
32
/**
33
 * @author Olivier Goffart <ogoffart @ kde.org>
34
 */
35
class MSNEditAccountWidget : public TQWidget, public KopeteEditAccountWidget
36
{
37
	Q_OBJECT
38
  
39
40
public:
41
	MSNEditAccountWidget( MSNProtocol *proto, Kopete::Account *account, TQWidget *parent = 0, const char *name = 0 );
42
	~MSNEditAccountWidget();
43
	virtual bool validateData();
44
	virtual Kopete::Account * apply();
45
46
private slots:
47
	void slotAllow();
48
	void slotBlock();
49
	void slotShowReverseList();
50
	void slotSelectImage();
51
	void slotOpenRegister();
52
53
private:
54
	MSNEditAccountWidgetPrivate *d;
55
};
56
57
#endif
58
59
// vim: set noet ts=4 sts=4 sw=4:
60
(-)tdenetwork.ori/kopete/protocols/msn/ui/msninfo.ui (-221 lines)
Lines 1-221 Link Here
1
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
2
<class>MSNInfo</class>
3
<widget class="TQWidget">
4
    <property name="name">
5
        <cstring>MSNInfo</cstring>
6
    </property>
7
    <property name="geometry">
8
        <rect>
9
            <x>0</x>
10
            <y>0</y>
11
            <width>457</width>
12
            <height>360</height>
13
        </rect>
14
    </property>
15
    <vbox>
16
        <property name="name">
17
            <cstring>unnamed</cstring>
18
        </property>
19
        <widget class="TQLayoutWidget">
20
            <property name="name">
21
                <cstring>Layout22</cstring>
22
            </property>
23
            <hbox>
24
                <property name="name">
25
                    <cstring>unnamed</cstring>
26
                </property>
27
                <property name="margin">
28
                    <number>0</number>
29
                </property>
30
                <property name="spacing">
31
                    <number>6</number>
32
                </property>
33
                <widget class="TQLabel">
34
                    <property name="name">
35
                        <cstring>TextLabel2_2</cstring>
36
                    </property>
37
                    <property name="sizePolicy">
38
                        <sizepolicy>
39
                            <hsizetype>4</hsizetype>
40
                            <vsizetype>4</vsizetype>
41
                            <horstretch>0</horstretch>
42
                            <verstretch>0</verstretch>
43
                        </sizepolicy>
44
                    </property>
45
                    <property name="text">
46
                        <string>Email address:</string>
47
                    </property>
48
                </widget>
49
                <widget class="TQLineEdit">
50
                    <property name="name">
51
                        <cstring>m_id</cstring>
52
                    </property>
53
                    <property name="readOnly">
54
                        <bool>true</bool>
55
                    </property>
56
                </widget>
57
            </hbox>
58
        </widget>
59
        <widget class="TQLayoutWidget">
60
            <property name="name">
61
                <cstring>Layout22_2</cstring>
62
            </property>
63
            <hbox>
64
                <property name="name">
65
                    <cstring>unnamed</cstring>
66
                </property>
67
                <property name="margin">
68
                    <number>0</number>
69
                </property>
70
                <property name="spacing">
71
                    <number>6</number>
72
                </property>
73
                <widget class="TQLabel">
74
                    <property name="name">
75
                        <cstring>TextLabel2_2_2</cstring>
76
                    </property>
77
                    <property name="sizePolicy">
78
                        <sizepolicy>
79
                            <hsizetype>4</hsizetype>
80
                            <vsizetype>4</vsizetype>
81
                            <horstretch>0</horstretch>
82
                            <verstretch>0</verstretch>
83
                        </sizepolicy>
84
                    </property>
85
                    <property name="text">
86
                        <string>Display name:</string>
87
                    </property>
88
                </widget>
89
                <widget class="TQLineEdit">
90
                    <property name="name">
91
                        <cstring>m_displayName</cstring>
92
                    </property>
93
                    <property name="readOnly">
94
                        <bool>true</bool>
95
                    </property>
96
                </widget>
97
            </hbox>
98
        </widget>
99
        <widget class="TQLayoutWidget">
100
            <property name="name">
101
                <cstring>layout3</cstring>
102
            </property>
103
            <hbox>
104
                <property name="name">
105
                    <cstring>unnamed</cstring>
106
                </property>
107
                <widget class="TQLabel">
108
                    <property name="name">
109
                        <cstring>textLabel1</cstring>
110
                    </property>
111
                    <property name="text">
112
                        <string>Personal message:</string>
113
                    </property>
114
                </widget>
115
                <widget class="TQLineEdit">
116
                    <property name="name">
117
                        <cstring>m_personalMessage</cstring>
118
                    </property>
119
                    <property name="readOnly">
120
                        <bool>true</bool>
121
                    </property>
122
                </widget>
123
            </hbox>
124
        </widget>
125
        <widget class="TQGroupBox">
126
            <property name="name">
127
                <cstring>GroupBox2</cstring>
128
            </property>
129
            <property name="title">
130
                <string>Phones</string>
131
            </property>
132
            <grid>
133
                <property name="name">
134
                    <cstring>unnamed</cstring>
135
                </property>
136
                <widget class="TQLabel" row="1" column="0">
137
                    <property name="name">
138
                        <cstring>TextLabel5</cstring>
139
                    </property>
140
                    <property name="text">
141
                        <string>Home:</string>
142
                    </property>
143
                </widget>
144
                <widget class="TQLabel" row="0" column="0">
145
                    <property name="name">
146
                        <cstring>TextLabel6</cstring>
147
                    </property>
148
                    <property name="text">
149
                        <string>Work:</string>
150
                    </property>
151
                </widget>
152
                <widget class="TQLineEdit" row="0" column="1">
153
                    <property name="name">
154
                        <cstring>m_phw</cstring>
155
                    </property>
156
                    <property name="readOnly">
157
                        <bool>true</bool>
158
                    </property>
159
                </widget>
160
                <widget class="TQLineEdit" row="1" column="1">
161
                    <property name="name">
162
                        <cstring>m_phh</cstring>
163
                    </property>
164
                    <property name="readOnly">
165
                        <bool>true</bool>
166
                    </property>
167
                </widget>
168
                <widget class="TQLabel" row="2" column="0">
169
                    <property name="name">
170
                        <cstring>TextLabel7</cstring>
171
                    </property>
172
                    <property name="text">
173
                        <string>Mobile:</string>
174
                    </property>
175
                </widget>
176
                <widget class="TQLineEdit" row="2" column="1">
177
                    <property name="name">
178
                        <cstring>m_phm</cstring>
179
                    </property>
180
                    <property name="readOnly">
181
                        <bool>true</bool>
182
                    </property>
183
                </widget>
184
            </grid>
185
        </widget>
186
        <widget class="TQCheckBox">
187
            <property name="name">
188
                <cstring>m_reversed</cstring>
189
            </property>
190
            <property name="text">
191
                <string>I am on &amp;the contact list of this contact</string>
192
            </property>
193
            <property name="toolTip" stdset="0">
194
                <string>Show whether you are on the contact list of this user</string>
195
            </property>
196
            <property name="whatsThis" stdset="0">
197
                <string>If this box is checked, you are on this user's contact list.
198
If not, the user has not added you to their list, or has removed you.</string>
199
            </property>
200
        </widget>
201
        <spacer>
202
            <property name="name">
203
                <cstring>Spacer10</cstring>
204
            </property>
205
            <property name="orientation">
206
                <enum>Vertical</enum>
207
            </property>
208
            <property name="sizeType">
209
                <enum>Expanding</enum>
210
            </property>
211
            <property name="sizeHint">
212
                <size>
213
                    <width>20</width>
214
                    <height>40</height>
215
                </size>
216
            </property>
217
        </spacer>
218
    </vbox>
219
</widget>
220
<layoutdefaults spacing="6" margin="11"/>
221
</UI>
(-)tdenetwork.ori/kopete/protocols/msn/webcam/CMakeLists.txt (-28 lines)
Lines 1-28 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
add_subdirectory( libmimic )
13
14
include_directories(
15
  ${CMAKE_CURRENT_BINARY_DIR}
16
  ${CMAKE_SOURCE_DIR}/kopete/libkopete
17
  ${TDE_INCLUDE_DIR}
18
  ${TQT_INCLUDE_DIRS}
19
  ${GLIB2_INCLUDE_DIRS}
20
)
21
22
23
##### mimicwrapper (static) #####################
24
25
tde_add_library( mimicwrapper STATIC_PIC AUTOMOC
26
  SOURCES mimicwrapper.cpp msnwebcamdialog.cpp
27
  LINK mimic-static
28
)
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/AUTHORS (-2 lines)
Lines 1-2 Link Here
1
Ole André Vadla Ravnås <oleavr@gmail.com>
2
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/bitstring.c (-88 lines)
Lines 1-88 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include "mimic-private.h"
19
20
/*
21
 * _read_bits
22
 *
23
 * Internal helper-function used to read num_bits
24
 * from stream.
25
 */
26
guint32 _read_bits(MimCtx *ctx, gint num_bits)
27
{
28
    guint32 bits;
29
    
30
    if (ctx->cur_chunk_len >= 16) {
31
        guchar *input_buf = (guchar *) ctx->data_buffer + ctx->data_index;
32
33
        if (!ctx->read_odd) {
34
            ctx->read_odd = TRUE;
35
36
            ctx->cur_chunk = (input_buf[3] << 24) |
37
                             (input_buf[2] << 16) |
38
                             (input_buf[1] <<  8) |
39
                              input_buf[0];
40
41
        } else {
42
            ctx->read_odd = FALSE;
43
            
44
            ctx->cur_chunk = (input_buf[1] << 24) |
45
                             (input_buf[0] << 16) |
46
                             (input_buf[7] <<  8) |
47
                              input_buf[6];
48
49
            ctx->data_index += 4;
50
        }
51
52
        ctx->cur_chunk_len -= 16;
53
    }
54
55
    bits = (ctx->cur_chunk << ctx->cur_chunk_len) >> (32 - num_bits);
56
    ctx->cur_chunk_len += num_bits;
57
58
    return bits;
59
}
60
61
/*
62
 * _write_bits
63
 *
64
 * Internal helper-function used to write "length"
65
 * bits of "bits" to stream.
66
 */
67
void _write_bits(MimCtx *ctx, guint32 bits, gint length)
68
{
69
    /* Left-align the bit string within its 32-bit container. */
70
    bits <<= (32 - length);
71
72
    /* Append the bit string (one or more of the trailing bits might not fit, but that's ok). */
73
    ctx->cur_chunk |= bits >> ctx->cur_chunk_len;
74
    ctx->cur_chunk_len += length;
75
76
    /* Is it full? */
77
	if (ctx->cur_chunk_len >= 32) {
78
79
        /* Add the full 32-bit chunk to the stream and update counter. */
80
        ctx->chunk_ptr[0] = GUINT32_TO_LE(ctx->cur_chunk);
81
        ctx->chunk_ptr++;
82
        ctx->cur_chunk_len -= 32;
83
84
        /* Add any trailing bits that didn't fit. */
85
        ctx->cur_chunk = bits << (length - ctx->cur_chunk_len);
86
    }
87
}
88
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/CMakeLists.txt (-24 lines)
Lines 1-24 Link Here
1
#################################################
2
#
3
#  (C) 2010-2011 Serghei Amelian
4
#  serghei (DOT) amelian (AT) gmail.com
5
#
6
#  Improvements and feedback are welcome
7
#
8
#  This file is released under GPL >= 2
9
#
10
#################################################
11
12
include_directories(
13
  ${GLIB2_INCLUDE_DIRS}
14
)
15
16
17
##### mimic (static) ############################
18
19
tde_add_library( mimic STATIC_PIC
20
  SOURCES
21
    mimic.c encode.c decode.c bitstring.c vlc_common.c vlc_encode.c
22
    vlc_decode.c fdct_quant.c idct_dequant.c colorspace.c deblock.c
23
  LINK ${GLIB2_LIBRARIES}
24
)
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/colorspace.c (-161 lines)
Lines 1-161 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include "mimic-private.h"
19
20
#define RED_INDEX_1      0
21
#define GREEN_INDEX_1    1
22
#define BLUE_INDEX_1     2
23
24
#define RED_INDEX_2      3
25
#define GREEN_INDEX_2    4
26
#define BLUE_INDEX_2     5
27
28
/*
29
 * _rgb_to_yuv
30
 *
31
 * Internal helper-function used to convert an image
32
 * from RGB 24-bpp packed-pixel to YUV420 planar.
33
 */
34
void _rgb_to_yuv(const guchar *input_rgb,
35
                 guchar *output_y,
36
                 guchar *output_cb,
37
                 guchar *output_cr,
38
                 gint width,
39
                 gint height)
40
{
41
    gint y, x;
42
43
    for (y = 0; y < height; y += 2) {
44
45
        const guchar *src1, *src2;
46
        guchar *dst1, *dst2, *dst3, *dst4;
47
        gint num_cols;
48
49
        src1 = input_rgb + ((height - 1 - y) * width * 3);
50
        src2 = input_rgb + ((height - 2 - y) * width * 3);
51
52
        dst1 = output_y + (y * width);
53
        dst2 = output_y + ((y + 1) * width);
54
        dst3 = output_cb + ((y / 2) * (width / 2));
55
        dst4 = output_cr + ((y / 2) * (width / 2));
56
57
        num_cols = width / 2;
58
59
        for (x = 0; x < num_cols; x++) {
60
61
            gint expr1, expr2, expr3, expr4, expr5, v;
62
63
            expr1 = (src1[BLUE_INDEX_1] * 19595) + (src1[GREEN_INDEX_1] * 38470) + (src1[RED_INDEX_1] * 7471);
64
            expr2 = (src1[BLUE_INDEX_2] * 19595) + (src1[GREEN_INDEX_2] * 38470) + (src1[RED_INDEX_2] * 7471);
65
            expr3 = (src2[BLUE_INDEX_1] * 19595) + (src2[GREEN_INDEX_1] * 38470) + (src2[RED_INDEX_1] * 7471);
66
            expr4 = (src2[BLUE_INDEX_2] * 19595) + (src2[GREEN_INDEX_2] * 38470) + (src2[RED_INDEX_2] * 7471);
67
68
            expr5 = expr1 + expr2 + expr3 + expr4;
69
70
            dst1[0] = expr1 >> 16;
71
            dst1[1] = expr2 >> 16;
72
            dst2[0] = expr3 >> 16;
73
            dst2[1] = expr4 >> 16;
74
75
            v = (((src1[BLUE_INDEX_1] + src1[BLUE_INDEX_2] + src2[BLUE_INDEX_1] + src2[BLUE_INDEX_2]) << 16) - expr5 + 131071) >> 16;
76
            dst3[0] = _clamp_value(((v * 57475) >> 18) + 128);
77
            
78
            v = (((src1[RED_INDEX_1] + src1[RED_INDEX_2] + src2[RED_INDEX_1] + src2[RED_INDEX_2]) << 16) - expr5 + 131071) >> 16;
79
            dst4[0] = ((v * 32244) >> 18) + 128;
80
81
            src1 += 6;
82
            src2 += 6;
83
84
            dst1 += 2;
85
            dst2 += 2;
86
            dst3++;
87
            dst4++;
88
89
        }
90
91
    }
92
93
}
94
95
/*
96
 * _yuv_to_rgb
97
 *
98
 * Internal helper-function used to convert an image
99
 * from YUV420 planar to RGB 24-bpp packed-pixel.
100
 */
101
void _yuv_to_rgb(const guchar *input_y,
102
                 const guchar *input_cb,
103
                 const guchar *input_cr,
104
                 guchar *output_rgb,
105
                 guint width,
106
                 guint height)
107
{
108
    const guchar *src_y, *src_cb, *src_cr;
109
    guchar *dst_rgb;
110
    guint i, j, rgb_stride;
111
    
112
    src_y  = input_y;
113
    src_cb = input_cb;
114
    src_cr = input_cr;
115
    
116
    rgb_stride = width * 3;
117
    dst_rgb = output_rgb + (rgb_stride * (height - 1));
118
    
119
    for (i = 0; i < height; i++) {
120
        const guchar *p_y, *p_cb, *p_cr;
121
        guchar *p_rgb;
122
123
        p_y = src_y;
124
        p_cb = src_cb;
125
        p_cr = src_cr;
126
127
        p_rgb = dst_rgb;
128
129
        for (j = 0; j < width; j++) {
130
            gint v;
131
132
            v = ((p_y[0] * 65536) + ((p_cr[0] - 128) * 133169)) / 65536;
133
            p_rgb[0] = _clamp_value(v);
134
135
            v = ((p_y[0] * 65536) - ((p_cr[0] - 128) * 25821) - ((p_cb[0] - 128) * 38076)) / 65536;
136
            p_rgb[1] = _clamp_value(v);
137
138
            v = ((p_y[0] * 65536) + ((p_cb[0] - 128) * 74711)) / 65536;
139
            p_rgb[2] = _clamp_value(v);
140
141
            p_y++;
142
            if ((j + 1) % 2 == 0) {
143
                p_cb++;
144
                p_cr++;
145
            }
146
147
            p_rgb += 3;
148
        }
149
150
        src_y += width;
151
        if ((i + 1) % 2 == 0) {
152
            src_cb += (width + 1) / 2;
153
            src_cr += (width + 1) / 2;
154
        }
155
156
        dst_rgb -= rgb_stride;
157
158
    }
159
160
}
161
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/COPYING (-504 lines)
Lines 1-504 Link Here
1
		  GNU LESSER GENERAL PUBLIC LICENSE
2
		       Version 2.1, February 1999
3
4
 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
6
 Everyone is permitted to copy and distribute verbatim copies
7
 of this license document, but changing it is not allowed.
8
9
[This is the first released version of the Lesser GPL.  It also counts
10
 as the successor of the GNU Library Public License, version 2, hence
11
 the version number 2.1.]
12
13
			    Preamble
14
15
  The licenses for most software are designed to take away your
16
freedom to share and change it.  By contrast, the GNU General Public
17
Licenses are intended to guarantee your freedom to share and change
18
free software--to make sure the software is free for all its users.
19
20
  This license, the Lesser General Public License, applies to some
21
specially designated software packages--typically libraries--of the
22
Free Software Foundation and other authors who decide to use it.  You
23
can use it too, but we suggest you first think carefully about whether
24
this license or the ordinary General Public License is the better
25
strategy to use in any particular case, based on the explanations below.
26
27
  When we speak of free software, we are referring to freedom of use,
28
not price.  Our General Public Licenses are designed to make sure that
29
you have the freedom to distribute copies of free software (and charge
30
for this service if you wish); that you receive source code or can get
31
it if you want it; that you can change the software and use pieces of
32
it in new free programs; and that you are informed that you can do
33
these things.
34
35
  To protect your rights, we need to make restrictions that forbid
36
distributors to deny you these rights or to ask you to surrender these
37
rights.  These restrictions translate to certain responsibilities for
38
you if you distribute copies of the library or if you modify it.
39
40
  For example, if you distribute copies of the library, whether gratis
41
or for a fee, you must give the recipients all the rights that we gave
42
you.  You must make sure that they, too, receive or can get the source
43
code.  If you link other code with the library, you must provide
44
complete object files to the recipients, so that they can relink them
45
with the library after making changes to the library and recompiling
46
it.  And you must show them these terms so they know their rights.
47
48
  We protect your rights with a two-step method: (1) we copyright the
49
library, and (2) we offer you this license, which gives you legal
50
permission to copy, distribute and/or modify the library.
51
52
  To protect each distributor, we want to make it very clear that
53
there is no warranty for the free library.  Also, if the library is
54
modified by someone else and passed on, the recipients should know
55
that what they have is not the original version, so that the original
56
author's reputation will not be affected by problems that might be
57
introduced by others.
58
59
  Finally, software patents pose a constant threat to the existence of
60
any free program.  We wish to make sure that a company cannot
61
effectively restrict the users of a free program by obtaining a
62
restrictive license from a patent holder.  Therefore, we insist that
63
any patent license obtained for a version of the library must be
64
consistent with the full freedom of use specified in this license.
65
66
  Most GNU software, including some libraries, is covered by the
67
ordinary GNU General Public License.  This license, the GNU Lesser
68
General Public License, applies to certain designated libraries, and
69
is quite different from the ordinary General Public License.  We use
70
this license for certain libraries in order to permit linking those
71
libraries into non-free programs.
72
73
  When a program is linked with a library, whether statically or using
74
a shared library, the combination of the two is legally speaking a
75
combined work, a derivative of the original library.  The ordinary
76
General Public License therefore permits such linking only if the
77
entire combination fits its criteria of freedom.  The Lesser General
78
Public License permits more lax criteria for linking other code with
79
the library.
80
81
  We call this license the "Lesser" General Public License because it
82
does Less to protect the user's freedom than the ordinary General
83
Public License.  It also provides other free software developers Less
84
of an advantage over competing non-free programs.  These disadvantages
85
are the reason we use the ordinary General Public License for many
86
libraries.  However, the Lesser license provides advantages in certain
87
special circumstances.
88
89
  For example, on rare occasions, there may be a special need to
90
encourage the widest possible use of a certain library, so that it becomes
91
a de-facto standard.  To achieve this, non-free programs must be
92
allowed to use the library.  A more frequent case is that a free
93
library does the same job as widely used non-free libraries.  In this
94
case, there is little to gain by limiting the free library to free
95
software only, so we use the Lesser General Public License.
96
97
  In other cases, permission to use a particular library in non-free
98
programs enables a greater number of people to use a large body of
99
free software.  For example, permission to use the GNU C Library in
100
non-free programs enables many more people to use the whole GNU
101
operating system, as well as its variant, the GNU/Linux operating
102
system.
103
104
  Although the Lesser General Public License is Less protective of the
105
users' freedom, it does ensure that the user of a program that is
106
linked with the Library has the freedom and the wherewithal to run
107
that program using a modified version of the Library.
108
109
  The precise terms and conditions for copying, distribution and
110
modification follow.  Pay close attention to the difference between a
111
"work based on the library" and a "work that uses the library".  The
112
former contains code derived from the library, whereas the latter must
113
be combined with the library in order to run.
114
115
		  GNU LESSER GENERAL PUBLIC LICENSE
116
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118
  0. This License Agreement applies to any software library or other
119
program which contains a notice placed by the copyright holder or
120
other authorized party saying it may be distributed under the terms of
121
this Lesser General Public License (also called "this License").
122
Each licensee is addressed as "you".
123
124
  A "library" means a collection of software functions and/or data
125
prepared so as to be conveniently linked with application programs
126
(which use some of those functions and data) to form executables.
127
128
  The "Library", below, refers to any such software library or work
129
which has been distributed under these terms.  A "work based on the
130
Library" means either the Library or any derivative work under
131
copyright law: that is to say, a work containing the Library or a
132
portion of it, either verbatim or with modifications and/or translated
133
straightforwardly into another language.  (Hereinafter, translation is
134
included without limitation in the term "modification".)
135
136
  "Source code" for a work means the preferred form of the work for
137
making modifications to it.  For a library, complete source code means
138
all the source code for all modules it contains, plus any associated
139
interface definition files, plus the scripts used to control compilation
140
and installation of the library.
141
142
  Activities other than copying, distribution and modification are not
143
covered by this License; they are outside its scope.  The act of
144
running a program using the Library is not restricted, and output from
145
such a program is covered only if its contents constitute a work based
146
on the Library (independent of the use of the Library in a tool for
147
writing it).  Whether that is true depends on what the Library does
148
and what the program that uses the Library does.
149
  
150
  1. You may copy and distribute verbatim copies of the Library's
151
complete source code as you receive it, in any medium, provided that
152
you conspicuously and appropriately publish on each copy an
153
appropriate copyright notice and disclaimer of warranty; keep intact
154
all the notices that refer to this License and to the absence of any
155
warranty; and distribute a copy of this License along with the
156
Library.
157
158
  You may charge a fee for the physical act of transferring a copy,
159
and you may at your option offer warranty protection in exchange for a
160
fee.
161
162
  2. You may modify your copy or copies of the Library or any portion
163
of it, thus forming a work based on the Library, and copy and
164
distribute such modifications or work under the terms of Section 1
165
above, provided that you also meet all of these conditions:
166
167
    a) The modified work must itself be a software library.
168
169
    b) You must cause the files modified to carry prominent notices
170
    stating that you changed the files and the date of any change.
171
172
    c) You must cause the whole of the work to be licensed at no
173
    charge to all third parties under the terms of this License.
174
175
    d) If a facility in the modified Library refers to a function or a
176
    table of data to be supplied by an application program that uses
177
    the facility, other than as an argument passed when the facility
178
    is invoked, then you must make a good faith effort to ensure that,
179
    in the event an application does not supply such function or
180
    table, the facility still operates, and performs whatever part of
181
    its purpose remains meaningful.
182
183
    (For example, a function in a library to compute square roots has
184
    a purpose that is entirely well-defined independent of the
185
    application.  Therefore, Subsection 2d requires that any
186
    application-supplied function or table used by this function must
187
    be optional: if the application does not supply it, the square
188
    root function must still compute square roots.)
189
190
These requirements apply to the modified work as a whole.  If
191
identifiable sections of that work are not derived from the Library,
192
and can be reasonably considered independent and separate works in
193
themselves, then this License, and its terms, do not apply to those
194
sections when you distribute them as separate works.  But when you
195
distribute the same sections as part of a whole which is a work based
196
on the Library, the distribution of the whole must be on the terms of
197
this License, whose permissions for other licensees extend to the
198
entire whole, and thus to each and every part regardless of who wrote
199
it.
200
201
Thus, it is not the intent of this section to claim rights or contest
202
your rights to work written entirely by you; rather, the intent is to
203
exercise the right to control the distribution of derivative or
204
collective works based on the Library.
205
206
In addition, mere aggregation of another work not based on the Library
207
with the Library (or with a work based on the Library) on a volume of
208
a storage or distribution medium does not bring the other work under
209
the scope of this License.
210
211
  3. You may opt to apply the terms of the ordinary GNU General Public
212
License instead of this License to a given copy of the Library.  To do
213
this, you must alter all the notices that refer to this License, so
214
that they refer to the ordinary GNU General Public License, version 2,
215
instead of to this License.  (If a newer version than version 2 of the
216
ordinary GNU General Public License has appeared, then you can specify
217
that version instead if you wish.)  Do not make any other change in
218
these notices.
219
220
  Once this change is made in a given copy, it is irreversible for
221
that copy, so the ordinary GNU General Public License applies to all
222
subsequent copies and derivative works made from that copy.
223
224
  This option is useful when you wish to copy part of the code of
225
the Library into a program that is not a library.
226
227
  4. You may copy and distribute the Library (or a portion or
228
derivative of it, under Section 2) in object code or executable form
229
under the terms of Sections 1 and 2 above provided that you accompany
230
it with the complete corresponding machine-readable source code, which
231
must be distributed under the terms of Sections 1 and 2 above on a
232
medium customarily used for software interchange.
233
234
  If distribution of object code is made by offering access to copy
235
from a designated place, then offering equivalent access to copy the
236
source code from the same place satisfies the requirement to
237
distribute the source code, even though third parties are not
238
compelled to copy the source along with the object code.
239
240
  5. A program that contains no derivative of any portion of the
241
Library, but is designed to work with the Library by being compiled or
242
linked with it, is called a "work that uses the Library".  Such a
243
work, in isolation, is not a derivative work of the Library, and
244
therefore falls outside the scope of this License.
245
246
  However, linking a "work that uses the Library" with the Library
247
creates an executable that is a derivative of the Library (because it
248
contains portions of the Library), rather than a "work that uses the
249
library".  The executable is therefore covered by this License.
250
Section 6 states terms for distribution of such executables.
251
252
  When a "work that uses the Library" uses material from a header file
253
that is part of the Library, the object code for the work may be a
254
derivative work of the Library even though the source code is not.
255
Whether this is true is especially significant if the work can be
256
linked without the Library, or if the work is itself a library.  The
257
threshold for this to be true is not precisely defined by law.
258
259
  If such an object file uses only numerical parameters, data
260
structure layouts and accessors, and small macros and small inline
261
functions (ten lines or less in length), then the use of the object
262
file is unrestricted, regardless of whether it is legally a derivative
263
work.  (Executables containing this object code plus portions of the
264
Library will still fall under Section 6.)
265
266
  Otherwise, if the work is a derivative of the Library, you may
267
distribute the object code for the work under the terms of Section 6.
268
Any executables containing that work also fall under Section 6,
269
whether or not they are linked directly with the Library itself.
270
271
  6. As an exception to the Sections above, you may also combine or
272
link a "work that uses the Library" with the Library to produce a
273
work containing portions of the Library, and distribute that work
274
under terms of your choice, provided that the terms permit
275
modification of the work for the customer's own use and reverse
276
engineering for debugging such modifications.
277
278
  You must give prominent notice with each copy of the work that the
279
Library is used in it and that the Library and its use are covered by
280
this License.  You must supply a copy of this License.  If the work
281
during execution displays copyright notices, you must include the
282
copyright notice for the Library among them, as well as a reference
283
directing the user to the copy of this License.  Also, you must do one
284
of these things:
285
286
    a) Accompany the work with the complete corresponding
287
    machine-readable source code for the Library including whatever
288
    changes were used in the work (which must be distributed under
289
    Sections 1 and 2 above); and, if the work is an executable linked
290
    with the Library, with the complete machine-readable "work that
291
    uses the Library", as object code and/or source code, so that the
292
    user can modify the Library and then relink to produce a modified
293
    executable containing the modified Library.  (It is understood
294
    that the user who changes the contents of definitions files in the
295
    Library will not necessarily be able to recompile the application
296
    to use the modified definitions.)
297
298
    b) Use a suitable shared library mechanism for linking with the
299
    Library.  A suitable mechanism is one that (1) uses at run time a
300
    copy of the library already present on the user's computer system,
301
    rather than copying library functions into the executable, and (2)
302
    will operate properly with a modified version of the library, if
303
    the user installs one, as long as the modified version is
304
    interface-compatible with the version that the work was made with.
305
306
    c) Accompany the work with a written offer, valid for at
307
    least three years, to give the same user the materials
308
    specified in Subsection 6a, above, for a charge no more
309
    than the cost of performing this distribution.
310
311
    d) If distribution of the work is made by offering access to copy
312
    from a designated place, offer equivalent access to copy the above
313
    specified materials from the same place.
314
315
    e) Verify that the user has already received a copy of these
316
    materials or that you have already sent this user a copy.
317
318
  For an executable, the required form of the "work that uses the
319
Library" must include any data and utility programs needed for
320
reproducing the executable from it.  However, as a special exception,
321
the materials to be distributed need not include anything that is
322
normally distributed (in either source or binary form) with the major
323
components (compiler, kernel, and so on) of the operating system on
324
which the executable runs, unless that component itself accompanies
325
the executable.
326
327
  It may happen that this requirement contradicts the license
328
restrictions of other proprietary libraries that do not normally
329
accompany the operating system.  Such a contradiction means you cannot
330
use both them and the Library together in an executable that you
331
distribute.
332
333
  7. You may place library facilities that are a work based on the
334
Library side-by-side in a single library together with other library
335
facilities not covered by this License, and distribute such a combined
336
library, provided that the separate distribution of the work based on
337
the Library and of the other library facilities is otherwise
338
permitted, and provided that you do these two things:
339
340
    a) Accompany the combined library with a copy of the same work
341
    based on the Library, uncombined with any other library
342
    facilities.  This must be distributed under the terms of the
343
    Sections above.
344
345
    b) Give prominent notice with the combined library of the fact
346
    that part of it is a work based on the Library, and explaining
347
    where to find the accompanying uncombined form of the same work.
348
349
  8. You may not copy, modify, sublicense, link with, or distribute
350
the Library except as expressly provided under this License.  Any
351
attempt otherwise to copy, modify, sublicense, link with, or
352
distribute the Library is void, and will automatically terminate your
353
rights under this License.  However, parties who have received copies,
354
or rights, from you under this License will not have their licenses
355
terminated so long as such parties remain in full compliance.
356
357
  9. You are not required to accept this License, since you have not
358
signed it.  However, nothing else grants you permission to modify or
359
distribute the Library or its derivative works.  These actions are
360
prohibited by law if you do not accept this License.  Therefore, by
361
modifying or distributing the Library (or any work based on the
362
Library), you indicate your acceptance of this License to do so, and
363
all its terms and conditions for copying, distributing or modifying
364
the Library or works based on it.
365
366
  10. Each time you redistribute the Library (or any work based on the
367
Library), the recipient automatically receives a license from the
368
original licensor to copy, distribute, link with or modify the Library
369
subject to these terms and conditions.  You may not impose any further
370
restrictions on the recipients' exercise of the rights granted herein.
371
You are not responsible for enforcing compliance by third parties with
372
this License.
373
374
  11. If, as a consequence of a court judgment or allegation of patent
375
infringement or for any other reason (not limited to patent issues),
376
conditions are imposed on you (whether by court order, agreement or
377
otherwise) that contradict the conditions of this License, they do not
378
excuse you from the conditions of this License.  If you cannot
379
distribute so as to satisfy simultaneously your obligations under this
380
License and any other pertinent obligations, then as a consequence you
381
may not distribute the Library at all.  For example, if a patent
382
license would not permit royalty-free redistribution of the Library by
383
all those who receive copies directly or indirectly through you, then
384
the only way you could satisfy both it and this License would be to
385
refrain entirely from distribution of the Library.
386
387
If any portion of this section is held invalid or unenforceable under any
388
particular circumstance, the balance of the section is intended to apply,
389
and the section as a whole is intended to apply in other circumstances.
390
391
It is not the purpose of this section to induce you to infringe any
392
patents or other property right claims or to contest validity of any
393
such claims; this section has the sole purpose of protecting the
394
integrity of the free software distribution system which is
395
implemented by public license practices.  Many people have made
396
generous contributions to the wide range of software distributed
397
through that system in reliance on consistent application of that
398
system; it is up to the author/donor to decide if he or she is willing
399
to distribute software through any other system and a licensee cannot
400
impose that choice.
401
402
This section is intended to make thoroughly clear what is believed to
403
be a consequence of the rest of this License.
404
405
  12. If the distribution and/or use of the Library is restricted in
406
certain countries either by patents or by copyrighted interfaces, the
407
original copyright holder who places the Library under this License may add
408
an explicit geographical distribution limitation excluding those countries,
409
so that distribution is permitted only in or among countries not thus
410
excluded.  In such case, this License incorporates the limitation as if
411
written in the body of this License.
412
413
  13. The Free Software Foundation may publish revised and/or new
414
versions of the Lesser General Public License from time to time.
415
Such new versions will be similar in spirit to the present version,
416
but may differ in detail to address new problems or concerns.
417
418
Each version is given a distinguishing version number.  If the Library
419
specifies a version number of this License which applies to it and
420
"any later version", you have the option of following the terms and
421
conditions either of that version or of any later version published by
422
the Free Software Foundation.  If the Library does not specify a
423
license version number, you may choose any version ever published by
424
the Free Software Foundation.
425
426
  14. If you wish to incorporate parts of the Library into other free
427
programs whose distribution conditions are incompatible with these,
428
write to the author to ask for permission.  For software which is
429
copyrighted by the Free Software Foundation, write to the Free
430
Software Foundation; we sometimes make exceptions for this.  Our
431
decision will be guided by the two goals of preserving the free status
432
of all derivatives of our free software and of promoting the sharing
433
and reuse of software generally.
434
435
			    NO WARRANTY
436
437
  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447
  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456
DAMAGES.
457
458
		     END OF TERMS AND CONDITIONS
459
460
           How to Apply These Terms to Your New Libraries
461
462
  If you develop a new library, and you want it to be of the greatest
463
possible use to the public, we recommend making it free software that
464
everyone can redistribute and change.  You can do so by permitting
465
redistribution under these terms (or, alternatively, under the terms of the
466
ordinary General Public License).
467
468
  To apply these terms, attach the following notices to the library.  It is
469
safest to attach them to the start of each source file to most effectively
470
convey the exclusion of warranty; and each file should have at least the
471
"copyright" line and a pointer to where the full notice is found.
472
473
    <one line to give the library's name and a brief idea of what it does.>
474
    Copyright (C) <year>  <name of author>
475
476
    This library is free software; you can redistribute it and/or
477
    modify it under the terms of the GNU Lesser General Public
478
    License as published by the Free Software Foundation; either
479
    version 2.1 of the License, or (at your option) any later version.
480
481
    This library is distributed in the hope that it will be useful,
482
    but WITHOUT ANY WARRANTY; without even the implied warranty of
483
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
484
    Lesser General Public License for more details.
485
486
    You should have received a copy of the GNU Lesser General Public
487
    License along with this library; if not, write to the Free Software
488
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
489
490
Also add information on how to contact you by electronic and paper mail.
491
492
You should also get your employer (if you work as a programmer) or your
493
school, if any, to sign a "copyright disclaimer" for the library, if
494
necessary.  Here is a sample; alter the names:
495
496
  Yoyodyne, Inc., hereby disclaims all copyright interest in the
497
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499
  <signature of Ty Coon>, 1 April 1990
500
  Ty Coon, President of Vice
501
502
That's all there is to it!
503
504
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/deblock.c (-450 lines)
Lines 1-450 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <stdlib.h>
19
#include <string.h>
20
#include "mimic-private.h"
21
22
static void deblock_horizontal(guchar *blocks, guint stride, guint row_count);
23
static void deblock_vertical(guchar *blocks, guint stride, guint row_count);
24
25
static gboolean deblock_h_consider_entire(guchar *blocks, guint stride);
26
static void deblock_h_do_entire(guchar *blocks, guint stride);
27
static void deblock_h_do_boundaries(guchar *blocks, guint stride);
28
29
static gboolean deblock_v_consider_entire(guchar *blocks, guint stride);
30
static void deblock_v_do_entire(guchar *blocks, guint stride);
31
static void deblock_v_do_boundaries(guchar *blocks, guint stride);
32
33
/*
34
 * _deblock
35
 *
36
 * Internal helper-function used for de-blocking.
37
 */
38
void _deblock(guchar *blocks, guint stride, guint row_count)
39
{
40
    deblock_horizontal(blocks, stride, row_count);
41
    deblock_vertical(blocks, stride, row_count);
42
}
43
44
static void deblock_horizontal(guchar *blocks, guint stride, guint row_count)
45
{
46
    guchar *p1;
47
    gint i, j, n1, n2;
48
49
    if (stride <= 8 || row_count == 0)
50
        return;
51
52
    p1 = blocks + 4;
53
    n1 = ((row_count - 1) >> 2) + 1;
54
    n2 = ((stride - 9) >> 3) + 1;
55
56
    for (i = 0; i < n1; i++) {
57
        guchar *p;
58
59
        p = p1;
60
61
        for (j = 0; j < n2; j++) {
62
63
            if (deblock_h_consider_entire(p - 1, stride) == TRUE) {
64
65
                gint v1, v2, v;
66
67
                v1 = p[0];
68
                v2 = p[7];
69
70
                v = v1 - v2;
71
                if (v <= 0)
72
                    v = v2 - v1;
73
74
                if (v < 20)
75
                    deblock_h_do_entire(p - 1, stride);
76
77
            } else {
78
                deblock_h_do_boundaries(p - 1, stride);
79
            }
80
81
            p += 8;
82
        }
83
84
        p1 += stride * 4;
85
    }
86
}
87
88
static void deblock_vertical(guchar *blocks, guint stride, guint row_count)
89
{
90
    gint i, j, k, n1, n2;
91
    guchar *p1, *p2;
92
93
    if (stride == 0 || row_count <= 8)
94
        return;
95
96
    p1 = blocks + (stride * 3);
97
    p2 = blocks + (stride * 4);
98
99
    n1 = ((row_count - 9) >> 3) + 1;
100
    n2 = ((stride - 1) >> 3) + 1;
101
102
    for (i = 0; i < n1; i++) {
103
        guchar *p3, *p4;
104
105
        p3 = p1;
106
        p4 = p2;
107
108
        for (j = 0; j < n2; j++) {
109
110
            if (deblock_v_consider_entire(p3, stride) == TRUE) {
111
                guchar *p5;
112
                gboolean do_entire;
113
114
                p5 = p3 + (stride * 8);
115
                do_entire = TRUE;
116
117
                for (k = 0; k < 8; k++) {
118
                    gint v1, v2, v;
119
120
                    v1 = p4[k];
121
                    v2 = p5[k];
122
123
                    v = v1 - v2;
124
                    if (v <= 0)
125
                        v = v2 - v1;
126
127
                    if (v > 20) {
128
                        do_entire = FALSE;
129
                        break;
130
                    }
131
                }
132
133
                if (do_entire)
134
                    deblock_v_do_entire(p3, stride);
135
            } else {
136
                deblock_v_do_boundaries(p3, stride);
137
            }
138
139
            p3 += 8;
140
            p4 += 8;
141
        }
142
143
        p1 += stride * 8;
144
        p2 += stride * 8;
145
    }
146
}
147
148
static gboolean deblock_h_consider_entire(guchar *blocks, guint stride)
149
{
150
    guchar *p;
151
    gint i, j, count;
152
153
    count = 0;
154
    p = blocks;
155
156
    for (i = 0; i < 4; i++) {
157
158
        for (j = 1; j <= 7; j++) {
159
            gint v1, v2, v;
160
161
            v1 = p[j];
162
            v2 = p[j+1];
163
164
            v = v1 - v2;
165
            if (v <= 0)
166
                v = v2 - v1;
167
168
            if (v <= 1)
169
                count--;
170
        }
171
172
        p += stride;
173
    }
174
175
    return (count <= -20);
176
}
177
178
static void deblock_h_do_entire(guchar *blocks, guint stride)
179
{
180
    guchar buf[8], *p;
181
    gint i;
182
183
    p = blocks;
184
185
    for (i = 0; i < 4; i++) {
186
        gint v, low, high;
187
188
        v = p[0] - p[1];
189
        if (v <= 0)
190
            v = p[1] - p[0];
191
192
        if (v < 10)
193
            low = p[0];
194
        else
195
            low = p[1];
196
197
        v = p[8] - p[9];
198
        if (v <= 0)
199
            v = p[9] - p[8];
200
201
        if (v >= 10)
202
            high = p[8];
203
        else
204
            high = p[9];
205
206
        v = (low * 3) + p[1] + p[2] + p[3] + p[4] + 4;
207
        buf[0] = (((p[1] + v) << 1) - p[4] + p[5]) >> 4;
208
209
        v += p[5] - low;
210
        buf[1] = (((p[2] + v) << 1) - p[5] + p[6]) >> 4;
211
212
        v += p[6] - low;
213
        buf[2] = (((p[3] + v) << 1) - p[6] + p[7]) >> 4;
214
215
        v += p[7] - low;
216
        buf[3] = (((p[4] + v) << 1) - p[1] - p[7] + p[8] + low) >> 4;
217
218
        v += p[8] - p[1];
219
        buf[4] = (((p[5] + v) << 1) + p[1] - p[2] - p[8] + high) >> 4;
220
221
        v += high - p[2];
222
        buf[5] = (((p[6] + v) << 1) + p[2] - p[3]) >> 4;
223
224
        v += high - p[3];
225
        buf[6] = (((p[7] + v) << 1) + p[3] - p[4]) >> 4;
226
227
        v += high;
228
        buf[7] = (((p[8] + v) << 1) - p[4] - p[5]) >> 4;
229
230
        memcpy(p + 1, buf, 8);
231
232
        p += stride;
233
    }
234
}
235
236
static void deblock_h_do_boundaries(guchar *blocks, guint stride)
237
{
238
    guchar *p;
239
    gint i;
240
241
    p = blocks;
242
243
    for (i = 0; i < 4; i++) {
244
        gint v, v1, v2, v3;
245
246
        v = p[4] - p[5];
247
248
        if ((v / 2) != 0) {
249
250
            v1 = ((p[3] - p[6]) * 2) - (v * 5);
251
252
            if (abs(v1) < 80) {
253
254
                v2 = ((p[3] - p[2]) * 5) + ((p[1] - p[4]) * 2);
255
                v3 = (p[5] * 2) + (p[7] * 5) - (p[8] * 7);
256
257
                v = abs(v1) - MIN(abs(v2), abs(v3));
258
259
                if (v > 0) {
260
261
                    v = ((v * 5) + 32) >> 6;
262
                    if (v > 0) {
263
264
                        v2 = (p[4] - p[5]) / 2;
265
                        v3 = (((v1 < 0) * 2) - 1) * v;
266
267
                        if (v2 > 0)
268
                            v = MIN(v2, ((v3 < 0) - 1) & v3);
269
                        else
270
                            v = MAX(v2, ((v3 > 0) - 1) & v3);
271
272
                        p[4] -= v;
273
                        p[5] += v;
274
                    }
275
                }
276
            }
277
        }
278
279
        p += stride;
280
    }
281
}
282
283
static gboolean deblock_v_consider_entire(guchar *blocks, guint stride)
284
{
285
    gint count, i, j;
286
    guchar *p1, *p2;
287
288
    count = 0;
289
290
    p1 = blocks + stride;
291
    p2 = blocks + (stride * 2);
292
293
    for (i = 0; i < 7; i++) {
294
295
        for (j = 0; j < 8; j++) {
296
            gint v1, v2, v;
297
298
            v1 = p1[j];
299
            v2 = p2[j];
300
301
            v = v1 - v2;
302
            if (v <= 0)
303
                v = v2 - v1;
304
305
            if (v <= 1)
306
                count++;
307
        }
308
309
        p1 += stride;
310
        p2 += stride;
311
    }
312
313
    return (count > 40);
314
}
315
316
static void deblock_v_do_entire(guchar *blocks, guint stride)
317
{
318
    gint offset0, offset1, offset2, offset3;
319
    gint offset4, offset5, offset6, offset7;
320
    gint offset8, i;
321
    guchar *p, buf[8];
322
323
    offset0 = stride - (stride * 6);
324
    offset1 = (stride * 2) - (stride * 6);
325
    offset2 = (stride * 3) - (stride * 6);
326
    offset3 = (stride * 4) - (stride * 6);
327
    offset4 = (stride * 5) - (stride * 6);
328
    offset5 = 0;
329
    offset6 = (stride * 7) - (stride * 6);
330
    offset7 = (stride * 8) - (stride * 6);
331
    offset8 = (stride * 9) - (stride * 6);
332
333
    p = blocks + (stride * 6);
334
335
    for (i = 0; i < 8; i++) {
336
        gint v, low, high;
337
338
        v = blocks[i] - p[offset0];
339
        if (v <= 0)
340
            v = p[offset0] - blocks[i];
341
342
        if (v < 10)
343
            low = blocks[i];
344
        else
345
            low = p[offset0];
346
347
        v = p[offset7] - p[offset8];
348
        if (v <= 0)
349
            v = p[offset8] - p[offset7];
350
351
        if (v < 10)
352
            high = p[offset8];
353
        else
354
            high = p[offset7];
355
356
        v = p[offset0] + (low * 3) + p[offset1] + p[offset2] + p[offset3] + 4;
357
358
        buf[0] = (((p[offset0] + v) << 1) - p[offset3] + p[offset4]) >> 4;
359
360
        v += p[offset4] - low;
361
362
        buf[1] = (((p[offset1] + v) << 1) - p[offset4] + p[0]) >> 4;
363
364
        v += p[0] - low;
365
366
        buf[2] = (((p[offset2] + v) << 1) - p[0] + p[offset6]) >> 4;
367
368
        v += p[offset6] - low;
369
370
        buf[3] = (((p[offset3] + v) << 1) - p[offset0] - p[offset6] + p[offset7] + low) >> 4;
371
372
        v += p[offset7] - p[offset0];
373
374
        buf[4] = (((p[offset4] + v) << 1) - p[offset7] - p[offset1] + p[offset0] + high) >> 4;
375
376
        v += high - p[offset1];
377
378
        buf[5] = (((p[0] + v) << 1) - p[offset2] + p[offset1]) >> 4;
379
380
        v += high - p[offset2];
381
382
        buf[6] = (((p[offset6] + v) << 1) - p[offset3] + p[offset2]) >> 4;
383
384
        v += high;
385
386
        buf[7] = (((p[offset7] + v) << 1) - p[offset4] - p[offset3]) >> 4;
387
388
        p[offset0] = buf[0];
389
        p[offset1] = buf[1];
390
        p[offset2] = buf[2];
391
        p[offset3] = buf[3];
392
        p[offset4] = buf[4];
393
        p[offset5] = buf[5];
394
        p[offset6] = buf[6];
395
        p[offset7] = buf[7];
396
397
        p++;
398
    }
399
}
400
401
static void deblock_v_do_boundaries(guchar *blocks, guint stride)
402
{
403
    guchar *p;
404
    gint offset0, offset1, offset2, offset3;
405
    gint offset4, offset5, offset6, offset7;
406
    gint i;
407
408
    p = blocks + (stride * 3);
409
410
    offset0 = stride - (stride * 3);
411
    offset1 = (stride * 2) - (stride * 3);
412
    offset2 = 0;
413
    offset3 = (stride * 4) - (stride * 3);
414
    offset4 = (stride * 5) - (stride * 3);
415
    offset5 = (stride * 6) - (stride * 3);
416
    offset6 = (stride * 7) - (stride * 3);
417
    offset7 = (stride * 8) - (stride * 3);
418
419
    for (i = 0; i < 8; i++) {
420
        gint v1, v2, v3, v;
421
422
        v1 = ((p[offset4] - p[offset3]) * 5) + ((p[offset2] - p[offset5]) * 2);
423
424
        if (abs(v1) < 80) {
425
426
            v2 = ((p[offset2] - p[offset1]) * 5) + ((p[offset0] - p[offset3]) * 2);
427
            v3 = ((p[offset6] - p[offset5]) * 5) + ((p[offset4] - p[offset7]) * 2);
428
429
            v = abs(v1) - MIN(abs(v2), abs(v3));
430
            if (v < 0)
431
                v = 0;
432
433
            v2 = (p[offset3] - p[offset4]) / 2;
434
            v3 = (((v * 5) + 32) >> 6) * (((v1 < 0) * 2) - 1);
435
436
            if (v2 > 0)
437
                v = MIN(v2, ((v3 < 0) - 1) & v3);
438
            else
439
                v = MAX(v2, ((v3 > 0) - 1) & v3);
440
        } else {
441
            v = 0;
442
        }
443
444
        p[offset3] -= v;
445
        p[offset4] += v;
446
447
        p++;
448
    }
449
}
450
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/decode.c (-311 lines)
Lines 1-311 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <string.h>
19
#include "mimic-private.h"
20
21
22
static gboolean decode(MimCtx *ctx, gboolean is_pframe);
23
24
/**
25
 * Decode a MIMIC-encoded frame into RGB data.
26
 *
27
 * @param ctx the mimic context
28
 * @param input_buffer buffer containing the MIMIC-encoded frame to decode
29
 * @param output_buffer buffer that will receive the decoded frame in RGB 24-bpp packed pixel top-down format
30
 *                      (use #mimic_get_property to determine the required buffer size, as well as frame width and height)
31
 * @returns #TRUE on success
32
 */
33
gboolean mimic_decode_frame(MimCtx *ctx,
34
                            const guchar *input_buffer,
35
                            guchar *output_buffer)
36
{
37
    gboolean result, is_pframe;
38
    guchar *input_y, *input_cr, *input_cb;
39
    gint width, height;
40
    
41
    /*
42
     * Some sanity checks.
43
     */
44
    if (ctx == NULL || input_buffer == NULL || output_buffer == NULL)
45
    {
46
        return FALSE;
47
    }
48
49
    if (!ctx->decoder_initialized)
50
    {
51
        return FALSE;
52
    }
53
    
54
    /*
55
     * Get frame dimensions.
56
     */
57
    width  = GUINT16_FROM_LE(*((guint16 *) (input_buffer + 4)));
58
    height = GUINT16_FROM_LE(*((guint16 *) (input_buffer + 6)));
59
60
    /*
61
     * Resolution changing is not supported.
62
     */
63
    if (width  != ctx->frame_width ||
64
        height != ctx->frame_height)
65
    {
66
        return FALSE;
67
    }
68
    
69
    /*
70
     * Increment frame counter.
71
     */
72
    ctx->frame_num++;
73
74
    /*
75
     * Initialize state.
76
     */
77
    ctx->quality = GUINT16_FROM_LE(*((guint16 *) (input_buffer + 2)));
78
    is_pframe = GUINT32_FROM_LE(*((guint32 *) (input_buffer + 12)));
79
    ctx->num_coeffs = input_buffer[16];
80
    
81
    ctx->data_buffer = (gchar *) (input_buffer + 20);
82
    ctx->data_index = 0;
83
    ctx->cur_chunk_len = 16;
84
    ctx->read_odd = FALSE;
85
    
86
    /*
87
     * Decode frame.
88
     */
89
    if (!(is_pframe && ctx->prev_frame_buf == NULL))
90
        result = decode(ctx, is_pframe);
91
    else
92
    {
93
        result = FALSE;
94
    }
95
96
    /*
97
     * Perform YUV 420 to RGB conversion.
98
     */
99
    input_y = ctx->cur_frame_buf;
100
    input_cr = ctx->cur_frame_buf + ctx->y_size;
101
    input_cb = ctx->cur_frame_buf + ctx->y_size + ctx->crcb_size;
102
103
    _yuv_to_rgb(input_y,
104
                input_cb,
105
                input_cr,
106
                output_buffer,
107
                ctx->frame_width,
108
                ctx->frame_height);
109
110
    return result;
111
}
112
113
/*
114
 * decode_main
115
 *
116
 * Main decoding loop.
117
 */
118
static gboolean decode(MimCtx *ctx, gboolean is_pframe)
119
{
120
    gint y, x, i, j, chrom_ch, *bptr, base_offset, offset;
121
    gint dct_block[64];
122
    guchar *src, *dst, *p;
123
    guint32 bit;
124
    
125
    /*
126
     * Clear Cr and Cb planes.
127
     */
128
    p = ctx->cur_frame_buf + ctx->y_size;
129
    memset(p, 128, 2 * ctx->crcb_size);
130
131
    /*
132
     * Decode Y plane.
133
     */
134
    for (y = 0; y < ctx->num_vblocks_y; y++) {
135
136
        base_offset = ctx->y_stride * 8 * y;
137
138
        src = ctx->prev_frame_buf + base_offset;
139
        dst = ctx->cur_frame_buf  + base_offset;
140
141
        for (x = 0; x < ctx->num_hblocks_y; x++) {
142
143
            /* Check for a change condition in the current block. */
144
145
            if (is_pframe)
146
                bit = _read_bits(ctx, 1);
147
            else
148
                bit = 0;
149
150
            if (bit == 0) {
151
152
                /* Yes: Is the new content the same as it was in one of
153
                 * the 15 last frames preceding the previous? */
154
                
155
                if (is_pframe)
156
                    bit = _read_bits(ctx, 1);
157
158
                if (bit == 0) {
159
160
                    /* No: decode it. */
161
                    
162
                    if (_vlc_decode_block(ctx, dct_block, ctx->num_coeffs) == FALSE) {
163
164
                        return FALSE;
165
                    }
166
167
                    _idct_dequant_block(ctx, dct_block, 0);
168
169
                    bptr = dct_block;
170
                    for (i = 0; i < 8; i++) {
171
                        offset = ctx->y_stride * i;
172
173
                        for (j = 0; j < 8; j++) {
174
                            guint v;
175
                            
176
                            if (bptr[j] <= 255)
177
                                v = (bptr[j] >= 0) ? bptr[j] : 0;
178
                            else
179
                                v = 255;
180
                            
181
                            *(dst + offset + j) = v;
182
                        }
183
184
                        bptr += 8;
185
                    }
186
                } else {
187
                    guint32 backref;
188
                    
189
                    /* Yes: read the backreference (4 bits) and copy. */
190
191
                    backref = _read_bits(ctx, 4);
192
193
                    p = ctx->buf_ptrs[(ctx->ptr_index + backref) % 16];
194
                    p += base_offset + (x * 8);
195
196
                    for (i = 0; i < 8; i++) {
197
                        offset = ctx->y_stride * i;
198
199
                        memcpy(dst + offset, p + offset, 8);
200
                    }
201
                }
202
            } else {
203
                
204
                /* No change no worries: just copy from the previous frame. */
205
206
                for (i = 0; i < 8; i++) {
207
                    offset = ctx->y_stride * i;
208
209
                    memcpy(dst + offset, src + offset, 8);
210
                }
211
            }
212
213
            src += 8;
214
            dst += 8;
215
        }
216
    }
217
218
    /*
219
     * Decode Cr and Cb planes.
220
     */
221
    for (chrom_ch = 0; chrom_ch < 2; chrom_ch++) {
222
223
        base_offset = ctx->y_size + (ctx->crcb_size * chrom_ch);
224
225
        for (y = 0; y < ctx->num_vblocks_cbcr; y++) {
226
            guint num_rows = 8;
227
            
228
            /* The last row of blocks in chrominance for 160x120 resolution
229
             * is half the normal height and must be accounted for. */
230
            if (y + 1 == ctx->num_vblocks_cbcr && ctx->frame_height % 16 != 0)
231
                num_rows = 4;
232
233
            offset = base_offset + (ctx->crcb_stride * 8 * y);
234
235
            src = ctx->prev_frame_buf + offset;
236
            dst = ctx->cur_frame_buf  + offset;
237
            
238
            for (x = 0; x < ctx->num_hblocks_cbcr; x++) {
239
                
240
                /* Check for a change condition in the current block. */
241
                
242
                if (is_pframe)
243
                    bit = _read_bits(ctx, 1);
244
                else
245
                    bit = 1;
246
247
                if (bit == 1) {
248
                    
249
                    /* Yes: decode it. */
250
251
                    if (_vlc_decode_block(ctx, dct_block, ctx->num_coeffs) == FALSE) {
252
253
                         /* Corrupted frame: clear Cr and Cb planes and return. */
254
                        p = ctx->cur_frame_buf + ctx->y_size;
255
                        memset(p, 128, ctx->crcb_size * 2);
256
257
                        return FALSE;
258
                    }
259
260
                    _idct_dequant_block(ctx, dct_block, 1);
261
262
                    for (i = 0; i < num_rows; i++) {
263
                        p = dst + (ctx->crcb_stride * i);
264
265
                        for (j = 0; j < 8; j++)
266
                            p[j] = dct_block[(i * 8) + j];
267
                    }
268
269
                } else {
270
271
                    /* No change no worries: just copy from the previous frame. */
272
                    
273
                    for (i = 0; i < num_rows; i++) {
274
                        offset = ctx->crcb_stride * i;
275
                        
276
                        memcpy(dst + offset, src + offset, 8);
277
                    }
278
                }
279
280
                src += 8;
281
                dst += 8;
282
            }
283
        }
284
    }
285
286
    /*
287
     * Make a copy of the current frame and store in
288
     * the circular pointer list of 16 entries.
289
     */
290
    ctx->prev_frame_buf = ctx->buf_ptrs[ctx->ptr_index];
291
    memcpy(ctx->prev_frame_buf, ctx->cur_frame_buf,
292
           ctx->y_size + (ctx->crcb_size * 2));
293
    
294
    if (--ctx->ptr_index < 0)
295
        ctx->ptr_index = 15;
296
    
297
    /*
298
     * Perform deblocking on all planes.
299
     */
300
    _deblock(ctx->cur_frame_buf,
301
             ctx->y_stride, ctx->y_row_count);
302
    
303
    _deblock(ctx->cur_frame_buf + ctx->y_size,
304
             ctx->crcb_stride, ctx->crcb_row_count);
305
    
306
    _deblock(ctx->cur_frame_buf + ctx->y_size + ctx->crcb_size,
307
             ctx->crcb_stride, ctx->crcb_row_count);
308
309
    return TRUE;
310
}
311
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/encode.c (-419 lines)
Lines 1-419 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <stdlib.h>
19
#include <string.h>
20
#include <math.h>
21
#include "mimic-private.h"
22
23
#define LUMINANCE_THRESHOLD   32.0f
24
#define CHROMINANCE_THRESHOLD 36.0f
25
26
static void encode_main(MimCtx *ctx, guchar *out_buf, gboolean is_pframe);
27
28
/**
29
 * Encode a MIMIC-encoded frame from RGB data.
30
 *
31
 * @param ctx the mimic context
32
 * @param input_buffer buffer containing pixeldata in RGB 24-bpp packed pixel top-down format
33
 * @param output_buffer buffer that will receive the MIMIC-encoded frame
34
 *                      (use #mimic_get_property to determine the required buffer size)
35
 * @param output_length pointer to an integer that receives the length of the encoded data
36
 *                      written to output_buffer
37
 * @param make_keyframe whether the encoder should make this frame a keyframe
38
 * @returns #TRUE on success
39
 */
40
gboolean mimic_encode_frame(MimCtx *ctx,
41
                            const guchar *input_buffer,
42
                            guchar *output_buffer,
43
                            gint *output_length,
44
                            gboolean make_keyframe)
45
{
46
    guchar *output_y, *output_cb, *output_cr;
47
    
48
    /*
49
     * Some sanity checks.
50
     */
51
    if (ctx == NULL || input_buffer == NULL ||
52
        output_buffer == NULL || output_length == NULL)
53
    {
54
        return FALSE;
55
    }
56
57
    if (!ctx->encoder_initialized)
58
        return FALSE;
59
    
60
    /*
61
     * Initialize state.
62
     */
63
    ctx->chunk_ptr = (guint32 *) (output_buffer + 20);
64
    ctx->cur_chunk = 0;
65
    ctx->cur_chunk_len = 0;
66
    
67
    if (ctx->frame_num == 0)
68
        make_keyframe = TRUE;
69
    
70
    /*
71
     * Write header.
72
     */
73
    memset(output_buffer, 0, 20);
74
    *((guint16 *) (output_buffer +  0)) = GUINT16_TO_LE(256);
75
    *((guint16 *) (output_buffer +  2)) = GUINT16_TO_LE(ctx->quality);
76
    *((guint16 *) (output_buffer +  4)) = GUINT16_TO_LE(ctx->frame_width);
77
    *((guint16 *) (output_buffer +  6)) = GUINT16_TO_LE(ctx->frame_height);
78
    *((guint32 *) (output_buffer + 12)) = GUINT32_TO_LE((make_keyframe == 0));
79
    *(output_buffer + 16) = ctx->num_coeffs;
80
    *(output_buffer + 17) = 0;
81
    
82
    /*
83
     * Perform RGB to YUV 420 conversion.
84
     */
85
    output_y  = ctx->cur_frame_buf;
86
    output_cr = ctx->cur_frame_buf + ctx->y_size;
87
    output_cb = ctx->cur_frame_buf + ctx->y_size + ctx->crcb_size;
88
89
    _rgb_to_yuv(input_buffer,
90
                output_y,
91
                output_cb,
92
                output_cr,
93
                ctx->frame_width,
94
                ctx->frame_height);
95
96
    /*
97
     * Encode frame.
98
     */
99
    encode_main(ctx, output_buffer, (make_keyframe == FALSE));
100
101
    /*
102
     * Write out any pending bits to stream by zero-padding with 32 bits.
103
     */
104
    _write_bits(ctx, 0, 32);
105
106
    /*
107
     * Calculate bytes written.
108
     */
109
    *output_length = (guchar *) ctx->chunk_ptr - output_buffer;
110
    
111
    /*
112
     * Increment frame counter.
113
     */
114
    ctx->frame_num++;
115
    
116
    return TRUE;
117
}
118
119
static gdouble compare_blocks(const guchar *p1,
120
                              const guchar *p2,
121
                              gint stride,
122
                              gint row_count,
123
                              gboolean is_chrom);
124
125
/*
126
 * encode_main
127
 *
128
 * Main encoding loop.
129
 */
130
static void encode_main(MimCtx *ctx, guchar *out_buf, gboolean is_pframe)
131
{
132
    gint x, y, i, offset, chrom_ch;
133
    gint dct_block[64];
134
    guchar *src, *dst, *p1, *p2;
135
    gdouble match;
136
    gboolean encoded;
137
138
    /*
139
     * Round down small differences in luminance channel.
140
     */
141
    if (is_pframe) {
142
        
143
        p1 = ctx->cur_frame_buf;
144
        p2 = ctx->prev_frame_buf;
145
146
        for (i = 0; i < ctx->y_size; i++) {
147
148
            if (abs(p2[0] - p1[0]) < 7)
149
                p1[0] = p2[0];
150
151
            p1++;
152
            p2++;
153
        }
154
    }
155
156
    /*
157
     * Encode Y plane.
158
     */
159
    for (y = 0; y < ctx->num_vblocks_y; y++) {
160
161
        for (x = 0; x < ctx->num_hblocks_y; x++) {
162
163
            /* Calculate final offset into buffer. */
164
            offset = (ctx->y_stride * 8 * y) + (x * 8);
165
166
            src = NULL;
167
            encoded = FALSE;
168
169
            if (is_pframe) {
170
171
                /* Is the current block similar enough to what it was in the previous frame? */
172
173
                match = compare_blocks(ctx->cur_frame_buf + offset,
174
                                       ctx->prev_frame_buf + offset,
175
                                       ctx->y_stride, 8,
176
                                       FALSE);
177
178
                if (match > LUMINANCE_THRESHOLD) {
179
180
                    /* Yes: write out '1' to indicate a no-change condition. */
181
                    
182
                    _write_bits(ctx, 1, 1);
183
184
                    src = ctx->prev_frame_buf + offset;
185
                    encoded = TRUE;
186
187
                } else {
188
189
                    /* No: Is the current block similar enough to what it was in one
190
                     *     of the (up to) 15 last frames preceding the previous? */
191
192
                    gint best_index = 0;
193
                    gdouble best_match = 0.0;
194
195
                    gint num_backrefs = ctx->frame_num - 1;
196
                    if (num_backrefs > 15)
197
                        num_backrefs = 15;
198
199
                    for (i = 1; i <= num_backrefs; i++) {
200
                        
201
                        match = compare_blocks(ctx->buf_ptrs[(ctx->ptr_index + i) % 16] + offset,
202
                                               ctx->cur_frame_buf + offset,
203
                                               ctx->y_stride, 8,
204
                                               FALSE);
205
206
                        if (match > LUMINANCE_THRESHOLD && match > best_match) {
207
                            best_index = i;
208
                            best_match = match;
209
                        }
210
211
                    }
212
213
                    if (best_index != 0) {
214
215
                        /* Yes: write out '01' to indicate a "change but like previous"-condition,
216
                         * followed by 4 bits containing the back-reference. */
217
                        _write_bits(ctx, 0, 1);
218
                        _write_bits(ctx, 1, 1);
219
                        _write_bits(ctx, best_index, 4);
220
221
                        src = ctx->buf_ptrs[(ctx->ptr_index + best_index) % 16] + offset;
222
                        encoded = TRUE;
223
224
                    }
225
                }
226
            }
227
228
            if (!encoded) {
229
230
                /* Keyframe or in any case no? ;-) Well, encode it then. */
231
232
                if (is_pframe) {
233
                    _write_bits(ctx, 0, 1);
234
                    _write_bits(ctx, 0, 1);
235
                }
236
237
                _fdct_quant_block(ctx,
238
                                  dct_block,
239
                                  ctx->cur_frame_buf + offset,
240
                                  ctx->y_stride,
241
                                  FALSE,
242
                                  ctx->num_coeffs);
243
244
                _vlc_encode_block(ctx,
245
                                  dct_block,
246
                                  ctx->num_coeffs);
247
248
            }
249
250
            /* And if there was some kind of no-change condition,
251
             * we want to copy the previous block. */
252
            if (src != NULL) {
253
                
254
                dst = ctx->cur_frame_buf + offset;
255
                for (i = 0; i < 8; i++) {
256
257
                    memcpy(dst, src, 8);
258
259
                    src += ctx->y_stride;
260
                    dst += ctx->y_stride;
261
                }
262
                
263
            }
264
265
        }
266
        
267
    }
268
269
    /*
270
     * Encode Cr and Cb planes.
271
     */
272
    for (chrom_ch = 0; chrom_ch < 2; chrom_ch++) {
273
274
        /* Calculate base offset into buffer. */
275
        gint base_offset = ctx->y_size + (ctx->crcb_size * chrom_ch);
276
277
        for (y = 0; y < ctx->num_vblocks_cbcr; y++) {
278
            guchar tmp_block[64];
279
            guint num_rows = 8;
280
            
281
            /* The last row of blocks in chrominance for 160x120 resolution
282
             * is half the normal height and must be accounted for. */
283
            if (y + 1 == ctx->num_vblocks_cbcr && ctx->frame_height % 16 != 0)
284
                num_rows = 4;
285
            
286
            for (x = 0; x < ctx->num_hblocks_cbcr; x++) {
287
288
                /* Calculate final offset into buffer. */
289
                offset = base_offset + (ctx->crcb_stride * 8 * y) + (x * 8);
290
291
                src = NULL;
292
                encoded = FALSE;
293
294
                if (is_pframe) {
295
                    
296
                    /* Is the current block similar enough to what it was in the previous frame? */
297
298
                    match = compare_blocks(ctx->prev_frame_buf + offset,
299
                                           ctx->cur_frame_buf + offset,
300
                                           ctx->crcb_stride, num_rows,
301
                                           TRUE);
302
303
                    if (match > CHROMINANCE_THRESHOLD) {
304
305
                        /* Yes: write out '0' to indicate a no-change condition. */
306
                        
307
                        _write_bits(ctx, 0, 1);
308
                        
309
                        encoded = TRUE;
310
311
                        src = ctx->prev_frame_buf + offset;
312
                        dst = ctx->cur_frame_buf + offset;
313
                        for (i = 0; i < num_rows; i++) {
314
315
                            memcpy(dst, src, 8);
316
317
                            src += ctx->crcb_stride;
318
                            dst += ctx->crcb_stride;
319
                        }
320
                    }
321
                
322
                }
323
324
                if (!encoded) {
325
326
                    /* Keyframe or just not similar enough? ;-) Well, encode it then. */
327
                    
328
                    if (is_pframe)
329
                        _write_bits(ctx, 1, 1);
330
                    
331
                    /* Use a temporary array to handle cases where the
332
                     * current block is not of normal height (see above). */
333
                    src = ctx->cur_frame_buf + offset;
334
                    dst = tmp_block;
335
                    for (i = 0; i < 8; i++) {
336
                        
337
                        memcpy(dst, src, 8);
338
339
                        if (i < (num_rows - 1))
340
                            src += ctx->crcb_stride;
341
                        dst += 8;
342
                    }
343
                    
344
                    _fdct_quant_block(ctx,
345
                                      dct_block,
346
                                      tmp_block,
347
                                      8,
348
                                      TRUE,
349
                                      ctx->num_coeffs);
350
351
                    _vlc_encode_block(ctx,
352
                                      dct_block,
353
                                      ctx->num_coeffs);
354
                    
355
                }
356
357
            }
358
            
359
        }
360
        
361
    }
362
    
363
    /*
364
     * Make a copy of the current frame and store in
365
     * the circular pointer list of 16 entries.
366
     */
367
    ctx->prev_frame_buf = ctx->buf_ptrs[ctx->ptr_index];
368
    memcpy(ctx->prev_frame_buf, ctx->cur_frame_buf,
369
           ctx->y_size + (ctx->crcb_size * 2));
370
371
    if (--ctx->ptr_index < 0)
372
        ctx->ptr_index = 15;
373
}
374
375
/*
376
 * compare_blocks
377
 *
378
 * Helper-function used to compare two blocks and
379
 * determine how similar they are.
380
 */
381
static gdouble compare_blocks(const guchar *p1,
382
                              const guchar *p2,
383
                              gint stride,
384
                              gint row_count,
385
                              gboolean is_chrom)
386
{
387
	gint i, j, sum;
388
    gdouble d;
389
390
	sum = 0;
391
392
	for (i = 0; i < row_count; i++) {
393
394
		for (j = 0; j < 8; j++) {
395
396
			gint d = p2[j] - p1[j];
397
398
			sum += d * d;
399
		}
400
401
		p1 += stride;
402
		p2 += stride;
403
	}
404
405
    if (is_chrom) {
406
        if (row_count == 8)
407
            d = sum * 0.015625;
408
        else
409
            d = sum * 0.03125;
410
    } else {
411
        d = sum / 64;
412
    }
413
    
414
    if (d == 0.0f)
415
        return 100.0f;
416
    else
417
        return (10.0f * log(65025.0f / d)) / G_LN10;
418
}
419
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/fdct_quant.c (-181 lines)
Lines 1-181 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include "mimic-private.h"
19
20
extern guchar _col_zag[64];
21
22
void _fdct_quant_block(MimCtx *ctx, gint *block, const guchar *src,
23
                       gint stride, gboolean is_chrom, gint num_coeffs)
24
{
25
	gint sum1, sum2, sum3, sum4;
26
	gint diff1, diff2, diff3, diff4;
27
	gint ex1, ex2, ex3, ex4, ex5;
28
	gint i, j;
29
	const guchar *p1;
30
	gint *iptr;
31
32
    /*
33
     * Forward DCT, first pass (horizontal).
34
     */
35
    p1 = src;
36
    iptr = block;
37
38
	for (i = 0; i < 8; i++) {
39
		sum1 = p1[0] + p1[7];
40
		sum2 = p1[1] + p1[6];
41
		sum3 = p1[2] + p1[5];
42
		sum4 = p1[3] + p1[4];
43
44
		diff1 = p1[0] - p1[7];
45
		diff2 = p1[1] - p1[6];
46
		diff3 = p1[2] - p1[5];
47
		diff4 = p1[3] - p1[4];
48
49
		ex1 = ((diff1 + diff4) *  851) - (diff1 *  282);
50
		ex2 = ((diff2 + diff3) * 1004) - (diff2 *  804);
51
		ex3 = ((diff2 + diff3) * 1004) - (diff3 * 1204);
52
		ex4 = ((diff1 + diff4) *  851) - (diff4 * 1420);
53
54
		iptr[0] = sum1 + sum2 + sum3 + sum4;
55
		iptr[2] = (((sum1 - sum4) * 1337) + ((sum2 - sum3) * 554)) >> 10;
56
		iptr[4] = sum1 - sum2 - sum3 + sum4;
57
58
		iptr[1] = (ex1 + ex2 + ex3 + ex4) >> 10;
59
		iptr[3] = ((ex4 - ex2) * 181) >> 17;
60
		iptr[5] = ((ex1 - ex3) * 181) >> 17;
61
62
		p1 += stride;
63
		iptr += 8;
64
	}
65
66
	p1 = src;
67
    iptr = block;
68
69
    /*
70
     * Forward DCT, first pass (vertical).
71
     * 
72
     * This is only known to be correct for i == 0, though it seems to be ...
73
     */
74
    for (i = 0; i < 6; i++) {
75
        sum1 = iptr[ 0 + i] + iptr[56 + i];
76
        sum2 = iptr[ 8 + i] + iptr[48 + i];
77
        sum3 = iptr[16 + i] + iptr[40 + i];
78
        sum4 = iptr[24 + i] + iptr[32 + i];
79
80
        diff1 = iptr[ 0 + i] - iptr[56 + i];
81
        diff2 = iptr[ 8 + i] - iptr[48 + i];
82
        diff3 = iptr[16 + i] - iptr[40 + i];
83
        diff4 = iptr[24 + i] - iptr[32 + i];
84
85
        ex1 = ((diff1 + diff4) *  851) - (diff1 *  282);
86
        ex2 = ((diff2 + diff3) * 1004) - (diff2 *  804);
87
        ex3 = ((diff2 + diff3) * 1004) - (diff3 * 1204);
88
        ex4 = ((diff1 + diff4) *  851) - (diff4 * 1420);
89
90
        ex5 = (sum1 + sum2 - sum3 - sum4) * 554;
91
92
        for (j = 0; j < 7 - i; j++) {
93
            switch (j) {
94
95
                case 0:
96
                    iptr[ 0 + i] = (16 + sum1 + sum2 + sum3 + sum4) >> 5;
97
                    break;
98
99
                case 1:
100
                    iptr[ 8 + i] = (16384 + ex1 + ex2 + ex3 + ex4) >> 15;
101
                    break;
102
103
                case 2:
104
                    iptr[16 + i] = (16384 + ((sum1 - sum4) * 783) + ex5) >> 15;
105
                    break;
106
107
                case 3:
108
                    iptr[24 + i] = (8192 + (((ex4 - ex2) >> 8) * 181)) >> 14;
109
                    break;
110
111
                case 4:
112
                    iptr[32 + i] = (16 + sum1 - sum2 - sum3 + sum4) >>  5;
113
                    break;
114
115
                case 5:
116
                    iptr[40 + i] = (8192 + (((ex1 - ex3) >> 8) * 181)) >> 14;
117
                    break;
118
119
                case 6:
120
                    iptr[48 + i] = (16384 - ((sum2 - sum3) * 1891) + ex5) >> 15;
121
                    break;
122
            }
123
        }
124
    }
125
126
    /*
127
     * Quantize.
128
     */
129
	block[0] /= 2;
130
	block[8] /= 4;
131
	block[1] /= 4;
132
	block[6] = 0;
133
134
	if (num_coeffs > 3) {
135
136
        gdouble s = (10000 - ctx->quality) * 10.0 * (gfloat) 9.9999997e-5;
137
138
        if (s > 10.0)
139
            s = 10.0;
140
        else if (is_chrom != 0 && s < 1.0)
141
            s = 1.0;
142
        else if (s < 2.0)
143
            s = 2.0;
144
145
		s = 1.0 / s;
146
147
		for (i = 3; i < num_coeffs; i++) {
148
149
            gdouble coeff, r;
150
151
			coeff = block[_col_zag[i]] * s;
152
            r = coeff - (gint) coeff;
153
154
			if (r >= 0.6)
155
				block[_col_zag[i]] = (gint) (coeff + 1.0);
156
			else if (r <= -0.6)
157
				block[_col_zag[i]] = (gint) (coeff - 1.0);
158
			else
159
				block[_col_zag[i]] = (gint) coeff;
160
161
			if (block[_col_zag[i]] > 120)
162
				block[_col_zag[i]] = 120;
163
			else if (block[_col_zag[i]] < -120)
164
				block[_col_zag[i]] = -120;
165
		}
166
	}
167
168
	if (block[8] > 120)
169
		block[8] = 120;
170
	else if (block[8] < -120)
171
		block[8] = -120;
172
173
	if (block[1] > 120)
174
		block[1] = 120;
175
	else if (block[1] < -120)
176
		block[1] = -120;
177
178
	for (i = num_coeffs; i < 64; i++)
179
		block[_col_zag[i]] = 0;
180
}
181
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/idct_dequant.c (-134 lines)
Lines 1-134 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include "mimic-private.h"
19
20
void _idct_dequant_block(MimCtx *ctx, gint *block, gboolean is_chrom)
21
{
22
    gdouble f;
23
    gint i, *p;
24
25
    /*
26
     * De-quantize.
27
     */
28
    f = (10000 - ctx->quality) * 10.0 * (gfloat) 9.9999997e-5;
29
30
    if (f > 10.0)
31
        f = 10.0;
32
33
    if (!is_chrom) {
34
        if (f < 2.0)
35
            f = 2.0;
36
    } else {
37
        if (f < 1.0)
38
            f = 1.0;
39
    }
40
41
    block[0] <<= 1;
42
    block[1] <<= 2;
43
    block[8] <<= 2;
44
45
    for (i = 2; i < 64; i++) {
46
        if (i == 8)
47
            continue;
48
49
        block[i] *= f;
50
    }
51
52
    /*
53
     * Inverse DCT, first pass (horizontal).
54
     */
55
    p = block;
56
57
    for (i = 0; i < 8; i++) {
58
        gint v1, v2, v3, v4, v5, v6, v7, v8;
59
        gint va, vb;
60
61
        va = (p[0] << 11) + (p[4] << 11);
62
        vb = ((p[2] << 2) * 392) + (((p[2] << 2) + (p[6] << 2)) * 277);
63
        v1 = va + vb + 512;
64
        v2 = va - vb + 512;
65
66
        va = (p[0] << 11) - (p[4] << 11);
67
        vb = (((p[2] << 2) + (p[6] << 2)) * 277) - ((p[6] << 2) * 946);
68
        v3 = va + vb + 512;
69
        v4 = va - vb + 512;
70
71
        va = (p[1] << 9) + (p[3] * 724) + (p[7] << 9);
72
        vb = (p[1] << 9) + (p[5] * 724) - (p[7] << 9);
73
        v5 = (((va + vb) * 213) - (vb * 71)) >> 6;
74
        v6 = (((va + vb) * 213) - (va * 355)) >> 6;
75
76
        va = (p[1] << 9) - (p[3] * 724) + (p[7] << 9);
77
        vb = (p[1] << 9) - (p[5] * 724) - (p[7] << 9);
78
        v7 = (((va + vb) * 251) - (va * 201)) >> 6;
79
        v8 = (((va + vb) * 251) - (vb * 301)) >> 6;
80
81
        p[0] = (v1 + v5) >> 10;
82
        p[1] = (v3 + v7) >> 10;
83
        p[2] = (v4 + v8) >> 10;
84
        p[3] = (v2 + v6) >> 10;
85
        p[4] = (v2 - v6) >> 10;
86
        p[5] = (v4 - v8) >> 10;
87
        p[6] = (v3 - v7) >> 10;
88
        p[7] = (v1 - v5) >> 10;
89
90
        p += 8;
91
    }
92
    
93
    /*
94
     * Inverse dct, second pass (vertical).
95
     */
96
    p = block;
97
98
    for (i = 0; i < 8; i++) {
99
        gint v1, v2, v3, v4, v5, v6, v7, v8;
100
        gint va, vb;
101
102
        va = (p[0] << 9) + (p[32] << 9);
103
        vb = ((p[16] + p[48]) * 277) + (p[16] * 392);
104
        v1 = va + vb + 1024;
105
        v2 = va - vb + 1024;
106
107
        va = (p[0] << 9) - (p[32] << 9);
108
        vb = ((p[16] + p[48]) * 277) - (p[48] * 946);
109
        v3 = va + vb + 1024;
110
        v4 = va - vb + 1024;
111
112
        va = ((p[8] << 7) + (p[24] * 181) + (p[56] << 7)) >> 6;
113
        vb = ((p[8] << 7) + (p[40] * 181) - (p[56] << 7)) >> 6;
114
        v5 = ((va + vb) * 213) - (vb * 71);
115
        v6 = ((va + vb) * 213) - (va * 355);
116
117
        va = ((p[8] << 7) - (p[24] * 181) + (p[56] << 7)) >> 6;
118
        vb = ((p[8] << 7) - (p[40] * 181) - (p[56] << 7)) >> 6;
119
        v7 = ((va + vb) * 251) - (va * 201);
120
        v8 = ((va + vb) * 251) - (vb * 301);
121
122
        p[0] = (v1 + v5) >> 11;
123
        p[8] = (v3 + v7) >> 11;
124
        p[16] = (v4 + v8) >> 11;
125
        p[24] = (v2 + v6) >> 11;
126
        p[32] = (v2 - v6) >> 11;
127
        p[40] = (v4 - v8) >> 11;
128
        p[48] = (v3 - v7) >> 11;
129
        p[56] = (v1 - v5) >> 11;
130
131
        p++;
132
    }
133
}
134
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/Makefile.am (-24 lines)
Lines 1-24 Link Here
1
# INCLUDES = @GLIB_CFLAGS@
2
AM_CPPFLAGS = $(all_includes) $(GLIB_CFLAGS)
3
4
# libmimicincludedir = $(includedir)
5
# libmimicinclude_HEADERS = mimic.h
6
7
noinst_LTLIBRARIES = libmimic.la
8
libmimic_la_SOURCES = \
9
	mimic.c \
10
	encode.c \
11
	decode.c \
12
	bitstring.c \
13
	vlc_common.c \
14
	vlc_encode.c \
15
	vlc_decode.c \
16
	fdct_quant.c \
17
	idct_dequant.c \
18
	colorspace.c \
19
	deblock.c \
20
	mimic-private.h
21
# libmimic_la_LDFLAGS = \
22
# 	-version-info $(MIMIC_CURRENT):$(MIMIC_REVISION):$(MIMIC_AGE) \
23
# 	-export-symbols-regex "^[^_].*"
24
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/mimic.c (-334 lines)
Lines 1-334 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <string.h>
19
#include "mimic-private.h"
20
21
/**
22
 * Creates a new instance and returns a pointer to the new context
23
 * that can be used for either encoding or decoding by calling
24
 * #mimic_encoder_init or #mimic_decoder_init.
25
 *
26
 * #mimic_close is called to free any resources associated with
27
 * the context once done.
28
 *
29
 * @returns a new mimic context
30
 */
31
MimCtx *mimic_open()
32
{
33
    MimCtx *ctx;
34
    
35
    ctx = g_new0(MimCtx, 1);
36
    
37
    ctx->encoder_initialized = FALSE;
38
    ctx->decoder_initialized = FALSE;
39
    
40
    return ctx;
41
}
42
43
/**
44
 * Frees any resources associated with the given context.
45
 *
46
 * @param ctx the mimic context to free
47
 */
48
void mimic_close(MimCtx *ctx)
49
{
50
    if (ctx->encoder_initialized || ctx->decoder_initialized) {
51
        gint i;
52
        
53
        g_free(ctx->cur_frame_buf);
54
        
55
        for (i = 0; i < 16; i++)
56
            g_free(ctx->buf_ptrs[i]);
57
    }
58
    
59
    g_free(ctx);
60
}
61
62
/*
63
 * mimic_init
64
 *
65
 * Internal helper-function used to initialize
66
 * a given context.
67
 */
68
static void mimic_init(MimCtx *ctx, gint width, gint height)
69
{
70
    gint bufsize, i;
71
    
72
    /*
73
     * Dimensions-related.
74
     */
75
    ctx->frame_width = width;
76
    ctx->frame_height = height;
77
78
    ctx->y_stride    = ctx->frame_width;
79
    ctx->y_row_count = ctx->frame_height;
80
    ctx->y_size      = ctx->y_stride * ctx->y_row_count;
81
    
82
    ctx->crcb_stride    = ctx->y_stride    / 2;
83
    ctx->crcb_row_count = ctx->y_row_count / 2;
84
    ctx->crcb_size      = ctx->crcb_stride * ctx->crcb_row_count;
85
    
86
    ctx->num_vblocks_y = ctx->frame_height / 8;
87
    ctx->num_hblocks_y = ctx->frame_width  / 8;
88
89
    ctx->num_vblocks_cbcr = ctx->frame_height / 16;
90
    ctx->num_hblocks_cbcr = ctx->frame_width  / 16;
91
92
    if (ctx->frame_height % 16 != 0)
93
        ctx->num_vblocks_cbcr++;
94
95
    /*
96
     * Initialize state.
97
     */
98
    ctx->frame_num = 0;
99
    ctx->ptr_index = 15;
100
    ctx->num_coeffs = 28;
101
102
    /*
103
     * Allocate memory for buffers.
104
     */
105
    ctx->cur_frame_buf = g_new(guchar, (320 * 240 * 3) / 2);
106
107
    bufsize = ctx->y_size + (ctx->crcb_size * 2);
108
    for (i = 0; i < 16; i++)
109
        ctx->buf_ptrs[i] = g_new(guchar, bufsize);
110
111
    /*
112
     * Initialize vlc lookup used by decoder.
113
     */
114
    _initialize_vlcdec_lookup(ctx->vlcdec_lookup);
115
}
116
117
/**
118
 * Initialize the mimic encoder and prepare for encoding by
119
 * initializing internal state and allocating resources as
120
 * needed.
121
 * 
122
 * After initializing use #mimic_get_property to determine
123
 * the size of the output buffer needed for calls to
124
 * #mimic_encode_frame. Use #mimic_set_property to set
125
 * encoding quality.
126
 *
127
 * Note that once a given context has been initialized
128
 * for either encoding or decoding it is not possible
129
 * to initialize it again.
130
 *
131
 * @param ctx the mimic context to initialize
132
 * @param resolution a #MimicResEnum used to specify the resolution
133
 * @returns #TRUE on success
134
 */
135
gboolean mimic_encoder_init(MimCtx *ctx, const MimicResEnum resolution)
136
{
137
    gint width, height;
138
    
139
    /* Check if we've been initialized before. */
140
    if (ctx->encoder_initialized || ctx->decoder_initialized)
141
        return FALSE;
142
143
    /* Check resolution. */
144
    if (resolution == MIMIC_RES_LOW) {
145
        width = 160;
146
        height = 120;
147
    } else if (resolution == MIMIC_RES_HIGH) {
148
        width = 320;
149
        height = 240;
150
    } else {
151
        return FALSE;
152
    }
153
154
    /* Initialize! */
155
    mimic_init(ctx, width, height);
156
157
    /* Set a default quality setting. */
158
    ctx->quality = ENCODER_QUALITY_DEFAULT;
159
160
    ctx->encoder_initialized = TRUE;
161
    
162
    return TRUE;
163
}
164
165
/**
166
 * Initialize the mimic decoder. The frame passed in frame_buffer
167
 * is used to determine the resolution so that the internal state
168
 * can be prepared and resources allocated accordingly. Note that
169
 * the frame passed has to be a keyframe.
170
 *
171
 * After initializing use #mimic_get_property to determine required
172
 * buffer-size, resolution, quality, etc.
173
 *
174
 * Note that once a given context has been initialized
175
 * for either encoding or decoding it is not possible
176
 * to initialize it again.
177
 *
178
 * @param ctx the mimic context to initialize
179
 * @param frame_buffer buffer containing the first frame to decode
180
 * @returns #TRUE on success
181
 */
182
gboolean mimic_decoder_init(MimCtx *ctx, const guchar *frame_buffer)
183
{
184
    gint width, height;
185
    gboolean is_keyframe;
186
    
187
    /* Check if we've been initialized before and that
188
     * frame_buffer is not NULL. */
189
    if (ctx->encoder_initialized || ctx->decoder_initialized ||
190
        frame_buffer == NULL)
191
    {
192
        return FALSE;
193
    }
194
    
195
    /* Check resolution. */
196
    width  = GUINT16_FROM_LE(*((guint16 *) (frame_buffer + 4)));
197
    height = GUINT16_FROM_LE(*((guint16 *) (frame_buffer + 6)));
198
    
199
    if (!(width == 160 && height == 120) && !(width == 320 && height == 240))
200
        return FALSE;
201
202
    /* Check that we're initialized with a keyframe. */
203
    is_keyframe = (GUINT32_FROM_LE(*((guint32 *) (frame_buffer + 12))) == 0);
204
    
205
    if (!is_keyframe)
206
        return FALSE;
207
208
    /* Get quality setting (in case we get queried for it before decoding). */
209
    ctx->quality = GUINT16_FROM_LE(*((guint16 *) (frame_buffer + 2)));
210
 
211
    /* Initialize! */
212
    mimic_init(ctx, width, height);
213
214
    ctx->decoder_initialized = TRUE;
215
216
    return TRUE;
217
}
218
219
/**
220
 * Get a property from a given mimic context. The context
221
 * has to be initialized.
222
 *
223
 * Currently the following properties are defined:
224
 *   - "buffer_size"
225
 *       - Required output buffer size
226
 *   - "width"
227
 *       - Frame width
228
 *   - "height"
229
 *       - Frame height
230
 *   - "quality"
231
 *       - Encoder: Encoding quality used
232
 *       - Decoder: Decoding quality of the last known frame
233
 *
234
 * @param ctx the mimic context to retrieve the property from
235
 * @param name of the property to retrieve the current value of
236
 * @param data pointer to the data that will receive the retrieved value
237
 * @returns #TRUE on success
238
 */
239
gboolean mimic_get_property(MimCtx *ctx, const gchar *name, gpointer data)
240
{
241
    /* Either the encoder or the decoder has to be initialized. */
242
    if (!ctx->encoder_initialized && !ctx->decoder_initialized)
243
        return FALSE;
244
245
    if (ctx->encoder_initialized) {
246
247
        if (strcmp(name, "buffer_size") == 0) {
248
            *((gint *) data) = ENCODER_BUFFER_SIZE;
249
250
            return TRUE;
251
        }
252
        
253
    } else { /* decoder_initialized */
254
255
        if (strcmp(name, "buffer_size") == 0) {
256
            *((gint *) data) = ctx->frame_width * ctx->frame_height * 3;
257
258
            return TRUE;
259
        }
260
    }
261
262
    if (strcmp(name, "width") == 0) {
263
        *((gint *) data) = ctx->frame_width;
264
265
        return TRUE;
266
    } else if (strcmp(name, "height") == 0) {
267
        *((gint *) data) = ctx->frame_height;
268
        
269
        return TRUE;
270
    } else if (strcmp(name, "quality") == 0) {
271
        *((gint *) data) = ctx->quality;
272
        
273
        return TRUE;
274
    }
275
276
    return FALSE;
277
}
278
279
/**
280
 * Set a property in a given mimic context. The context
281
 * has to be initialized.
282
 *
283
 * Currently the following properties are defined:
284
 *   - "quality"
285
 *       - Encoding quality used by encoder.
286
 *
287
 * @param ctx the mimic context to set a property in
288
 * @param name of the property to set to a new value
289
 * @param data pointer to the data that contains the new value
290
 * @returns #TRUE on success
291
 */
292
gboolean mimic_set_property(MimCtx *ctx, const gchar *name, gpointer data)
293
{
294
    /* Either the encoder or the decoder has to be initialized. */
295
    if (!ctx->encoder_initialized && !ctx->decoder_initialized)
296
        return FALSE;
297
298
    if (ctx->encoder_initialized) {
299
300
        if (strcmp(name, "quality") == 0) {
301
            gint new_quality = *((gint *) data);
302
303
            if (new_quality < ENCODER_QUALITY_MIN ||
304
                new_quality > ENCODER_QUALITY_MAX)
305
            {
306
                return FALSE;
307
            }
308
309
            ctx->quality = new_quality;
310
311
            return TRUE;
312
        }
313
        
314
    } else { /* decoder_initialized */ }
315
316
    return FALSE;
317
}
318
319
/*
320
 * _clamp_value
321
 *
322
 * Internal helper-function used to clamp a given
323
 * value to the range [ 0, 255 ].
324
 */
325
guchar _clamp_value(gint value)
326
{
327
    if (value < 0)
328
        return 0;
329
    else if (value > 255)
330
        return 255;
331
    else
332
        return value;
333
}
334
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/mimic.h (-73 lines)
Lines 1-73 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#ifndef MIMIC_H
19
#define MIMIC_H
20
21
#include <glib.h>
22
23
#ifdef __cplusplus
24
extern "C" {
25
#endif
26
27
/**
28
 * @defgroup libmimic libmimic public API
29
 * @brief The public API of the libmimic library
30
 *
31
 * libmimic provides the API required for encoding and decoding
32
 * MIMIC v2.x-encoded content.
33
 *
34
 * @{
35
 */
36
37
/**
38
 * The mimic encoding/decoding context returned by #mimic_open
39
 * and used for all further API calls until #mimic_close.
40
 */
41
typedef struct _MimCtx MimCtx;
42
43
typedef enum {
44
    MIMIC_RES_LOW,      /**< 160x120 resolution */
45
    MIMIC_RES_HIGH      /**< 320x240 resolution */
46
} MimicResEnum;
47
48
MimCtx *mimic_open();
49
void mimic_close(MimCtx *ctx);
50
51
gboolean mimic_encoder_init(MimCtx *ctx, const MimicResEnum resolution);
52
gboolean mimic_decoder_init(MimCtx *ctx, const guchar *frame_buffer);
53
54
gboolean mimic_get_property(MimCtx *ctx, const gchar *name, gpointer data);
55
gboolean mimic_set_property(MimCtx *ctx, const gchar *name, gpointer data);
56
57
gboolean mimic_encode_frame(MimCtx *ctx,
58
                            const guchar *input_buffer,
59
                            guchar *output_buffer,
60
                            gint *output_length,
61
                            gboolean make_keyframe);
62
gboolean mimic_decode_frame(MimCtx *ctx,
63
                            const guchar *input_buffer,
64
                            guchar *output_buffer);
65
66
/** @} */
67
68
#ifdef __cplusplus
69
}
70
#endif
71
72
#endif
73
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/mimic-private.h (-117 lines)
Lines 1-117 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#ifndef MIMIC_PRIVATE_H
19
#define MIMIC_PRIVATE_H
20
21
#include "mimic.h"
22
23
#define ENCODER_BUFFER_SIZE         16384
24
#define ENCODER_QUALITY_DEFAULT     0
25
#define ENCODER_QUALITY_MIN         0
26
#define ENCODER_QUALITY_MAX         10000
27
28
struct _MimCtx {
29
    gboolean encoder_initialized;
30
    gboolean decoder_initialized;
31
    
32
    gint frame_width;
33
    gint frame_height;
34
    gint quality;
35
    gint num_coeffs;
36
    
37
    gint y_stride;
38
    gint y_row_count;
39
    gint y_size;
40
    
41
    gint crcb_stride;
42
    gint crcb_row_count;
43
    gint crcb_size;
44
    
45
    gint num_vblocks_y;
46
    gint num_hblocks_y;
47
    
48
    gint num_vblocks_cbcr;
49
    gint num_hblocks_cbcr;
50
    
51
    guchar *cur_frame_buf;
52
    guchar *prev_frame_buf;
53
    
54
    gint8 vlcdec_lookup[2296];
55
    
56
    gchar *data_buffer;
57
    guint data_index;
58
59
    guint32 cur_chunk;
60
    gint cur_chunk_len;
61
    
62
    guint32 *chunk_ptr;
63
    gboolean read_odd;
64
65
    gint frame_num;
66
    
67
    gint ptr_index;
68
    guchar *buf_ptrs[16];
69
};
70
71
typedef struct {
72
	guchar length1;
73
	guint32 part1;
74
75
	guchar length2;
76
	guint32 part2;
77
} VlcSymbol;
78
79
typedef struct {
80
    guint32 magic;
81
    guchar pos_add;
82
    guchar num_bits;
83
} VlcMagic;
84
85
void _mimic_init(MimCtx *ctx, gint width, gint height);
86
guchar _clamp_value(gint value);
87
88
guint32 _read_bits(MimCtx *ctx, gint num_bits);
89
void _write_bits(MimCtx *ctx, guint32 bits, gint length);
90
91
void _vlc_encode_block(MimCtx *ctx, const gint *block, gint num_coeffs);
92
gboolean _vlc_decode_block(MimCtx *ctx, gint *block, gint num_coeffs);
93
94
void _fdct_quant_block(MimCtx *ctx, gint *block, const guchar *src,
95
                       gint stride, gboolean is_chrom, gint num_coeffs);
96
void _idct_dequant_block(MimCtx *ctx, gint *block, gboolean is_chrom);
97
98
VlcMagic *_find_magic(guint magic);
99
void _initialize_vlcdec_lookup(gint8 *lookup_tbl);
100
101
void _rgb_to_yuv(const guchar *input_rgb,
102
                 guchar *output_y,
103
                 guchar *output_cb,
104
                 guchar *output_cr,
105
                 gint width,
106
                 gint height);
107
void _yuv_to_rgb(const guchar *input_y,
108
                 const guchar *input_cb,
109
                 const guchar *input_cr,
110
                 guchar *output_rgb,
111
                 guint width,
112
                 guint height);
113
114
void _deblock(guchar *blocks, guint stride, guint row_count);
115
116
#endif
117
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/query.c (-1 lines)
Line 1 Link Here
1
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/README (-40 lines)
Lines 1-40 Link Here
1
ABOUT
2
-----
3
4
libmimic is an open source video encoding/decoding library for Mimic V2.x-
5
encoded content (fourCC: ML20), which is the encoding used by MSN Messenger
6
for webcam conversations.
7
8
It was written because there was no third-party MSN-client that supported
9
this feature due to this proprietary/unknown codec involved. I didn't like
10
this lack of interoperability, so I decided to do something about it. After
11
studying the official MSN-client a little closer, it became clear that the
12
codec involved was statically linked into the executable, so there was no
13
easy way to use the codec code through Wine. So for fun, and challenge, I
14
reverse-engineered the original implementation by studying the massive
15
amount of assembly code involved, and after a lot of hard work I ended
16
up with this implementation in C.
17
18
It should be noted that reverse-engineering for interoperability is 100%
19
legal here in Norway (and in most European countries).
20
21
22
THANKS
23
------
24
25
Special thanks to Rob Taylor and the rest of the Farsight-team for all
26
the feedback and inspiration during development, you guys rock! :-)
27
28
29
BOTTOM LINE
30
-----------
31
32
If you like my work and decide to use it in your project, please feel free
33
to credit me. I put a lot of time and hard work into this, so I hope others
34
will find it useful.
35
36
Well, enough chit chat, enjoy! :-)
37
38
Ole André Vadla Ravnås
39
oleavr at gmail dot com
40
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/vlc_common.c (-1364 lines)
Lines 1-1364 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <stdlib.h>
19
#include "mimic-private.h"
20
21
guchar _col_zag[64] = {
22
     0,  8,  1,  2,  9, 16, 24, 17,
23
    10,  3,  4, 11, 18, 25, 32, 40,
24
    33, 26, 19, 12,  5,  6, 13, 20,
25
    27, 34, 41, 48, 56, 49, 42, 35,
26
    28, 21, 14,  7, 15, 22, 29, 36,
27
    43, 50, 57, 58, 51, 44, 37, 30,
28
    23, 31, 38, 45, 52, 59, 39, 46,
29
    53, 60, 61, 54, 47, 55, 62, 63
30
};
31
32
VlcSymbol _vlc_alphabet[16][128] = {
33
34
    /*
35
     * base alphabet - no zeroes prefixed
36
     */
37
    {
38
        {  3,        0x1, 0,    0 },   {  4,        0x7, 0,    0 },
39
        {  4,        0x5, 0,    0 },   {  6,       0x27, 0,    0 },
40
        {  6,       0x25, 0,    0 },   {  6,       0x23, 0,    0 },
41
        {  6,       0x21, 0,    0 },   {  8,       0xcf, 0,    0 },
42
        {  8,       0xcd, 0,    0 },   {  8,       0xcb, 0,    0 },
43
        {  8,       0xc9, 0,    0 },   {  8,       0xc7, 0,    0 },
44
        {  8,       0xc5, 0,    0 },   {  8,       0xc3, 0,    0 },
45
        {  8,       0xc1, 0,    0 },   { 10,      0x35f, 0,    0 },
46
        { 10,      0x35d, 0,    0 },   { 10,      0x35b, 0,    0 },
47
        { 10,      0x359, 0,    0 },   { 10,      0x357, 0,    0 },
48
        { 10,      0x355, 0,    0 },   { 10,      0x353, 0,    0 },
49
        { 10,      0x351, 0,    0 },   { 10,      0x34f, 0,    0 },
50
        { 10,      0x34d, 0,    0 },   { 10,      0x34b, 0,    0 },
51
        { 10,      0x349, 0,    0 },   { 10,      0x347, 0,    0 },
52
        { 10,      0x345, 0,    0 },   { 10,      0x343, 0,    0 },
53
        { 10,      0x341, 0,    0 },   { 12,      0xeff, 0,    0 },
54
        { 12,      0xefd, 0,    0 },   { 12,      0xefb, 0,    0 },
55
        { 12,      0xef9, 0,    0 },   { 12,      0xef7, 0,    0 },
56
        { 12,      0xef5, 0,    0 },   { 12,      0xef3, 0,    0 },
57
        { 12,      0xef1, 0,    0 },   { 12,      0xeef, 0,    0 },
58
        { 12,      0xeed, 0,    0 },   { 12,      0xeeb, 0,    0 },
59
        { 12,      0xee9, 0,    0 },   { 12,      0xee7, 0,    0 },
60
        { 12,      0xee5, 0,    0 },   { 12,      0xee3, 0,    0 },
61
        { 12,      0xee1, 0,    0 },   { 12,      0xedf, 0,    0 },
62
        { 12,      0xedd, 0,    0 },   { 12,      0xedb, 0,    0 },
63
        { 12,      0xed9, 0,    0 },   { 12,      0xed7, 0,    0 },
64
        { 12,      0xed5, 0,    0 },   { 12,      0xed3, 0,    0 },
65
        { 12,      0xed1, 0,    0 },   { 12,      0xecf, 0,    0 },
66
        { 12,      0xecd, 0,    0 },   { 12,      0xecb, 0,    0 },
67
        { 12,      0xec9, 0,    0 },   { 12,      0xec7, 0,    0 },
68
        { 12,      0xec5, 0,    0 },   { 12,      0xec3, 0,    0 },
69
        { 12,      0xec1, 0,    0 },   { 17,    0x1fd7f, 0,    0 },
70
        { 17,    0x1fd7d, 0,    0 },   { 17,    0x1fd7b, 0,    0 },
71
        { 17,    0x1fd79, 0,    0 },   { 17,    0x1fd77, 0,    0 },
72
        { 17,    0x1fd75, 0,    0 },   { 17,    0x1fd73, 0,    0 },
73
        { 17,    0x1fd71, 0,    0 },   { 17,    0x1fd6f, 0,    0 },
74
        { 17,    0x1fd6d, 0,    0 },   { 17,    0x1fd6b, 0,    0 },
75
        { 17,    0x1fd69, 0,    0 },   { 17,    0x1fd67, 0,    0 },
76
        { 17,    0x1fd65, 0,    0 },   { 17,    0x1fd63, 0,    0 },
77
        { 17,    0x1fd61, 0,    0 },   { 17,    0x1fd5f, 0,    0 },
78
        { 17,    0x1fd5d, 0,    0 },   { 17,    0x1fd5b, 0,    0 },
79
        { 17,    0x1fd59, 0,    0 },   { 17,    0x1fd57, 0,    0 },
80
        { 17,    0x1fd55, 0,    0 },   { 17,    0x1fd53, 0,    0 },
81
        { 17,    0x1fd51, 0,    0 },   { 17,    0x1fd4f, 0,    0 },
82
        { 17,    0x1fd4d, 0,    0 },   { 17,    0x1fd4b, 0,    0 },
83
        { 17,    0x1fd49, 0,    0 },   { 17,    0x1fd47, 0,    0 },
84
        { 17,    0x1fd45, 0,    0 },   { 17,    0x1fd43, 0,    0 },
85
        { 17,    0x1fd41, 0,    0 },   { 17,    0x1fd3f, 0,    0 },
86
        { 17,    0x1fd3d, 0,    0 },   { 17,    0x1fd3b, 0,    0 },
87
        { 17,    0x1fd39, 0,    0 },   { 17,    0x1fd37, 0,    0 },
88
        { 17,    0x1fd35, 0,    0 },   { 17,    0x1fd33, 0,    0 },
89
        { 17,    0x1fd31, 0,    0 },   { 17,    0x1fd2f, 0,    0 },
90
        { 17,    0x1fd2d, 0,    0 },   { 17,    0x1fd2b, 0,    0 },
91
        { 17,    0x1fd29, 0,    0 },   { 17,    0x1fd27, 0,    0 },
92
        { 17,    0x1fd25, 0,    0 },   { 17,    0x1fd23, 0,    0 },
93
        { 17,    0x1fd21, 0,    0 },   { 17,    0x1fd1f, 0,    0 },
94
        { 17,    0x1fd1d, 0,    0 },   { 17,    0x1fd1b, 0,    0 },
95
        { 17,    0x1fd19, 0,    0 },   { 17,    0x1fd17, 0,    0 },
96
        { 17,    0x1fd15, 0,    0 },   { 17,    0x1fd13, 0,    0 },
97
        { 17,    0x1fd11, 0,    0 },   { 17,    0x1fd0f, 0,    0 },
98
        { 17,    0x1fd0d, 0,    0 },   { 17,    0x1fd0b, 0,    0 },
99
        { 17,    0x1fd09, 0,    0 },   { 17,    0x1fd07, 0,    0 },
100
        { 17,    0x1fd05, 0,    0 },   { 17,    0x1fd03, 0,    0 },
101
        { 17,    0x1fd01, 0,    0 },   { 17,    0x1fd01, 0,    0 }
102
    },
103
104
    /*
105
     * prefixed with 1 zero
106
     */
107
    {
108
        {  5,       0x17, 0,    0 },   {  8,       0xe7, 0,    0 },
109
        {  8,       0xe5, 0,    0 },   {  9,      0x1d7, 0,    0 },
110
        {  9,      0x1d5, 0,    0 },   {  9,      0x1d3, 0,    0 },
111
        {  9,      0x1d1, 0,    0 },   { 12,      0xf8f, 0,    0 },
112
        { 12,      0xf8d, 0,    0 },   { 12,      0xf8b, 0,    0 },
113
        { 12,      0xf89, 0,    0 },   { 12,      0xf87, 0,    0 },
114
        { 12,      0xf85, 0,    0 },   { 12,      0xf83, 0,    0 },
115
        { 12,      0xf81, 0,    0 },   { 15,     0x7f1f, 0,    0 },
116
        { 15,     0x7f1d, 0,    0 },   { 15,     0x7f1b, 0,    0 },
117
        { 15,     0x7f19, 0,    0 },   { 15,     0x7f17, 0,    0 },
118
        { 15,     0x7f15, 0,    0 },   { 15,     0x7f13, 0,    0 },
119
        { 15,     0x7f11, 0,    0 },   { 15,     0x7f0f, 0,    0 },
120
        { 15,     0x7f0d, 0,    0 },   { 15,     0x7f0b, 0,    0 },
121
        { 15,     0x7f09, 0,    0 },   { 15,     0x7f07, 0,    0 },
122
        { 15,     0x7f05, 0,    0 },   { 15,     0x7f03, 0,    0 },
123
        { 15,     0x7f01, 0,    0 },   { 16,     0xfe7f, 0,    0 },
124
        { 16,     0xfe7d, 0,    0 },   { 16,     0xfe7b, 0,    0 },
125
        { 16,     0xfe79, 0,    0 },   { 16,     0xfe77, 0,    0 },
126
        { 16,     0xfe75, 0,    0 },   { 16,     0xfe73, 0,    0 },
127
        { 16,     0xfe71, 0,    0 },   { 16,     0xfe6f, 0,    0 },
128
        { 16,     0xfe6d, 0,    0 },   { 16,     0xfe6b, 0,    0 },
129
        { 16,     0xfe69, 0,    0 },   { 16,     0xfe67, 0,    0 },
130
        { 16,     0xfe65, 0,    0 },   { 16,     0xfe63, 0,    0 },
131
        { 16,     0xfe61, 0,    0 },   { 16,     0xfe5f, 0,    0 },
132
        { 16,     0xfe5d, 0,    0 },   { 16,     0xfe5b, 0,    0 },
133
        { 16,     0xfe59, 0,    0 },   { 16,     0xfe57, 0,    0 },
134
        { 16,     0xfe55, 0,    0 },   { 16,     0xfe53, 0,    0 },
135
        { 16,     0xfe51, 0,    0 },   { 16,     0xfe4f, 0,    0 },
136
        { 16,     0xfe4d, 0,    0 },   { 16,     0xfe4b, 0,    0 },
137
        { 16,     0xfe49, 0,    0 },   { 16,     0xfe47, 0,    0 },
138
        { 16,     0xfe45, 0,    0 },   { 16,     0xfe43, 0,    0 },
139
        { 16,     0xfe41, 0,    0 },   { 27,  0x7fffff9, 7, 0x7f },
140
        { 27,  0x7fffff9, 7, 0x7d },   { 27,  0x7fffff9, 7, 0x7b },
141
        { 27,  0x7fffff9, 7, 0x79 },   { 27,  0x7fffff9, 7, 0x77 },
142
        { 27,  0x7fffff9, 7, 0x75 },   { 27,  0x7fffff9, 7, 0x73 },
143
        { 27,  0x7fffff9, 7, 0x71 },   { 27,  0x7fffff9, 7, 0x6f },
144
        { 27,  0x7fffff9, 7, 0x6d },   { 27,  0x7fffff9, 7, 0x6b },
145
        { 27,  0x7fffff9, 7, 0x69 },   { 27,  0x7fffff9, 7, 0x67 },
146
        { 27,  0x7fffff9, 7, 0x65 },   { 27,  0x7fffff9, 7, 0x63 },
147
        { 27,  0x7fffff9, 7, 0x61 },   { 27,  0x7fffff9, 7, 0x5f },
148
        { 27,  0x7fffff9, 7, 0x5d },   { 27,  0x7fffff9, 7, 0x5b },
149
        { 27,  0x7fffff9, 7, 0x59 },   { 27,  0x7fffff9, 7, 0x57 },
150
        { 27,  0x7fffff9, 7, 0x55 },   { 27,  0x7fffff9, 7, 0x53 },
151
        { 27,  0x7fffff9, 7, 0x51 },   { 27,  0x7fffff9, 7, 0x4f },
152
        { 27,  0x7fffff9, 7, 0x4d },   { 27,  0x7fffff9, 7, 0x4b },
153
        { 27,  0x7fffff9, 7, 0x49 },   { 27,  0x7fffff9, 7, 0x47 },
154
        { 27,  0x7fffff9, 7, 0x45 },   { 27,  0x7fffff9, 7, 0x43 },
155
        { 27,  0x7fffff9, 7, 0x41 },   { 27,  0x7fffff9, 7, 0x3f },
156
        { 27,  0x7fffff9, 7, 0x3d },   { 27,  0x7fffff9, 7, 0x3b },
157
        { 27,  0x7fffff9, 7, 0x39 },   { 27,  0x7fffff9, 7, 0x37 },
158
        { 27,  0x7fffff9, 7, 0x35 },   { 27,  0x7fffff9, 7, 0x33 },
159
        { 27,  0x7fffff9, 7, 0x31 },   { 27,  0x7fffff9, 7, 0x2f },
160
        { 27,  0x7fffff9, 7, 0x2d },   { 27,  0x7fffff9, 7, 0x2b },
161
        { 27,  0x7fffff9, 7, 0x29 },   { 27,  0x7fffff9, 7, 0x27 },
162
        { 27,  0x7fffff9, 7, 0x25 },   { 27,  0x7fffff9, 7, 0x23 },
163
        { 27,  0x7fffff9, 7, 0x21 },   { 27,  0x7fffff9, 7, 0x1f },
164
        { 27,  0x7fffff9, 7, 0x1d },   { 27,  0x7fffff9, 7, 0x1b },
165
        { 27,  0x7fffff9, 7, 0x19 },   { 27,  0x7fffff9, 7, 0x17 },
166
        { 27,  0x7fffff9, 7, 0x15 },   { 27,  0x7fffff9, 7, 0x13 },
167
        { 27,  0x7fffff9, 7, 0x11 },   { 27,  0x7fffff9, 7,  0xf },
168
        { 27,  0x7fffff9, 7,  0xd },   { 27,  0x7fffff9, 7,  0xb },
169
        { 27,  0x7fffff9, 7,  0x9 },   { 27,  0x7fffff9, 7,  0x7 },
170
        { 27,  0x7fffff9, 7,  0x5 },   { 27,  0x7fffff9, 7,  0x3 },
171
        { 27,  0x7fffff9, 7,  0x1 },   { 27,  0x7fffff9, 7,  0x1 }
172
    },
173
174
    /*
175
     * prefixed with 2 zeroes
176
     */
177
    {
178
        {  6,       0x37, 0,    0 },   {  9,      0x1ef, 0,    0 },
179
        {  9,      0x1ed, 0,    0 },   { 12,      0xfd7, 0,    0 },
180
        { 12,      0xfd5, 0,    0 },   { 12,      0xfd3, 0,    0 },
181
        { 12,      0xfd1, 0,    0 },   { 13,     0x1fbf, 0,    0 },
182
        { 13,     0x1fbd, 0,    0 },   { 13,     0x1fbb, 0,    0 },
183
        { 13,     0x1fb9, 0,    0 },   { 13,     0x1fb7, 0,    0 },
184
        { 13,     0x1fb5, 0,    0 },   { 13,     0x1fb3, 0,    0 },
185
        { 13,     0x1fb1, 0,    0 },   { 25,  0x1ffff7f, 0,    0 },
186
        { 25,  0x1ffff7d, 0,    0 },   { 25,  0x1ffff7b, 0,    0 },
187
        { 25,  0x1ffff79, 0,    0 },   { 25,  0x1ffff77, 0,    0 },
188
        { 25,  0x1ffff75, 0,    0 },   { 25,  0x1ffff73, 0,    0 },
189
        { 25,  0x1ffff71, 0,    0 },   { 25,  0x1ffff6f, 0,    0 },
190
        { 25,  0x1ffff6d, 0,    0 },   { 25,  0x1ffff6b, 0,    0 },
191
        { 25,  0x1ffff69, 0,    0 },   { 25,  0x1ffff67, 0,    0 },
192
        { 25,  0x1ffff65, 0,    0 },   { 25,  0x1ffff63, 0,    0 },
193
        { 25,  0x1ffff61, 0,    0 },   { 30, 0x3ffffe3f, 0,    0 },
194
        { 30, 0x3ffffe3d, 0,    0 },   { 30, 0x3ffffe3b, 0,    0 },
195
        { 30, 0x3ffffe39, 0,    0 },   { 30, 0x3ffffe37, 0,    0 },
196
        { 30, 0x3ffffe35, 0,    0 },   { 30, 0x3ffffe33, 0,    0 },
197
        { 30, 0x3ffffe31, 0,    0 },   { 30, 0x3ffffe2f, 0,    0 },
198
        { 30, 0x3ffffe2d, 0,    0 },   { 30, 0x3ffffe2b, 0,    0 },
199
        { 30, 0x3ffffe29, 0,    0 },   { 30, 0x3ffffe27, 0,    0 },
200
        { 30, 0x3ffffe25, 0,    0 },   { 30, 0x3ffffe23, 0,    0 },
201
        { 30, 0x3ffffe21, 0,    0 },   { 30, 0x3ffffe1f, 0,    0 },
202
        { 30, 0x3ffffe1d, 0,    0 },   { 30, 0x3ffffe1b, 0,    0 },
203
        { 30, 0x3ffffe19, 0,    0 },   { 30, 0x3ffffe17, 0,    0 },
204
        { 30, 0x3ffffe15, 0,    0 },   { 30, 0x3ffffe13, 0,    0 },
205
        { 30, 0x3ffffe11, 0,    0 },   { 30, 0x3ffffe0f, 0,    0 },
206
        { 30, 0x3ffffe0d, 0,    0 },   { 30, 0x3ffffe0b, 0,    0 },
207
        { 30, 0x3ffffe09, 0,    0 },   { 30, 0x3ffffe07, 0,    0 },
208
        { 30, 0x3ffffe05, 0,    0 },   { 30, 0x3ffffe03, 0,    0 },
209
        { 30, 0x3ffffe01, 0,    0 },   { 27,  0x7fffffa, 7, 0x7f },
210
        { 27,  0x7fffffa, 7, 0x7d },   { 27,  0x7fffffa, 7, 0x7b },
211
        { 27,  0x7fffffa, 7, 0x79 },   { 27,  0x7fffffa, 7, 0x77 },
212
        { 27,  0x7fffffa, 7, 0x75 },   { 27,  0x7fffffa, 7, 0x73 },
213
        { 27,  0x7fffffa, 7, 0x71 },   { 27,  0x7fffffa, 7, 0x6f },
214
        { 27,  0x7fffffa, 7, 0x6d },   { 27,  0x7fffffa, 7, 0x6b },
215
        { 27,  0x7fffffa, 7, 0x69 },   { 27,  0x7fffffa, 7, 0x67 },
216
        { 27,  0x7fffffa, 7, 0x65 },   { 27,  0x7fffffa, 7, 0x63 },
217
        { 27,  0x7fffffa, 7, 0x61 },   { 27,  0x7fffffa, 7, 0x5f },
218
        { 27,  0x7fffffa, 7, 0x5d },   { 27,  0x7fffffa, 7, 0x5b },
219
        { 27,  0x7fffffa, 7, 0x59 },   { 27,  0x7fffffa, 7, 0x57 },
220
        { 27,  0x7fffffa, 7, 0x55 },   { 27,  0x7fffffa, 7, 0x53 },
221
        { 27,  0x7fffffa, 7, 0x51 },   { 27,  0x7fffffa, 7, 0x4f },
222
        { 27,  0x7fffffa, 7, 0x4d },   { 27,  0x7fffffa, 7, 0x4b },
223
        { 27,  0x7fffffa, 7, 0x49 },   { 27,  0x7fffffa, 7, 0x47 },
224
        { 27,  0x7fffffa, 7, 0x45 },   { 27,  0x7fffffa, 7, 0x43 },
225
        { 27,  0x7fffffa, 7, 0x41 },   { 27,  0x7fffffa, 7, 0x3f },
226
        { 27,  0x7fffffa, 7, 0x3d },   { 27,  0x7fffffa, 7, 0x3b },
227
        { 27,  0x7fffffa, 7, 0x39 },   { 27,  0x7fffffa, 7, 0x37 },
228
        { 27,  0x7fffffa, 7, 0x35 },   { 27,  0x7fffffa, 7, 0x33 },
229
        { 27,  0x7fffffa, 7, 0x31 },   { 27,  0x7fffffa, 7, 0x2f },
230
        { 27,  0x7fffffa, 7, 0x2d },   { 27,  0x7fffffa, 7, 0x2b },
231
        { 27,  0x7fffffa, 7, 0x29 },   { 27,  0x7fffffa, 7, 0x27 },
232
        { 27,  0x7fffffa, 7, 0x25 },   { 27,  0x7fffffa, 7, 0x23 },
233
        { 27,  0x7fffffa, 7, 0x21 },   { 27,  0x7fffffa, 7, 0x1f },
234
        { 27,  0x7fffffa, 7, 0x1d },   { 27,  0x7fffffa, 7, 0x1b },
235
        { 27,  0x7fffffa, 7, 0x19 },   { 27,  0x7fffffa, 7, 0x17 },
236
        { 27,  0x7fffffa, 7, 0x15 },   { 27,  0x7fffffa, 7, 0x13 },
237
        { 27,  0x7fffffa, 7, 0x11 },   { 27,  0x7fffffa, 7,  0xf },
238
        { 27,  0x7fffffa, 7,  0xd },   { 27,  0x7fffffa, 7,  0xb },
239
        { 27,  0x7fffffa, 7,  0x9 },   { 27,  0x7fffffa, 7,  0x7 },
240
        { 27,  0x7fffffa, 7,  0x5 },   { 27,  0x7fffffa, 7,  0x3 },
241
        { 27,  0x7fffffa, 7,  0x1 },   { 27,  0x7fffffa, 7,  0x1 }
242
    },
243
244
    /*
245
     * prefixed with 3 zeroes
246
     */
247
    {
248
        {  7,       0x71, 0,    0 },   { 10,      0x3ef, 0,    0 },
249
        { 10,      0x3ed, 0,    0 },   { 17,    0x1ffdf, 0,    0 },
250
        { 17,    0x1ffdd, 0,    0 },   { 17,    0x1ffdb, 0,    0 },
251
        { 17,    0x1ffd9, 0,    0 },   { 21,   0x1fffbf, 0,    0 },
252
        { 21,   0x1fffbd, 0,    0 },   { 21,   0x1fffbb, 0,    0 },
253
        { 21,   0x1fffb9, 0,    0 },   { 21,   0x1fffb7, 0,    0 },
254
        { 21,   0x1fffb5, 0,    0 },   { 21,   0x1fffb3, 0,    0 },
255
        { 21,   0x1fffb1, 0,    0 },   { 26,  0x3ffff1f, 0,    0 },
256
        { 26,  0x3ffff1d, 0,    0 },   { 26,  0x3ffff1b, 0,    0 },
257
        { 26,  0x3ffff19, 0,    0 },   { 26,  0x3ffff17, 0,    0 },
258
        { 26,  0x3ffff15, 0,    0 },   { 26,  0x3ffff13, 0,    0 },
259
        { 26,  0x3ffff11, 0,    0 },   { 26,  0x3ffff0f, 0,    0 },
260
        { 26,  0x3ffff0d, 0,    0 },   { 26,  0x3ffff0b, 0,    0 },
261
        { 26,  0x3ffff09, 0,    0 },   { 26,  0x3ffff07, 0,    0 },
262
        { 26,  0x3ffff05, 0,    0 },   { 26,  0x3ffff03, 0,    0 },
263
        { 26,  0x3ffff01, 0,    0 },   { 30, 0x3ffffe7f, 0,    0 },
264
        { 30, 0x3ffffe7d, 0,    0 },   { 30, 0x3ffffe7b, 0,    0 },
265
        { 30, 0x3ffffe79, 0,    0 },   { 30, 0x3ffffe77, 0,    0 },
266
        { 30, 0x3ffffe75, 0,    0 },   { 30, 0x3ffffe73, 0,    0 },
267
        { 30, 0x3ffffe71, 0,    0 },   { 30, 0x3ffffe6f, 0,    0 },
268
        { 30, 0x3ffffe6d, 0,    0 },   { 30, 0x3ffffe6b, 0,    0 },
269
        { 30, 0x3ffffe69, 0,    0 },   { 30, 0x3ffffe67, 0,    0 },
270
        { 30, 0x3ffffe65, 0,    0 },   { 30, 0x3ffffe63, 0,    0 },
271
        { 30, 0x3ffffe61, 0,    0 },   { 30, 0x3ffffe5f, 0,    0 },
272
        { 30, 0x3ffffe5d, 0,    0 },   { 30, 0x3ffffe5b, 0,    0 },
273
        { 30, 0x3ffffe59, 0,    0 },   { 30, 0x3ffffe57, 0,    0 },
274
        { 30, 0x3ffffe55, 0,    0 },   { 30, 0x3ffffe53, 0,    0 },
275
        { 30, 0x3ffffe51, 0,    0 },   { 30, 0x3ffffe4f, 0,    0 },
276
        { 30, 0x3ffffe4d, 0,    0 },   { 30, 0x3ffffe4b, 0,    0 },
277
        { 30, 0x3ffffe49, 0,    0 },   { 30, 0x3ffffe47, 0,    0 },
278
        { 30, 0x3ffffe45, 0,    0 },   { 30, 0x3ffffe43, 0,    0 },
279
        { 30, 0x3ffffe41, 0,    0 },   { 27,  0x7fffffb, 7, 0x7f },
280
        { 27,  0x7fffffb, 7, 0x7d },   { 27,  0x7fffffb, 7, 0x7b },
281
        { 27,  0x7fffffb, 7, 0x79 },   { 27,  0x7fffffb, 7, 0x77 },
282
        { 27,  0x7fffffb, 7, 0x75 },   { 27,  0x7fffffb, 7, 0x73 },
283
        { 27,  0x7fffffb, 7, 0x71 },   { 27,  0x7fffffb, 7, 0x6f },
284
        { 27,  0x7fffffb, 7, 0x6d },   { 27,  0x7fffffb, 7, 0x6b },
285
        { 27,  0x7fffffb, 7, 0x69 },   { 27,  0x7fffffb, 7, 0x67 },
286
        { 27,  0x7fffffb, 7, 0x65 },   { 27,  0x7fffffb, 7, 0x63 },
287
        { 27,  0x7fffffb, 7, 0x61 },   { 27,  0x7fffffb, 7, 0x5f },
288
        { 27,  0x7fffffb, 7, 0x5d },   { 27,  0x7fffffb, 7, 0x5b },
289
        { 27,  0x7fffffb, 7, 0x59 },   { 27,  0x7fffffb, 7, 0x57 },
290
        { 27,  0x7fffffb, 7, 0x55 },   { 27,  0x7fffffb, 7, 0x53 },
291
        { 27,  0x7fffffb, 7, 0x51 },   { 27,  0x7fffffb, 7, 0x4f },
292
        { 27,  0x7fffffb, 7, 0x4d },   { 27,  0x7fffffb, 7, 0x4b },
293
        { 27,  0x7fffffb, 7, 0x49 },   { 27,  0x7fffffb, 7, 0x47 },
294
        { 27,  0x7fffffb, 7, 0x45 },   { 27,  0x7fffffb, 7, 0x43 },
295
        { 27,  0x7fffffb, 7, 0x41 },   { 27,  0x7fffffb, 7, 0x3f },
296
        { 27,  0x7fffffb, 7, 0x3d },   { 27,  0x7fffffb, 7, 0x3b },
297
        { 27,  0x7fffffb, 7, 0x39 },   { 27,  0x7fffffb, 7, 0x37 },
298
        { 27,  0x7fffffb, 7, 0x35 },   { 27,  0x7fffffb, 7, 0x33 },
299
        { 27,  0x7fffffb, 7, 0x31 },   { 27,  0x7fffffb, 7, 0x2f },
300
        { 27,  0x7fffffb, 7, 0x2d },   { 27,  0x7fffffb, 7, 0x2b },
301
        { 27,  0x7fffffb, 7, 0x29 },   { 27,  0x7fffffb, 7, 0x27 },
302
        { 27,  0x7fffffb, 7, 0x25 },   { 27,  0x7fffffb, 7, 0x23 },
303
        { 27,  0x7fffffb, 7, 0x21 },   { 27,  0x7fffffb, 7, 0x1f },
304
        { 27,  0x7fffffb, 7, 0x1d },   { 27,  0x7fffffb, 7, 0x1b },
305
        { 27,  0x7fffffb, 7, 0x19 },   { 27,  0x7fffffb, 7, 0x17 },
306
        { 27,  0x7fffffb, 7, 0x15 },   { 27,  0x7fffffb, 7, 0x13 },
307
        { 27,  0x7fffffb, 7, 0x11 },   { 27,  0x7fffffb, 7,  0xf },
308
        { 27,  0x7fffffb, 7,  0xd },   { 27,  0x7fffffb, 7,  0xb },
309
        { 27,  0x7fffffb, 7,  0x9 },   { 27,  0x7fffffb, 7,  0x7 },
310
        { 27,  0x7fffffb, 7,  0x5 },   { 27,  0x7fffffb, 7,  0x3 },
311
        { 27,  0x7fffffb, 7,  0x1 },   { 27,  0x7fffffb, 7,  0x1 }
312
    },
313
314
    /*
315
     * prefixed with 4 zeroes
316
     */
317
    {
318
        {  8,       0xf1, 0,    0 },   { 11,      0x7e3, 0,    0 },
319
        { 11,      0x7e1, 0,    0 },   { 18,    0x3ffc7, 0,    0 },
320
        { 18,    0x3ffc5, 0,    0 },   { 18,    0x3ffc3, 0,    0 },
321
        { 18,    0x3ffc1, 0,    0 },   { 22,   0x3fff8f, 0,    0 },
322
        { 22,   0x3fff8d, 0,    0 },   { 22,   0x3fff8b, 0,    0 },
323
        { 22,   0x3fff89, 0,    0 },   { 22,   0x3fff87, 0,    0 },
324
        { 22,   0x3fff85, 0,    0 },   { 22,   0x3fff83, 0,    0 },
325
        { 22,   0x3fff81, 0,    0 },   { 26,  0x3ffff3f, 0,    0 },
326
        { 26,  0x3ffff3d, 0,    0 },   { 26,  0x3ffff3b, 0,    0 },
327
        { 26,  0x3ffff39, 0,    0 },   { 26,  0x3ffff37, 0,    0 },
328
        { 26,  0x3ffff35, 0,    0 },   { 26,  0x3ffff33, 0,    0 },
329
        { 26,  0x3ffff31, 0,    0 },   { 26,  0x3ffff2f, 0,    0 },
330
        { 26,  0x3ffff2d, 0,    0 },   { 26,  0x3ffff2b, 0,    0 },
331
        { 26,  0x3ffff29, 0,    0 },   { 26,  0x3ffff27, 0,    0 },
332
        { 26,  0x3ffff25, 0,    0 },   { 26,  0x3ffff23, 0,    0 },
333
        { 26,  0x3ffff21, 0,    0 },   { 30, 0x3ffffebf, 0,    0 },
334
        { 30, 0x3ffffebd, 0,    0 },   { 30, 0x3ffffebb, 0,    0 },
335
        { 30, 0x3ffffeb9, 0,    0 },   { 30, 0x3ffffeb7, 0,    0 },
336
        { 30, 0x3ffffeb5, 0,    0 },   { 30, 0x3ffffeb3, 0,    0 },
337
        { 30, 0x3ffffeb1, 0,    0 },   { 30, 0x3ffffeaf, 0,    0 },
338
        { 30, 0x3ffffead, 0,    0 },   { 30, 0x3ffffeab, 0,    0 },
339
        { 30, 0x3ffffea9, 0,    0 },   { 30, 0x3ffffea7, 0,    0 },
340
        { 30, 0x3ffffea5, 0,    0 },   { 30, 0x3ffffea3, 0,    0 },
341
        { 30, 0x3ffffea1, 0,    0 },   { 30, 0x3ffffe9f, 0,    0 },
342
        { 30, 0x3ffffe9d, 0,    0 },   { 30, 0x3ffffe9b, 0,    0 },
343
        { 30, 0x3ffffe99, 0,    0 },   { 30, 0x3ffffe97, 0,    0 },
344
        { 30, 0x3ffffe95, 0,    0 },   { 30, 0x3ffffe93, 0,    0 },
345
        { 30, 0x3ffffe91, 0,    0 },   { 30, 0x3ffffe8f, 0,    0 },
346
        { 30, 0x3ffffe8d, 0,    0 },   { 30, 0x3ffffe8b, 0,    0 },
347
        { 30, 0x3ffffe89, 0,    0 },   { 30, 0x3ffffe87, 0,    0 },
348
        { 30, 0x3ffffe85, 0,    0 },   { 30, 0x3ffffe83, 0,    0 },
349
        { 30, 0x3ffffe81, 0,    0 },   { 28,  0xffffff8, 7, 0x7f },
350
        { 28,  0xffffff8, 7, 0x7d },   { 28,  0xffffff8, 7, 0x7b },
351
        { 28,  0xffffff8, 7, 0x79 },   { 28,  0xffffff8, 7, 0x77 },
352
        { 28,  0xffffff8, 7, 0x75 },   { 28,  0xffffff8, 7, 0x73 },
353
        { 28,  0xffffff8, 7, 0x71 },   { 28,  0xffffff8, 7, 0x6f },
354
        { 28,  0xffffff8, 7, 0x6d },   { 28,  0xffffff8, 7, 0x6b },
355
        { 28,  0xffffff8, 7, 0x69 },   { 28,  0xffffff8, 7, 0x67 },
356
        { 28,  0xffffff8, 7, 0x65 },   { 28,  0xffffff8, 7, 0x63 },
357
        { 28,  0xffffff8, 7, 0x61 },   { 28,  0xffffff8, 7, 0x5f },
358
        { 28,  0xffffff8, 7, 0x5d },   { 28,  0xffffff8, 7, 0x5b },
359
        { 28,  0xffffff8, 7, 0x59 },   { 28,  0xffffff8, 7, 0x57 },
360
        { 28,  0xffffff8, 7, 0x55 },   { 28,  0xffffff8, 7, 0x53 },
361
        { 28,  0xffffff8, 7, 0x51 },   { 28,  0xffffff8, 7, 0x4f },
362
        { 28,  0xffffff8, 7, 0x4d },   { 28,  0xffffff8, 7, 0x4b },
363
        { 28,  0xffffff8, 7, 0x49 },   { 28,  0xffffff8, 7, 0x47 },
364
        { 28,  0xffffff8, 7, 0x45 },   { 28,  0xffffff8, 7, 0x43 },
365
        { 28,  0xffffff8, 7, 0x41 },   { 28,  0xffffff8, 7, 0x3f },
366
        { 28,  0xffffff8, 7, 0x3d },   { 28,  0xffffff8, 7, 0x3b },
367
        { 28,  0xffffff8, 7, 0x39 },   { 28,  0xffffff8, 7, 0x37 },
368
        { 28,  0xffffff8, 7, 0x35 },   { 28,  0xffffff8, 7, 0x33 },
369
        { 28,  0xffffff8, 7, 0x31 },   { 28,  0xffffff8, 7, 0x2f },
370
        { 28,  0xffffff8, 7, 0x2d },   { 28,  0xffffff8, 7, 0x2b },
371
        { 28,  0xffffff8, 7, 0x29 },   { 28,  0xffffff8, 7, 0x27 },
372
        { 28,  0xffffff8, 7, 0x25 },   { 28,  0xffffff8, 7, 0x23 },
373
        { 28,  0xffffff8, 7, 0x21 },   { 28,  0xffffff8, 7, 0x1f },
374
        { 28,  0xffffff8, 7, 0x1d },   { 28,  0xffffff8, 7, 0x1b },
375
        { 28,  0xffffff8, 7, 0x19 },   { 28,  0xffffff8, 7, 0x17 },
376
        { 28,  0xffffff8, 7, 0x15 },   { 28,  0xffffff8, 7, 0x13 },
377
        { 28,  0xffffff8, 7, 0x11 },   { 28,  0xffffff8, 7,  0xf },
378
        { 28,  0xffffff8, 7,  0xd },   { 28,  0xffffff8, 7,  0xb },
379
        { 28,  0xffffff8, 7,  0x9 },   { 28,  0xffffff8, 7,  0x7 },
380
        { 28,  0xffffff8, 7,  0x5 },   { 28,  0xffffff8, 7,  0x3 },
381
        { 28,  0xffffff8, 7,  0x1 },   {  0,          0, 0,    0 }
382
    },
383
384
    /*
385
     * prefixed with 5 zeroes
386
     */
387
    {
388
        {  8,       0xf3, 0,    0 },   { 11,      0x7e7, 0,    0 },
389
        { 11,      0x7e5, 0,    0 },   { 18,    0x3ffcf, 0,    0 },
390
        { 18,    0x3ffcd, 0,    0 },   { 18,    0x3ffcb, 0,    0 },
391
        { 18,    0x3ffc9, 0,    0 },   { 22,   0x3fff9f, 0,    0 },
392
        { 22,   0x3fff9d, 0,    0 },   { 22,   0x3fff9b, 0,    0 },
393
        { 22,   0x3fff99, 0,    0 },   { 22,   0x3fff97, 0,    0 },
394
        { 22,   0x3fff95, 0,    0 },   { 22,   0x3fff93, 0,    0 },
395
        { 22,   0x3fff91, 0,    0 },   { 26,  0x3ffff5f, 0,    0 },
396
        { 26,  0x3ffff5d, 0,    0 },   { 26,  0x3ffff5b, 0,    0 },
397
        { 26,  0x3ffff59, 0,    0 },   { 26,  0x3ffff57, 0,    0 },
398
        { 26,  0x3ffff55, 0,    0 },   { 26,  0x3ffff53, 0,    0 },
399
        { 26,  0x3ffff51, 0,    0 },   { 26,  0x3ffff4f, 0,    0 },
400
        { 26,  0x3ffff4d, 0,    0 },   { 26,  0x3ffff4b, 0,    0 },
401
        { 26,  0x3ffff49, 0,    0 },   { 26,  0x3ffff47, 0,    0 },
402
        { 26,  0x3ffff45, 0,    0 },   { 26,  0x3ffff43, 0,    0 },
403
        { 26,  0x3ffff41, 0,    0 },   { 30, 0x3ffffeff, 0,    0 },
404
        { 30, 0x3ffffefd, 0,    0 },   { 30, 0x3ffffefb, 0,    0 },
405
        { 30, 0x3ffffef9, 0,    0 },   { 30, 0x3ffffef7, 0,    0 },
406
        { 30, 0x3ffffef5, 0,    0 },   { 30, 0x3ffffef3, 0,    0 },
407
        { 30, 0x3ffffef1, 0,    0 },   { 30, 0x3ffffeef, 0,    0 },
408
        { 30, 0x3ffffeed, 0,    0 },   { 30, 0x3ffffeeb, 0,    0 },
409
        { 30, 0x3ffffee9, 0,    0 },   { 30, 0x3ffffee7, 0,    0 },
410
        { 30, 0x3ffffee5, 0,    0 },   { 30, 0x3ffffee3, 0,    0 },
411
        { 30, 0x3ffffee1, 0,    0 },   { 30, 0x3ffffedf, 0,    0 },
412
        { 30, 0x3ffffedd, 0,    0 },   { 30, 0x3ffffedb, 0,    0 },
413
        { 30, 0x3ffffed9, 0,    0 },   { 30, 0x3ffffed7, 0,    0 },
414
        { 30, 0x3ffffed5, 0,    0 },   { 30, 0x3ffffed3, 0,    0 },
415
        { 30, 0x3ffffed1, 0,    0 },   { 30, 0x3ffffecf, 0,    0 },
416
        { 30, 0x3ffffecd, 0,    0 },   { 30, 0x3ffffecb, 0,    0 },
417
        { 30, 0x3ffffec9, 0,    0 },   { 30, 0x3ffffec7, 0,    0 },
418
        { 30, 0x3ffffec5, 0,    0 },   { 30, 0x3ffffec3, 0,    0 },
419
        { 30, 0x3ffffec1, 0,    0 },   { 28,  0xffffff9, 7, 0x7f },
420
        { 28,  0xffffff9, 7, 0x7d },   { 28,  0xffffff9, 7, 0x7b },
421
        { 28,  0xffffff9, 7, 0x79 },   { 28,  0xffffff9, 7, 0x77 },
422
        { 28,  0xffffff9, 7, 0x75 },   { 28,  0xffffff9, 7, 0x73 },
423
        { 28,  0xffffff9, 7, 0x71 },   { 28,  0xffffff9, 7, 0x6f },
424
        { 28,  0xffffff9, 7, 0x6d },   { 28,  0xffffff9, 7, 0x6b },
425
        { 28,  0xffffff9, 7, 0x69 },   { 28,  0xffffff9, 7, 0x67 },
426
        { 28,  0xffffff9, 7, 0x65 },   { 28,  0xffffff9, 7, 0x63 },
427
        { 28,  0xffffff9, 7, 0x61 },   { 28,  0xffffff9, 7, 0x5f },
428
        { 28,  0xffffff9, 7, 0x5d },   { 28,  0xffffff9, 7, 0x5b },
429
        { 28,  0xffffff9, 7, 0x59 },   { 28,  0xffffff9, 7, 0x57 },
430
        { 28,  0xffffff9, 7, 0x55 },   { 28,  0xffffff9, 7, 0x53 },
431
        { 28,  0xffffff9, 7, 0x51 },   { 28,  0xffffff9, 7, 0x4f },
432
        { 28,  0xffffff9, 7, 0x4d },   { 28,  0xffffff9, 7, 0x4b },
433
        { 28,  0xffffff9, 7, 0x49 },   { 28,  0xffffff9, 7, 0x47 },
434
        { 28,  0xffffff9, 7, 0x45 },   { 28,  0xffffff9, 7, 0x43 },
435
        { 28,  0xffffff9, 7, 0x41 },   { 28,  0xffffff9, 7, 0x3f },
436
        { 28,  0xffffff9, 7, 0x3d },   { 28,  0xffffff9, 7, 0x3b },
437
        { 28,  0xffffff9, 7, 0x39 },   { 28,  0xffffff9, 7, 0x37 },
438
        { 28,  0xffffff9, 7, 0x35 },   { 28,  0xffffff9, 7, 0x33 },
439
        { 28,  0xffffff9, 7, 0x31 },   { 28,  0xffffff9, 7, 0x2f },
440
        { 28,  0xffffff9, 7, 0x2d },   { 28,  0xffffff9, 7, 0x2b },
441
        { 28,  0xffffff9, 7, 0x29 },   { 28,  0xffffff9, 7, 0x27 },
442
        { 28,  0xffffff9, 7, 0x25 },   { 28,  0xffffff9, 7, 0x23 },
443
        { 28,  0xffffff9, 7, 0x21 },   { 28,  0xffffff9, 7, 0x1f },
444
        { 28,  0xffffff9, 7, 0x1d },   { 28,  0xffffff9, 7, 0x1b },
445
        { 28,  0xffffff9, 7, 0x19 },   { 28,  0xffffff9, 7, 0x17 },
446
        { 28,  0xffffff9, 7, 0x15 },   { 28,  0xffffff9, 7, 0x13 },
447
        { 28,  0xffffff9, 7, 0x11 },   { 28,  0xffffff9, 7,  0xf },
448
        { 28,  0xffffff9, 7,  0xd },   { 28,  0xffffff9, 7,  0xb },
449
        { 28,  0xffffff9, 7,  0x9 },   { 28,  0xffffff9, 7,  0x7 },
450
        { 28,  0xffffff9, 7,  0x5 },   { 28,  0xffffff9, 7,  0x3 },
451
        { 28,  0xffffff9, 7,  0x1 },   {  0,          0, 0,    0 }
452
    },
453
454
    /*
455
     * prefixed with 6 zeroes
456
     */
457
    {
458
        {  8,       0xf5, 0,    0 },   { 14,     0x3feb, 0,    0 },
459
        { 14,     0x3fe9, 0,    0 },   { 18,    0x3ffd7, 0,    0 },
460
        { 18,    0x3ffd5, 0,    0 },   { 18,    0x3ffd3, 0,    0 },
461
        { 18,    0x3ffd1, 0,    0 },   { 22,   0x3fffaf, 0,    0 },
462
        { 22,   0x3fffad, 0,    0 },   { 22,   0x3fffab, 0,    0 },
463
        { 22,   0x3fffa9, 0,    0 },   { 22,   0x3fffa7, 0,    0 },
464
        { 22,   0x3fffa5, 0,    0 },   { 22,   0x3fffa3, 0,    0 },
465
        { 22,   0x3fffa1, 0,    0 },   { 26,  0x3ffff7f, 0,    0 },
466
        { 26,  0x3ffff7d, 0,    0 },   { 26,  0x3ffff7b, 0,    0 },
467
        { 26,  0x3ffff79, 0,    0 },   { 26,  0x3ffff77, 0,    0 },
468
        { 26,  0x3ffff75, 0,    0 },   { 26,  0x3ffff73, 0,    0 },
469
        { 26,  0x3ffff71, 0,    0 },   { 26,  0x3ffff6f, 0,    0 },
470
        { 26,  0x3ffff6d, 0,    0 },   { 26,  0x3ffff6b, 0,    0 },
471
        { 26,  0x3ffff69, 0,    0 },   { 26,  0x3ffff67, 0,    0 },
472
        { 26,  0x3ffff65, 0,    0 },   { 26,  0x3ffff63, 0,    0 },
473
        { 26,  0x3ffff61, 0,    0 },   { 31, 0x7ffffe3f, 0,    0 },
474
        { 31, 0x7ffffe3d, 0,    0 },   { 31, 0x7ffffe3b, 0,    0 },
475
        { 31, 0x7ffffe39, 0,    0 },   { 31, 0x7ffffe37, 0,    0 },
476
        { 31, 0x7ffffe35, 0,    0 },   { 31, 0x7ffffe33, 0,    0 },
477
        { 31, 0x7ffffe31, 0,    0 },   { 31, 0x7ffffe2f, 0,    0 },
478
        { 31, 0x7ffffe2d, 0,    0 },   { 31, 0x7ffffe2b, 0,    0 },
479
        { 31, 0x7ffffe29, 0,    0 },   { 31, 0x7ffffe27, 0,    0 },
480
        { 31, 0x7ffffe25, 0,    0 },   { 31, 0x7ffffe23, 0,    0 },
481
        { 31, 0x7ffffe21, 0,    0 },   { 31, 0x7ffffe1f, 0,    0 },
482
        { 31, 0x7ffffe1d, 0,    0 },   { 31, 0x7ffffe1b, 0,    0 },
483
        { 31, 0x7ffffe19, 0,    0 },   { 31, 0x7ffffe17, 0,    0 },
484
        { 31, 0x7ffffe15, 0,    0 },   { 31, 0x7ffffe13, 0,    0 },
485
        { 31, 0x7ffffe11, 0,    0 },   { 31, 0x7ffffe0f, 0,    0 },
486
        { 31, 0x7ffffe0d, 0,    0 },   { 31, 0x7ffffe0b, 0,    0 },
487
        { 31, 0x7ffffe09, 0,    0 },   { 31, 0x7ffffe07, 0,    0 },
488
        { 31, 0x7ffffe05, 0,    0 },   { 31, 0x7ffffe03, 0,    0 },
489
        { 31, 0x7ffffe01, 0,    0 },   { 28,  0xffffffa, 7, 0x7f },
490
        { 28,  0xffffffa, 7, 0x7d },   { 28,  0xffffffa, 7, 0x7b },
491
        { 28,  0xffffffa, 7, 0x79 },   { 28,  0xffffffa, 7, 0x77 },
492
        { 28,  0xffffffa, 7, 0x75 },   { 28,  0xffffffa, 7, 0x73 },
493
        { 28,  0xffffffa, 7, 0x71 },   { 28,  0xffffffa, 7, 0x6f },
494
        { 28,  0xffffffa, 7, 0x6d },   { 28,  0xffffffa, 7, 0x6b },
495
        { 28,  0xffffffa, 7, 0x69 },   { 28,  0xffffffa, 7, 0x67 },
496
        { 28,  0xffffffa, 7, 0x65 },   { 28,  0xffffffa, 7, 0x63 },
497
        { 28,  0xffffffa, 7, 0x61 },   { 28,  0xffffffa, 7, 0x5f },
498
        { 28,  0xffffffa, 7, 0x5d },   { 28,  0xffffffa, 7, 0x5b },
499
        { 28,  0xffffffa, 7, 0x59 },   { 28,  0xffffffa, 7, 0x57 },
500
        { 28,  0xffffffa, 7, 0x55 },   { 28,  0xffffffa, 7, 0x53 },
501
        { 28,  0xffffffa, 7, 0x51 },   { 28,  0xffffffa, 7, 0x4f },
502
        { 28,  0xffffffa, 7, 0x4d },   { 28,  0xffffffa, 7, 0x4b },
503
        { 28,  0xffffffa, 7, 0x49 },   { 28,  0xffffffa, 7, 0x47 },
504
        { 28,  0xffffffa, 7, 0x45 },   { 28,  0xffffffa, 7, 0x43 },
505
        { 28,  0xffffffa, 7, 0x41 },   { 28,  0xffffffa, 7, 0x3f },
506
        { 28,  0xffffffa, 7, 0x3d },   { 28,  0xffffffa, 7, 0x3b },
507
        { 28,  0xffffffa, 7, 0x39 },   { 28,  0xffffffa, 7, 0x37 },
508
        { 28,  0xffffffa, 7, 0x35 },   { 28,  0xffffffa, 7, 0x33 },
509
        { 28,  0xffffffa, 7, 0x31 },   { 28,  0xffffffa, 7, 0x2f },
510
        { 28,  0xffffffa, 7, 0x2d },   { 28,  0xffffffa, 7, 0x2b },
511
        { 28,  0xffffffa, 7, 0x29 },   { 28,  0xffffffa, 7, 0x27 },
512
        { 28,  0xffffffa, 7, 0x25 },   { 28,  0xffffffa, 7, 0x23 },
513
        { 28,  0xffffffa, 7, 0x21 },   { 28,  0xffffffa, 7, 0x1f },
514
        { 28,  0xffffffa, 7, 0x1d },   { 28,  0xffffffa, 7, 0x1b },
515
        { 28,  0xffffffa, 7, 0x19 },   { 28,  0xffffffa, 7, 0x17 },
516
        { 28,  0xffffffa, 7, 0x15 },   { 28,  0xffffffa, 7, 0x13 },
517
        { 28,  0xffffffa, 7, 0x11 },   { 28,  0xffffffa, 7,  0xf },
518
        { 28,  0xffffffa, 7,  0xd },   { 28,  0xffffffa, 7,  0xb },
519
        { 28,  0xffffffa, 7,  0x9 },   { 28,  0xffffffa, 7,  0x7 },
520
        { 28,  0xffffffa, 7,  0x5 },   { 28,  0xffffffa, 7,  0x3 },
521
        { 28,  0xffffffa, 7,  0x1 },   {  0,          0, 0,    0 }
522
    },
523
524
    /*
525
     * prefixed with 7 zeroes
526
     */
527
    {
528
        {  9,      0x1f3, 0,    0 },   { 14,     0x3fef, 0,    0 },
529
        { 14,     0x3fed, 0,    0 },   { 18,    0x3ffdf, 0,    0 },
530
        { 18,    0x3ffdd, 0,    0 },   { 18,    0x3ffdb, 0,    0 },
531
        { 18,    0x3ffd9, 0,    0 },   { 22,   0x3fffbf, 0,    0 },
532
        { 22,   0x3fffbd, 0,    0 },   { 22,   0x3fffbb, 0,    0 },
533
        { 22,   0x3fffb9, 0,    0 },   { 22,   0x3fffb7, 0,    0 },
534
        { 22,   0x3fffb5, 0,    0 },   { 22,   0x3fffb3, 0,    0 },
535
        { 22,   0x3fffb1, 0,    0 },   { 27,  0x7ffff1f, 0,    0 },
536
        { 27,  0x7ffff1d, 0,    0 },   { 27,  0x7ffff1b, 0,    0 },
537
        { 27,  0x7ffff19, 0,    0 },   { 27,  0x7ffff17, 0,    0 },
538
        { 27,  0x7ffff15, 0,    0 },   { 27,  0x7ffff13, 0,    0 },
539
        { 27,  0x7ffff11, 0,    0 },   { 27,  0x7ffff0f, 0,    0 },
540
        { 27,  0x7ffff0d, 0,    0 },   { 27,  0x7ffff0b, 0,    0 },
541
        { 27,  0x7ffff09, 0,    0 },   { 27,  0x7ffff07, 0,    0 },
542
        { 27,  0x7ffff05, 0,    0 },   { 27,  0x7ffff03, 0,    0 },
543
        { 27,  0x7ffff01, 0,    0 },   { 31, 0x7ffffe7f, 0,    0 },
544
        { 31, 0x7ffffe7d, 0,    0 },   { 31, 0x7ffffe7b, 0,    0 },
545
        { 31, 0x7ffffe79, 0,    0 },   { 31, 0x7ffffe77, 0,    0 },
546
        { 31, 0x7ffffe75, 0,    0 },   { 31, 0x7ffffe73, 0,    0 },
547
        { 31, 0x7ffffe71, 0,    0 },   { 31, 0x7ffffe6f, 0,    0 },
548
        { 31, 0x7ffffe6d, 0,    0 },   { 31, 0x7ffffe6b, 0,    0 },
549
        { 31, 0x7ffffe69, 0,    0 },   { 31, 0x7ffffe67, 0,    0 },
550
        { 31, 0x7ffffe65, 0,    0 },   { 31, 0x7ffffe63, 0,    0 },
551
        { 31, 0x7ffffe61, 0,    0 },   { 31, 0x7ffffe5f, 0,    0 },
552
        { 31, 0x7ffffe5d, 0,    0 },   { 31, 0x7ffffe5b, 0,    0 },
553
        { 31, 0x7ffffe59, 0,    0 },   { 31, 0x7ffffe57, 0,    0 },
554
        { 31, 0x7ffffe55, 0,    0 },   { 31, 0x7ffffe53, 0,    0 },
555
        { 31, 0x7ffffe51, 0,    0 },   { 31, 0x7ffffe4f, 0,    0 },
556
        { 31, 0x7ffffe4d, 0,    0 },   { 31, 0x7ffffe4b, 0,    0 },
557
        { 31, 0x7ffffe49, 0,    0 },   { 31, 0x7ffffe47, 0,    0 },
558
        { 31, 0x7ffffe45, 0,    0 },   { 31, 0x7ffffe43, 0,    0 },
559
        { 31, 0x7ffffe41, 0,    0 },   { 28,  0xffffffb, 7, 0x7f },
560
        { 28,  0xffffffb, 7, 0x7d },   { 28,  0xffffffb, 7, 0x7b },
561
        { 28,  0xffffffb, 7, 0x79 },   { 28,  0xffffffb, 7, 0x77 },
562
        { 28,  0xffffffb, 7, 0x75 },   { 28,  0xffffffb, 7, 0x73 },
563
        { 28,  0xffffffb, 7, 0x71 },   { 28,  0xffffffb, 7, 0x6f },
564
        { 28,  0xffffffb, 7, 0x6d },   { 28,  0xffffffb, 7, 0x6b },
565
        { 28,  0xffffffb, 7, 0x69 },   { 28,  0xffffffb, 7, 0x67 },
566
        { 28,  0xffffffb, 7, 0x65 },   { 28,  0xffffffb, 7, 0x63 },
567
        { 28,  0xffffffb, 7, 0x61 },   { 28,  0xffffffb, 7, 0x5f },
568
        { 28,  0xffffffb, 7, 0x5d },   { 28,  0xffffffb, 7, 0x5b },
569
        { 28,  0xffffffb, 7, 0x59 },   { 28,  0xffffffb, 7, 0x57 },
570
        { 28,  0xffffffb, 7, 0x55 },   { 28,  0xffffffb, 7, 0x53 },
571
        { 28,  0xffffffb, 7, 0x51 },   { 28,  0xffffffb, 7, 0x4f },
572
        { 28,  0xffffffb, 7, 0x4d },   { 28,  0xffffffb, 7, 0x4b },
573
        { 28,  0xffffffb, 7, 0x49 },   { 28,  0xffffffb, 7, 0x47 },
574
        { 28,  0xffffffb, 7, 0x45 },   { 28,  0xffffffb, 7, 0x43 },
575
        { 28,  0xffffffb, 7, 0x41 },   { 28,  0xffffffb, 7, 0x3f },
576
        { 28,  0xffffffb, 7, 0x3d },   { 28,  0xffffffb, 7, 0x3b },
577
        { 28,  0xffffffb, 7, 0x39 },   { 28,  0xffffffb, 7, 0x37 },
578
        { 28,  0xffffffb, 7, 0x35 },   { 28,  0xffffffb, 7, 0x33 },
579
        { 28,  0xffffffb, 7, 0x31 },   { 28,  0xffffffb, 7, 0x2f },
580
        { 28,  0xffffffb, 7, 0x2d },   { 28,  0xffffffb, 7, 0x2b },
581
        { 28,  0xffffffb, 7, 0x29 },   { 28,  0xffffffb, 7, 0x27 },
582
        { 28,  0xffffffb, 7, 0x25 },   { 28,  0xffffffb, 7, 0x23 },
583
        { 28,  0xffffffb, 7, 0x21 },   { 28,  0xffffffb, 7, 0x1f },
584
        { 28,  0xffffffb, 7, 0x1d },   { 28,  0xffffffb, 7, 0x1b },
585
        { 28,  0xffffffb, 7, 0x19 },   { 28,  0xffffffb, 7, 0x17 },
586
        { 28,  0xffffffb, 7, 0x15 },   { 28,  0xffffffb, 7, 0x13 },
587
        { 28,  0xffffffb, 7, 0x11 },   { 28,  0xffffffb, 7,  0xf },
588
        { 28,  0xffffffb, 7,  0xd },   { 28,  0xffffffb, 7,  0xb },
589
        { 28,  0xffffffb, 7,  0x9 },   { 28,  0xffffffb, 7,  0x7 },
590
        { 28,  0xffffffb, 7,  0x5 },   { 28,  0xffffffb, 7,  0x3 },
591
        { 28,  0xffffffb, 7,  0x1 },   {  0,          0, 0,    0 }
592
    },
593
594
    /*
595
     * prefixed with 8 zeroes
596
     */
597
    {
598
        {  9,      0x1f5, 0,    0 },   { 15,     0x7fe3, 0,    0 },
599
        { 15,     0x7fe1, 0,    0 },   { 19,    0x7ffc7, 0,    0 },
600
        { 19,    0x7ffc5, 0,    0 },   { 19,    0x7ffc3, 0,    0 },
601
        { 19,    0x7ffc1, 0,    0 },   { 23,   0x7fff8f, 0,    0 },
602
        { 23,   0x7fff8d, 0,    0 },   { 23,   0x7fff8b, 0,    0 },
603
        { 23,   0x7fff89, 0,    0 },   { 23,   0x7fff87, 0,    0 },
604
        { 23,   0x7fff85, 0,    0 },   { 23,   0x7fff83, 0,    0 },
605
        { 23,   0x7fff81, 0,    0 },   { 27,  0x7ffff3f, 0,    0 },
606
        { 27,  0x7ffff3d, 0,    0 },   { 27,  0x7ffff3b, 0,    0 },
607
        { 27,  0x7ffff39, 0,    0 },   { 27,  0x7ffff37, 0,    0 },
608
        { 27,  0x7ffff35, 0,    0 },   { 27,  0x7ffff33, 0,    0 },
609
        { 27,  0x7ffff31, 0,    0 },   { 27,  0x7ffff2f, 0,    0 },
610
        { 27,  0x7ffff2d, 0,    0 },   { 27,  0x7ffff2b, 0,    0 },
611
        { 27,  0x7ffff29, 0,    0 },   { 27,  0x7ffff27, 0,    0 },
612
        { 27,  0x7ffff25, 0,    0 },   { 27,  0x7ffff23, 0,    0 },
613
        { 27,  0x7ffff21, 0,    0 },   { 31, 0x7ffffebf, 0,    0 },
614
        { 31, 0x7ffffebd, 0,    0 },   { 31, 0x7ffffebb, 0,    0 },
615
        { 31, 0x7ffffeb9, 0,    0 },   { 31, 0x7ffffeb7, 0,    0 },
616
        { 31, 0x7ffffeb5, 0,    0 },   { 31, 0x7ffffeb3, 0,    0 },
617
        { 31, 0x7ffffeb1, 0,    0 },   { 31, 0x7ffffeaf, 0,    0 },
618
        { 31, 0x7ffffead, 0,    0 },   { 31, 0x7ffffeab, 0,    0 },
619
        { 31, 0x7ffffea9, 0,    0 },   { 31, 0x7ffffea7, 0,    0 },
620
        { 31, 0x7ffffea5, 0,    0 },   { 31, 0x7ffffea3, 0,    0 },
621
        { 31, 0x7ffffea1, 0,    0 },   { 31, 0x7ffffe9f, 0,    0 },
622
        { 31, 0x7ffffe9d, 0,    0 },   { 31, 0x7ffffe9b, 0,    0 },
623
        { 31, 0x7ffffe99, 0,    0 },   { 31, 0x7ffffe97, 0,    0 },
624
        { 31, 0x7ffffe95, 0,    0 },   { 31, 0x7ffffe93, 0,    0 },
625
        { 31, 0x7ffffe91, 0,    0 },   { 31, 0x7ffffe8f, 0,    0 },
626
        { 31, 0x7ffffe8d, 0,    0 },   { 31, 0x7ffffe8b, 0,    0 },
627
        { 31, 0x7ffffe89, 0,    0 },   { 31, 0x7ffffe87, 0,    0 },
628
        { 31, 0x7ffffe85, 0,    0 },   { 31, 0x7ffffe83, 0,    0 },
629
        { 31, 0x7ffffe81, 0,    0 },   { 29, 0x1ffffff8, 7, 0x7f },
630
        { 29, 0x1ffffff8, 7, 0x7d },   { 29, 0x1ffffff8, 7, 0x7b },
631
        { 29, 0x1ffffff8, 7, 0x79 },   { 29, 0x1ffffff8, 7, 0x77 },
632
        { 29, 0x1ffffff8, 7, 0x75 },   { 29, 0x1ffffff8, 7, 0x73 },
633
        { 29, 0x1ffffff8, 7, 0x71 },   { 29, 0x1ffffff8, 7, 0x6f },
634
        { 29, 0x1ffffff8, 7, 0x6d },   { 29, 0x1ffffff8, 7, 0x6b },
635
        { 29, 0x1ffffff8, 7, 0x69 },   { 29, 0x1ffffff8, 7, 0x67 },
636
        { 29, 0x1ffffff8, 7, 0x65 },   { 29, 0x1ffffff8, 7, 0x63 },
637
        { 29, 0x1ffffff8, 7, 0x61 },   { 29, 0x1ffffff8, 7, 0x5f },
638
        { 29, 0x1ffffff8, 7, 0x5d },   { 29, 0x1ffffff8, 7, 0x5b },
639
        { 29, 0x1ffffff8, 7, 0x59 },   { 29, 0x1ffffff8, 7, 0x57 },
640
        { 29, 0x1ffffff8, 7, 0x55 },   { 29, 0x1ffffff8, 7, 0x53 },
641
        { 29, 0x1ffffff8, 7, 0x51 },   { 29, 0x1ffffff8, 7, 0x4f },
642
        { 29, 0x1ffffff8, 7, 0x4d },   { 29, 0x1ffffff8, 7, 0x4b },
643
        { 29, 0x1ffffff8, 7, 0x49 },   { 29, 0x1ffffff8, 7, 0x47 },
644
        { 29, 0x1ffffff8, 7, 0x45 },   { 29, 0x1ffffff8, 7, 0x43 },
645
        { 29, 0x1ffffff8, 7, 0x41 },   { 29, 0x1ffffff8, 7, 0x3f },
646
        { 29, 0x1ffffff8, 7, 0x3d },   { 29, 0x1ffffff8, 7, 0x3b },
647
        { 29, 0x1ffffff8, 7, 0x39 },   { 29, 0x1ffffff8, 7, 0x37 },
648
        { 29, 0x1ffffff8, 7, 0x35 },   { 29, 0x1ffffff8, 7, 0x33 },
649
        { 29, 0x1ffffff8, 7, 0x31 },   { 29, 0x1ffffff8, 7, 0x2f },
650
        { 29, 0x1ffffff8, 7, 0x2d },   { 29, 0x1ffffff8, 7, 0x2b },
651
        { 29, 0x1ffffff8, 7, 0x29 },   { 29, 0x1ffffff8, 7, 0x27 },
652
        { 29, 0x1ffffff8, 7, 0x25 },   { 29, 0x1ffffff8, 7, 0x23 },
653
        { 29, 0x1ffffff8, 7, 0x21 },   { 29, 0x1ffffff8, 7, 0x1f },
654
        { 29, 0x1ffffff8, 7, 0x1d },   { 29, 0x1ffffff8, 7, 0x1b },
655
        { 29, 0x1ffffff8, 7, 0x19 },   { 29, 0x1ffffff8, 7, 0x17 },
656
        { 29, 0x1ffffff8, 7, 0x15 },   { 29, 0x1ffffff8, 7, 0x13 },
657
        { 29, 0x1ffffff8, 7, 0x11 },   { 29, 0x1ffffff8, 7,  0xf },
658
        { 29, 0x1ffffff8, 7,  0xd },   { 29, 0x1ffffff8, 7,  0xb },
659
        { 29, 0x1ffffff8, 7,  0x9 },   { 29, 0x1ffffff8, 7,  0x7 },
660
        { 29, 0x1ffffff8, 7,  0x5 },   { 29, 0x1ffffff8, 7,  0x3 },
661
        { 29, 0x1ffffff8, 7,  0x1 },   {  0,          0, 0,    0 }
662
    },
663
664
    /*
665
     * prefixed with 9 zeroes
666
     */
667
    {
668
        { 11,      0x7f7, 0,    0 },   { 15,     0x7fe7, 0,    0 },
669
        { 15,     0x7fe5, 0,    0 },   { 19,    0x7ffcf, 0,    0 },
670
        { 19,    0x7ffcd, 0,    0 },   { 19,    0x7ffcb, 0,    0 },
671
        { 19,    0x7ffc9, 0,    0 },   { 23,   0x7fff9f, 0,    0 },
672
        { 23,   0x7fff9d, 0,    0 },   { 23,   0x7fff9b, 0,    0 },
673
        { 23,   0x7fff99, 0,    0 },   { 23,   0x7fff97, 0,    0 },
674
        { 23,   0x7fff95, 0,    0 },   { 23,   0x7fff93, 0,    0 },
675
        { 23,   0x7fff91, 0,    0 },   { 27,  0x7ffff5f, 0,    0 },
676
        { 27,  0x7ffff5d, 0,    0 },   { 27,  0x7ffff5b, 0,    0 },
677
        { 27,  0x7ffff59, 0,    0 },   { 27,  0x7ffff57, 0,    0 },
678
        { 27,  0x7ffff55, 0,    0 },   { 27,  0x7ffff53, 0,    0 },
679
        { 27,  0x7ffff51, 0,    0 },   { 27,  0x7ffff4f, 0,    0 },
680
        { 27,  0x7ffff4d, 0,    0 },   { 27,  0x7ffff4b, 0,    0 },
681
        { 27,  0x7ffff49, 0,    0 },   { 27,  0x7ffff47, 0,    0 },
682
        { 27,  0x7ffff45, 0,    0 },   { 27,  0x7ffff43, 0,    0 },
683
        { 27,  0x7ffff41, 0,    0 },   { 31, 0x7ffffeff, 0,    0 },
684
        { 31, 0x7ffffefd, 0,    0 },   { 31, 0x7ffffefb, 0,    0 },
685
        { 31, 0x7ffffef9, 0,    0 },   { 31, 0x7ffffef7, 0,    0 },
686
        { 31, 0x7ffffef5, 0,    0 },   { 31, 0x7ffffef3, 0,    0 },
687
        { 31, 0x7ffffef1, 0,    0 },   { 31, 0x7ffffeef, 0,    0 },
688
        { 31, 0x7ffffeed, 0,    0 },   { 31, 0x7ffffeeb, 0,    0 },
689
        { 31, 0x7ffffee9, 0,    0 },   { 31, 0x7ffffee7, 0,    0 },
690
        { 31, 0x7ffffee5, 0,    0 },   { 31, 0x7ffffee3, 0,    0 },
691
        { 31, 0x7ffffee1, 0,    0 },   { 31, 0x7ffffedf, 0,    0 },
692
        { 31, 0x7ffffedd, 0,    0 },   { 31, 0x7ffffedb, 0,    0 },
693
        { 31, 0x7ffffed9, 0,    0 },   { 31, 0x7ffffed7, 0,    0 },
694
        { 31, 0x7ffffed5, 0,    0 },   { 31, 0x7ffffed3, 0,    0 },
695
        { 31, 0x7ffffed1, 0,    0 },   { 31, 0x7ffffecf, 0,    0 },
696
        { 31, 0x7ffffecd, 0,    0 },   { 31, 0x7ffffecb, 0,    0 },
697
        { 31, 0x7ffffec9, 0,    0 },   { 31, 0x7ffffec7, 0,    0 },
698
        { 31, 0x7ffffec5, 0,    0 },   { 31, 0x7ffffec3, 0,    0 },
699
        { 31, 0x7ffffec1, 0,    0 },   { 29, 0x1ffffff9, 7, 0x7f },
700
        { 29, 0x1ffffff9, 7, 0x7d },   { 29, 0x1ffffff9, 7, 0x7b },
701
        { 29, 0x1ffffff9, 7, 0x79 },   { 29, 0x1ffffff9, 7, 0x77 },
702
        { 29, 0x1ffffff9, 7, 0x75 },   { 29, 0x1ffffff9, 7, 0x73 },
703
        { 29, 0x1ffffff9, 7, 0x71 },   { 29, 0x1ffffff9, 7, 0x6f },
704
        { 29, 0x1ffffff9, 7, 0x6d },   { 29, 0x1ffffff9, 7, 0x6b },
705
        { 29, 0x1ffffff9, 7, 0x69 },   { 29, 0x1ffffff9, 7, 0x67 },
706
        { 29, 0x1ffffff9, 7, 0x65 },   { 29, 0x1ffffff9, 7, 0x63 },
707
        { 29, 0x1ffffff9, 7, 0x61 },   { 29, 0x1ffffff9, 7, 0x5f },
708
        { 29, 0x1ffffff9, 7, 0x5d },   { 29, 0x1ffffff9, 7, 0x5b },
709
        { 29, 0x1ffffff9, 7, 0x59 },   { 29, 0x1ffffff9, 7, 0x57 },
710
        { 29, 0x1ffffff9, 7, 0x55 },   { 29, 0x1ffffff9, 7, 0x53 },
711
        { 29, 0x1ffffff9, 7, 0x51 },   { 29, 0x1ffffff9, 7, 0x4f },
712
        { 29, 0x1ffffff9, 7, 0x4d },   { 29, 0x1ffffff9, 7, 0x4b },
713
        { 29, 0x1ffffff9, 7, 0x49 },   { 29, 0x1ffffff9, 7, 0x47 },
714
        { 29, 0x1ffffff9, 7, 0x45 },   { 29, 0x1ffffff9, 7, 0x43 },
715
        { 29, 0x1ffffff9, 7, 0x41 },   { 29, 0x1ffffff9, 7, 0x3f },
716
        { 29, 0x1ffffff9, 7, 0x3d },   { 29, 0x1ffffff9, 7, 0x3b },
717
        { 29, 0x1ffffff9, 7, 0x39 },   { 29, 0x1ffffff9, 7, 0x37 },
718
        { 29, 0x1ffffff9, 7, 0x35 },   { 29, 0x1ffffff9, 7, 0x33 },
719
        { 29, 0x1ffffff9, 7, 0x31 },   { 29, 0x1ffffff9, 7, 0x2f },
720
        { 29, 0x1ffffff9, 7, 0x2d },   { 29, 0x1ffffff9, 7, 0x2b },
721
        { 29, 0x1ffffff9, 7, 0x29 },   { 29, 0x1ffffff9, 7, 0x27 },
722
        { 29, 0x1ffffff9, 7, 0x25 },   { 29, 0x1ffffff9, 7, 0x23 },
723
        { 29, 0x1ffffff9, 7, 0x21 },   { 29, 0x1ffffff9, 7, 0x1f },
724
        { 29, 0x1ffffff9, 7, 0x1d },   { 29, 0x1ffffff9, 7, 0x1b },
725
        { 29, 0x1ffffff9, 7, 0x19 },   { 29, 0x1ffffff9, 7, 0x17 },
726
        { 29, 0x1ffffff9, 7, 0x15 },   { 29, 0x1ffffff9, 7, 0x13 },
727
        { 29, 0x1ffffff9, 7, 0x11 },   { 29, 0x1ffffff9, 7,  0xf },
728
        { 29, 0x1ffffff9, 7,  0xd },   { 29, 0x1ffffff9, 7,  0xb },
729
        { 29, 0x1ffffff9, 7,  0x9 },   { 29, 0x1ffffff9, 7,  0x7 },
730
        { 29, 0x1ffffff9, 7,  0x5 },   { 29, 0x1ffffff9, 7,  0x3 },
731
        { 29, 0x1ffffff9, 7,  0x1 },   {  0,          0, 0,    0 }
732
    },
733
734
    /*
735
     * prefixed with 10 zeroes
736
     */
737
    {
738
        { 12,      0xff1, 0,    0 },   { 15,     0x7feb, 0,    0 },
739
        { 15,     0x7fe9, 0,    0 },   { 19,    0x7ffd7, 0,    0 },
740
        { 19,    0x7ffd5, 0,    0 },   { 19,    0x7ffd3, 0,    0 },
741
        { 19,    0x7ffd1, 0,    0 },   { 23,   0x7fffaf, 0,    0 },
742
        { 23,   0x7fffad, 0,    0 },   { 23,   0x7fffab, 0,    0 },
743
        { 23,   0x7fffa9, 0,    0 },   { 23,   0x7fffa7, 0,    0 },
744
        { 23,   0x7fffa5, 0,    0 },   { 23,   0x7fffa3, 0,    0 },
745
        { 23,   0x7fffa1, 0,    0 },   { 27,  0x7ffff7f, 0,    0 },
746
        { 27,  0x7ffff7d, 0,    0 },   { 27,  0x7ffff7b, 0,    0 },
747
        { 27,  0x7ffff79, 0,    0 },   { 27,  0x7ffff77, 0,    0 },
748
        { 27,  0x7ffff75, 0,    0 },   { 27,  0x7ffff73, 0,    0 },
749
        { 27,  0x7ffff71, 0,    0 },   { 27,  0x7ffff6f, 0,    0 },
750
        { 27,  0x7ffff6d, 0,    0 },   { 27,  0x7ffff6b, 0,    0 },
751
        { 27,  0x7ffff69, 0,    0 },   { 27,  0x7ffff67, 0,    0 },
752
        { 27,  0x7ffff65, 0,    0 },   { 27,  0x7ffff63, 0,    0 },
753
        { 27,  0x7ffff61, 0,    0 },   { 32, 0xfffffe3f, 0,    0 },
754
        { 32, 0xfffffe3d, 0,    0 },   { 32, 0xfffffe3b, 0,    0 },
755
        { 32, 0xfffffe39, 0,    0 },   { 32, 0xfffffe37, 0,    0 },
756
        { 32, 0xfffffe35, 0,    0 },   { 32, 0xfffffe33, 0,    0 },
757
        { 32, 0xfffffe31, 0,    0 },   { 32, 0xfffffe2f, 0,    0 },
758
        { 32, 0xfffffe2d, 0,    0 },   { 32, 0xfffffe2b, 0,    0 },
759
        { 32, 0xfffffe29, 0,    0 },   { 32, 0xfffffe27, 0,    0 },
760
        { 32, 0xfffffe25, 0,    0 },   { 32, 0xfffffe23, 0,    0 },
761
        { 32, 0xfffffe21, 0,    0 },   { 32, 0xfffffe1f, 0,    0 },
762
        { 32, 0xfffffe1d, 0,    0 },   { 32, 0xfffffe1b, 0,    0 },
763
        { 32, 0xfffffe19, 0,    0 },   { 32, 0xfffffe17, 0,    0 },
764
        { 32, 0xfffffe15, 0,    0 },   { 32, 0xfffffe13, 0,    0 },
765
        { 32, 0xfffffe11, 0,    0 },   { 32, 0xfffffe0f, 0,    0 },
766
        { 32, 0xfffffe0d, 0,    0 },   { 32, 0xfffffe0b, 0,    0 },
767
        { 32, 0xfffffe09, 0,    0 },   { 32, 0xfffffe07, 0,    0 },
768
        { 32, 0xfffffe05, 0,    0 },   { 32, 0xfffffe03, 0,    0 },
769
        { 32, 0xfffffe01, 0,    0 },   { 29, 0x1ffffffa, 7, 0x7f },
770
        { 29, 0x1ffffffa, 7, 0x7d },   { 29, 0x1ffffffa, 7, 0x7b },
771
        { 29, 0x1ffffffa, 7, 0x79 },   { 29, 0x1ffffffa, 7, 0x77 },
772
        { 29, 0x1ffffffa, 7, 0x75 },   { 29, 0x1ffffffa, 7, 0x73 },
773
        { 29, 0x1ffffffa, 7, 0x71 },   { 29, 0x1ffffffa, 7, 0x6f },
774
        { 29, 0x1ffffffa, 7, 0x6d },   { 29, 0x1ffffffa, 7, 0x6b },
775
        { 29, 0x1ffffffa, 7, 0x69 },   { 29, 0x1ffffffa, 7, 0x67 },
776
        { 29, 0x1ffffffa, 7, 0x65 },   { 29, 0x1ffffffa, 7, 0x63 },
777
        { 29, 0x1ffffffa, 7, 0x61 },   { 29, 0x1ffffffa, 7, 0x5f },
778
        { 29, 0x1ffffffa, 7, 0x5d },   { 29, 0x1ffffffa, 7, 0x5b },
779
        { 29, 0x1ffffffa, 7, 0x59 },   { 29, 0x1ffffffa, 7, 0x57 },
780
        { 29, 0x1ffffffa, 7, 0x55 },   { 29, 0x1ffffffa, 7, 0x53 },
781
        { 29, 0x1ffffffa, 7, 0x51 },   { 29, 0x1ffffffa, 7, 0x4f },
782
        { 29, 0x1ffffffa, 7, 0x4d },   { 29, 0x1ffffffa, 7, 0x4b },
783
        { 29, 0x1ffffffa, 7, 0x49 },   { 29, 0x1ffffffa, 7, 0x47 },
784
        { 29, 0x1ffffffa, 7, 0x45 },   { 29, 0x1ffffffa, 7, 0x43 },
785
        { 29, 0x1ffffffa, 7, 0x41 },   { 29, 0x1ffffffa, 7, 0x3f },
786
        { 29, 0x1ffffffa, 7, 0x3d },   { 29, 0x1ffffffa, 7, 0x3b },
787
        { 29, 0x1ffffffa, 7, 0x39 },   { 29, 0x1ffffffa, 7, 0x37 },
788
        { 29, 0x1ffffffa, 7, 0x35 },   { 29, 0x1ffffffa, 7, 0x33 },
789
        { 29, 0x1ffffffa, 7, 0x31 },   { 29, 0x1ffffffa, 7, 0x2f },
790
        { 29, 0x1ffffffa, 7, 0x2d },   { 29, 0x1ffffffa, 7, 0x2b },
791
        { 29, 0x1ffffffa, 7, 0x29 },   { 29, 0x1ffffffa, 7, 0x27 },
792
        { 29, 0x1ffffffa, 7, 0x25 },   { 29, 0x1ffffffa, 7, 0x23 },
793
        { 29, 0x1ffffffa, 7, 0x21 },   { 29, 0x1ffffffa, 7, 0x1f },
794
        { 29, 0x1ffffffa, 7, 0x1d },   { 29, 0x1ffffffa, 7, 0x1b },
795
        { 29, 0x1ffffffa, 7, 0x19 },   { 29, 0x1ffffffa, 7, 0x17 },
796
        { 29, 0x1ffffffa, 7, 0x15 },   { 29, 0x1ffffffa, 7, 0x13 },
797
        { 29, 0x1ffffffa, 7, 0x11 },   { 29, 0x1ffffffa, 7,  0xf },
798
        { 29, 0x1ffffffa, 7,  0xd },   { 29, 0x1ffffffa, 7,  0xb },
799
        { 29, 0x1ffffffa, 7,  0x9 },   { 29, 0x1ffffffa, 7,  0x7 },
800
        { 29, 0x1ffffffa, 7,  0x5 },   { 29, 0x1ffffffa, 7,  0x3 },
801
        { 29, 0x1ffffffa, 7,  0x1 },   {  0,          0, 0,    0 }
802
    },
803
804
    /*
805
     * prefixed with 11 zeroes
806
     */
807
    {
808
        { 12,      0xff3, 0,    0 },   { 15,     0x7fef, 0,    0 },
809
        { 15,     0x7fed, 0,    0 },   { 19,    0x7ffdf, 0,    0 },
810
        { 19,    0x7ffdd, 0,    0 },   { 19,    0x7ffdb, 0,    0 },
811
        { 19,    0x7ffd9, 0,    0 },   { 23,   0x7fffbf, 0,    0 },
812
        { 23,   0x7fffbd, 0,    0 },   { 23,   0x7fffbb, 0,    0 },
813
        { 23,   0x7fffb9, 0,    0 },   { 23,   0x7fffb7, 0,    0 },
814
        { 23,   0x7fffb5, 0,    0 },   { 23,   0x7fffb3, 0,    0 },
815
        { 23,   0x7fffb1, 0,    0 },   { 28,  0xfffff1f, 0,    0 },
816
        { 28,  0xfffff1d, 0,    0 },   { 28,  0xfffff1b, 0,    0 },
817
        { 28,  0xfffff19, 0,    0 },   { 28,  0xfffff17, 0,    0 },
818
        { 28,  0xfffff15, 0,    0 },   { 28,  0xfffff13, 0,    0 },
819
        { 28,  0xfffff11, 0,    0 },   { 28,  0xfffff0f, 0,    0 },
820
        { 28,  0xfffff0d, 0,    0 },   { 28,  0xfffff0b, 0,    0 },
821
        { 28,  0xfffff09, 0,    0 },   { 28,  0xfffff07, 0,    0 },
822
        { 28,  0xfffff05, 0,    0 },   { 28,  0xfffff03, 0,    0 },
823
        { 28,  0xfffff01, 0,    0 },   { 32, 0xfffffe7f, 0,    0 },
824
        { 32, 0xfffffe7d, 0,    0 },   { 32, 0xfffffe7b, 0,    0 },
825
        { 32, 0xfffffe79, 0,    0 },   { 32, 0xfffffe77, 0,    0 },
826
        { 32, 0xfffffe75, 0,    0 },   { 32, 0xfffffe73, 0,    0 },
827
        { 32, 0xfffffe71, 0,    0 },   { 32, 0xfffffe6f, 0,    0 },
828
        { 32, 0xfffffe6d, 0,    0 },   { 32, 0xfffffe6b, 0,    0 },
829
        { 32, 0xfffffe69, 0,    0 },   { 32, 0xfffffe67, 0,    0 },
830
        { 32, 0xfffffe65, 0,    0 },   { 32, 0xfffffe63, 0,    0 },
831
        { 32, 0xfffffe61, 0,    0 },   { 32, 0xfffffe5f, 0,    0 },
832
        { 32, 0xfffffe5d, 0,    0 },   { 32, 0xfffffe5b, 0,    0 },
833
        { 32, 0xfffffe59, 0,    0 },   { 32, 0xfffffe57, 0,    0 },
834
        { 32, 0xfffffe55, 0,    0 },   { 32, 0xfffffe53, 0,    0 },
835
        { 32, 0xfffffe51, 0,    0 },   { 32, 0xfffffe4f, 0,    0 },
836
        { 32, 0xfffffe4d, 0,    0 },   { 32, 0xfffffe4b, 0,    0 },
837
        { 32, 0xfffffe49, 0,    0 },   { 32, 0xfffffe47, 0,    0 },
838
        { 32, 0xfffffe45, 0,    0 },   { 32, 0xfffffe43, 0,    0 },
839
        { 32, 0xfffffe41, 0,    0 },   { 29, 0x1ffffffb, 7, 0x7f },
840
        { 29, 0x1ffffffb, 7, 0x7d },   { 29, 0x1ffffffb, 7, 0x7b },
841
        { 29, 0x1ffffffb, 7, 0x79 },   { 29, 0x1ffffffb, 7, 0x77 },
842
        { 29, 0x1ffffffb, 7, 0x75 },   { 29, 0x1ffffffb, 7, 0x73 },
843
        { 29, 0x1ffffffb, 7, 0x71 },   { 29, 0x1ffffffb, 7, 0x6f },
844
        { 29, 0x1ffffffb, 7, 0x6d },   { 29, 0x1ffffffb, 7, 0x6b },
845
        { 29, 0x1ffffffb, 7, 0x69 },   { 29, 0x1ffffffb, 7, 0x67 },
846
        { 29, 0x1ffffffb, 7, 0x65 },   { 29, 0x1ffffffb, 7, 0x63 },
847
        { 29, 0x1ffffffb, 7, 0x61 },   { 29, 0x1ffffffb, 7, 0x5f },
848
        { 29, 0x1ffffffb, 7, 0x5d },   { 29, 0x1ffffffb, 7, 0x5b },
849
        { 29, 0x1ffffffb, 7, 0x59 },   { 29, 0x1ffffffb, 7, 0x57 },
850
        { 29, 0x1ffffffb, 7, 0x55 },   { 29, 0x1ffffffb, 7, 0x53 },
851
        { 29, 0x1ffffffb, 7, 0x51 },   { 29, 0x1ffffffb, 7, 0x4f },
852
        { 29, 0x1ffffffb, 7, 0x4d },   { 29, 0x1ffffffb, 7, 0x4b },
853
        { 29, 0x1ffffffb, 7, 0x49 },   { 29, 0x1ffffffb, 7, 0x47 },
854
        { 29, 0x1ffffffb, 7, 0x45 },   { 29, 0x1ffffffb, 7, 0x43 },
855
        { 29, 0x1ffffffb, 7, 0x41 },   { 29, 0x1ffffffb, 7, 0x3f },
856
        { 29, 0x1ffffffb, 7, 0x3d },   { 29, 0x1ffffffb, 7, 0x3b },
857
        { 29, 0x1ffffffb, 7, 0x39 },   { 29, 0x1ffffffb, 7, 0x37 },
858
        { 29, 0x1ffffffb, 7, 0x35 },   { 29, 0x1ffffffb, 7, 0x33 },
859
        { 29, 0x1ffffffb, 7, 0x31 },   { 29, 0x1ffffffb, 7, 0x2f },
860
        { 29, 0x1ffffffb, 7, 0x2d },   { 29, 0x1ffffffb, 7, 0x2b },
861
        { 29, 0x1ffffffb, 7, 0x29 },   { 29, 0x1ffffffb, 7, 0x27 },
862
        { 29, 0x1ffffffb, 7, 0x25 },   { 29, 0x1ffffffb, 7, 0x23 },
863
        { 29, 0x1ffffffb, 7, 0x21 },   { 29, 0x1ffffffb, 7, 0x1f },
864
        { 29, 0x1ffffffb, 7, 0x1d },   { 29, 0x1ffffffb, 7, 0x1b },
865
        { 29, 0x1ffffffb, 7, 0x19 },   { 29, 0x1ffffffb, 7, 0x17 },
866
        { 29, 0x1ffffffb, 7, 0x15 },   { 29, 0x1ffffffb, 7, 0x13 },
867
        { 29, 0x1ffffffb, 7, 0x11 },   { 29, 0x1ffffffb, 7,  0xf },
868
        { 29, 0x1ffffffb, 7,  0xd },   { 29, 0x1ffffffb, 7,  0xb },
869
        { 29, 0x1ffffffb, 7,  0x9 },   { 29, 0x1ffffffb, 7,  0x7 },
870
        { 29, 0x1ffffffb, 7,  0x5 },   { 29, 0x1ffffffb, 7,  0x3 },
871
        { 29, 0x1ffffffb, 7,  0x1 },   {  0,          0, 0,    0 }
872
    },
873
874
    /*
875
     * prefixed with 12 zeroes
876
     */
877
    {
878
        { 12,      0xff5, 0,    0 },   { 16,     0xffe3, 0,    0 },
879
        { 16,     0xffe1, 0,    0 },   { 20,    0xfffc7, 0,    0 },
880
        { 20,    0xfffc5, 0,    0 },   { 20,    0xfffc3, 0,    0 },
881
        { 20,    0xfffc1, 0,    0 },   { 24,   0xffff8f, 0,    0 },
882
        { 24,   0xffff8d, 0,    0 },   { 24,   0xffff8b, 0,    0 },
883
        { 24,   0xffff89, 0,    0 },   { 24,   0xffff87, 0,    0 },
884
        { 24,   0xffff85, 0,    0 },   { 24,   0xffff83, 0,    0 },
885
        { 24,   0xffff81, 0,    0 },   { 28,  0xfffff3f, 0,    0 },
886
        { 28,  0xfffff3d, 0,    0 },   { 28,  0xfffff3b, 0,    0 },
887
        { 28,  0xfffff39, 0,    0 },   { 28,  0xfffff37, 0,    0 },
888
        { 28,  0xfffff35, 0,    0 },   { 28,  0xfffff33, 0,    0 },
889
        { 28,  0xfffff31, 0,    0 },   { 28,  0xfffff2f, 0,    0 },
890
        { 28,  0xfffff2d, 0,    0 },   { 28,  0xfffff2b, 0,    0 },
891
        { 28,  0xfffff29, 0,    0 },   { 28,  0xfffff27, 0,    0 },
892
        { 28,  0xfffff25, 0,    0 },   { 28,  0xfffff23, 0,    0 },
893
        { 28,  0xfffff21, 0,    0 },   { 32, 0xfffffebf, 0,    0 },
894
        { 32, 0xfffffebd, 0,    0 },   { 32, 0xfffffebb, 0,    0 },
895
        { 32, 0xfffffeb9, 0,    0 },   { 32, 0xfffffeb7, 0,    0 },
896
        { 32, 0xfffffeb5, 0,    0 },   { 32, 0xfffffeb3, 0,    0 },
897
        { 32, 0xfffffeb1, 0,    0 },   { 32, 0xfffffeaf, 0,    0 },
898
        { 32, 0xfffffead, 0,    0 },   { 32, 0xfffffeab, 0,    0 },
899
        { 32, 0xfffffea9, 0,    0 },   { 32, 0xfffffea7, 0,    0 },
900
        { 32, 0xfffffea5, 0,    0 },   { 32, 0xfffffea3, 0,    0 },
901
        { 32, 0xfffffea1, 0,    0 },   { 32, 0xfffffe9f, 0,    0 },
902
        { 32, 0xfffffe9d, 0,    0 },   { 32, 0xfffffe9b, 0,    0 },
903
        { 32, 0xfffffe99, 0,    0 },   { 32, 0xfffffe97, 0,    0 },
904
        { 32, 0xfffffe95, 0,    0 },   { 32, 0xfffffe93, 0,    0 },
905
        { 32, 0xfffffe91, 0,    0 },   { 32, 0xfffffe8f, 0,    0 },
906
        { 32, 0xfffffe8d, 0,    0 },   { 32, 0xfffffe8b, 0,    0 },
907
        { 32, 0xfffffe89, 0,    0 },   { 32, 0xfffffe87, 0,    0 },
908
        { 32, 0xfffffe85, 0,    0 },   { 32, 0xfffffe83, 0,    0 },
909
        { 32, 0xfffffe81, 0,    0 },   { 30, 0x1fff7400, 7, 0x7f },
910
        { 30, 0x1fff7400, 7, 0x7d },   { 30, 0x1fff7400, 7, 0x7b },
911
        { 30, 0x1fff7400, 7, 0x79 },   { 30, 0x1fff7400, 7, 0x77 },
912
        { 30, 0x1fff7400, 7, 0x75 },   { 30, 0x1fff7400, 7, 0x73 },
913
        { 30, 0x1fff7400, 7, 0x71 },   { 30, 0x1fff7400, 7, 0x6f },
914
        { 30, 0x1fff7400, 7, 0x6d },   { 30, 0x1fff7400, 7, 0x6b },
915
        { 30, 0x1fff7400, 7, 0x69 },   { 30, 0x1fff7400, 7, 0x67 },
916
        { 30, 0x1fff7400, 7, 0x65 },   { 30, 0x1fff7400, 7, 0x63 },
917
        { 30, 0x1fff7400, 7, 0x61 },   { 30, 0x1fff7400, 7, 0x5f },
918
        { 30, 0x1fff7400, 7, 0x5d },   { 30, 0x1fff7400, 7, 0x5b },
919
        { 30, 0x1fff7400, 7, 0x59 },   { 30, 0x1fff7400, 7, 0x57 },
920
        { 30, 0x1fff7400, 7, 0x55 },   { 30, 0x1fff7400, 7, 0x53 },
921
        { 30, 0x1fff7400, 7, 0x51 },   { 30, 0x1fff7400, 7, 0x4f },
922
        { 30, 0x1fff7400, 7, 0x4d },   { 30, 0x1fff7400, 7, 0x4b },
923
        { 30, 0x1fff7400, 7, 0x49 },   { 30, 0x1fff7400, 7, 0x47 },
924
        { 30, 0x1fff7400, 7, 0x45 },   { 30, 0x1fff7400, 7, 0x43 },
925
        { 30, 0x1fff7400, 7, 0x41 },   { 30, 0x1fff7400, 7, 0x3f },
926
        { 30, 0x1fff7400, 7, 0x3d },   { 30, 0x1fff7400, 7, 0x3b },
927
        { 30, 0x1fff7400, 7, 0x39 },   { 30, 0x1fff7400, 7, 0x37 },
928
        { 30, 0x1fff7400, 7, 0x35 },   { 30, 0x1fff7400, 7, 0x33 },
929
        { 30, 0x1fff7400, 7, 0x31 },   { 30, 0x1fff7400, 7, 0x2f },
930
        { 30, 0x1fff7400, 7, 0x2d },   { 30, 0x1fff7400, 7, 0x2b },
931
        { 30, 0x1fff7400, 7, 0x29 },   { 30, 0x1fff7400, 7, 0x27 },
932
        { 30, 0x1fff7400, 7, 0x25 },   { 30, 0x1fff7400, 7, 0x23 },
933
        { 30, 0x1fff7400, 7, 0x21 },   { 30, 0x1fff7400, 7, 0x1f },
934
        { 30, 0x1fff7400, 7, 0x1d },   { 30, 0x1fff7400, 7, 0x1b },
935
        { 30, 0x1fff7400, 7, 0x19 },   { 30, 0x1fff7400, 7, 0x17 },
936
        { 30, 0x1fff7400, 7, 0x15 },   { 30, 0x1fff7400, 7, 0x13 },
937
        { 30, 0x1fff7400, 7, 0x11 },   { 30, 0x1fff7400, 7,  0xf },
938
        { 30, 0x1fff7400, 7,  0xd },   { 30, 0x1fff7400, 7,  0xb },
939
        { 30, 0x1fff7400, 7,  0x9 },   { 30, 0x1fff7400, 7,  0x7 },
940
        { 30, 0x1fff7400, 7,  0x5 },   { 30, 0x1fff7400, 7,  0x3 },
941
        { 30, 0x1fff7400, 7,  0x1 },   {  0,          0, 0,    0 }
942
    },
943
944
    /*
945
     * prefixed with 13 zeroes
946
     */
947
    {
948
        { 12,      0xff7, 0,    0 },   { 16,     0xffe7, 0,    0 },
949
        { 16,     0xffe5, 0,    0 },   { 20,    0xfffcf, 0,    0 },
950
        { 20,    0xfffcd, 0,    0 },   { 20,    0xfffcb, 0,    0 },
951
        { 20,    0xfffc9, 0,    0 },   { 24,   0xffff9f, 0,    0 },
952
        { 24,   0xffff9d, 0,    0 },   { 24,   0xffff9b, 0,    0 },
953
        { 24,   0xffff99, 0,    0 },   { 24,   0xffff97, 0,    0 },
954
        { 24,   0xffff95, 0,    0 },   { 24,   0xffff93, 0,    0 },
955
        { 24,   0xffff91, 0,    0 },   { 28,  0xfffff5f, 0,    0 },
956
        { 28,  0xfffff5d, 0,    0 },   { 28,  0xfffff5b, 0,    0 },
957
        { 28,  0xfffff59, 0,    0 },   { 28,  0xfffff57, 0,    0 },
958
        { 28,  0xfffff55, 0,    0 },   { 28,  0xfffff53, 0,    0 },
959
        { 28,  0xfffff51, 0,    0 },   { 28,  0xfffff4f, 0,    0 },
960
        { 28,  0xfffff4d, 0,    0 },   { 28,  0xfffff4b, 0,    0 },
961
        { 28,  0xfffff49, 0,    0 },   { 28,  0xfffff47, 0,    0 },
962
        { 28,  0xfffff45, 0,    0 },   { 28,  0xfffff43, 0,    0 },
963
        { 28,  0xfffff41, 0,    0 },   { 32, 0xfffffeff, 0,    0 },
964
        { 32, 0xfffffefd, 0,    0 },   { 32, 0xfffffefb, 0,    0 },
965
        { 32, 0xfffffef9, 0,    0 },   { 32, 0xfffffef7, 0,    0 },
966
        { 32, 0xfffffef5, 0,    0 },   { 32, 0xfffffef3, 0,    0 },
967
        { 32, 0xfffffef1, 0,    0 },   { 32, 0xfffffeef, 0,    0 },
968
        { 32, 0xfffffeed, 0,    0 },   { 32, 0xfffffeeb, 0,    0 },
969
        { 32, 0xfffffee9, 0,    0 },   { 32, 0xfffffee7, 0,    0 },
970
        { 32, 0xfffffee5, 0,    0 },   { 32, 0xfffffee3, 0,    0 },
971
        { 32, 0xfffffee1, 0,    0 },   { 32, 0xfffffedf, 0,    0 },
972
        { 32, 0xfffffedd, 0,    0 },   { 32, 0xfffffedb, 0,    0 },
973
        { 32, 0xfffffed9, 0,    0 },   { 32, 0xfffffed7, 0,    0 },
974
        { 32, 0xfffffed5, 0,    0 },   { 32, 0xfffffed3, 0,    0 },
975
        { 32, 0xfffffed1, 0,    0 },   { 32, 0xfffffecf, 0,    0 },
976
        { 32, 0xfffffecd, 0,    0 },   { 32, 0xfffffecb, 0,    0 },
977
        { 32, 0xfffffec9, 0,    0 },   { 32, 0xfffffec7, 0,    0 },
978
        { 32, 0xfffffec5, 0,    0 },   { 32, 0xfffffec3, 0,    0 },
979
        { 32, 0xfffffec1, 0,    0 },   { 30, 0x3ffffff9, 7, 0x7f },
980
        { 30, 0x3ffffff9, 7, 0x7d },   { 30, 0x3ffffff9, 7, 0x7b },
981
        { 30, 0x3ffffff9, 7, 0x79 },   { 30, 0x3ffffff9, 7, 0x77 },
982
        { 30, 0x3ffffff9, 7, 0x75 },   { 30, 0x3ffffff9, 7, 0x73 },
983
        { 30, 0x3ffffff9, 7, 0x71 },   { 30, 0x3ffffff9, 7, 0x6f },
984
        { 30, 0x3ffffff9, 7, 0x6d },   { 30, 0x3ffffff9, 7, 0x6b },
985
        { 30, 0x3ffffff9, 7, 0x69 },   { 30, 0x3ffffff9, 7, 0x67 },
986
        { 30, 0x3ffffff9, 7, 0x65 },   { 30, 0x3ffffff9, 7, 0x63 },
987
        { 30, 0x3ffffff9, 7, 0x61 },   { 30, 0x3ffffff9, 7, 0x5f },
988
        { 30, 0x3ffffff9, 7, 0x5d },   { 30, 0x3ffffff9, 7, 0x5b },
989
        { 30, 0x3ffffff9, 7, 0x59 },   { 30, 0x3ffffff9, 7, 0x57 },
990
        { 30, 0x3ffffff9, 7, 0x55 },   { 30, 0x3ffffff9, 7, 0x53 },
991
        { 30, 0x3ffffff9, 7, 0x51 },   { 30, 0x3ffffff9, 7, 0x4f },
992
        { 30, 0x3ffffff9, 7, 0x4d },   { 30, 0x3ffffff9, 7, 0x4b },
993
        { 30, 0x3ffffff9, 7, 0x49 },   { 30, 0x3ffffff9, 7, 0x47 },
994
        { 30, 0x3ffffff9, 7, 0x45 },   { 30, 0x3ffffff9, 7, 0x43 },
995
        { 30, 0x3ffffff9, 7, 0x41 },   { 30, 0x3ffffff9, 7, 0x3f },
996
        { 30, 0x3ffffff9, 7, 0x3d },   { 30, 0x3ffffff9, 7, 0x3b },
997
        { 30, 0x3ffffff9, 7, 0x39 },   { 30, 0x3ffffff9, 7, 0x37 },
998
        { 30, 0x3ffffff9, 7, 0x35 },   { 30, 0x3ffffff9, 7, 0x33 },
999
        { 30, 0x3ffffff9, 7, 0x31 },   { 30, 0x3ffffff9, 7, 0x2f },
1000
        { 30, 0x3ffffff9, 7, 0x2d },   { 30, 0x3ffffff9, 7, 0x2b },
1001
        { 30, 0x3ffffff9, 7, 0x29 },   { 30, 0x3ffffff9, 7, 0x27 },
1002
        { 30, 0x3ffffff9, 7, 0x25 },   { 30, 0x3ffffff9, 7, 0x23 },
1003
        { 30, 0x3ffffff9, 7, 0x21 },   { 30, 0x3ffffff9, 7, 0x1f },
1004
        { 30, 0x3ffffff9, 7, 0x1d },   { 30, 0x3ffffff9, 7, 0x1b },
1005
        { 30, 0x3ffffff9, 7, 0x19 },   { 30, 0x3ffffff9, 7, 0x17 },
1006
        { 30, 0x3ffffff9, 7, 0x15 },   { 30, 0x3ffffff9, 7, 0x13 },
1007
        { 30, 0x3ffffff9, 7, 0x11 },   { 30, 0x3ffffff9, 7,  0xf },
1008
        { 30, 0x3ffffff9, 7,  0xd },   { 30, 0x3ffffff9, 7,  0xb },
1009
        { 30, 0x3ffffff9, 7,  0x9 },   { 30, 0x3ffffff9, 7,  0x7 },
1010
        { 30, 0x3ffffff9, 7,  0x5 },   { 30, 0x3ffffff9, 7,  0x3 },
1011
        { 30, 0x3ffffff9, 7,  0x1 },   {  0,          0, 0,    0 }
1012
    },
1013
1014
    /*
1015
     * prefixed with 14 zeroes
1016
     */
1017
    {
1018
        { 13,     0x1ff1, 0,    0 },   { 16,     0xffeb, 0,    0 },
1019
        { 16,     0xffe9, 0,    0 },   { 20,    0xfffd7, 0,    0 },
1020
        { 20,    0xfffd5, 0,    0 },   { 20,    0xfffd3, 0,    0 },
1021
        { 20,    0xfffd1, 0,    0 },   { 24,   0xffffaf, 0,    0 },
1022
        { 24,   0xffffad, 0,    0 },   { 24,   0xffffab, 0,    0 },
1023
        { 24,   0xffffa9, 0,    0 },   { 24,   0xffffa7, 0,    0 },
1024
        { 24,   0xffffa5, 0,    0 },   { 24,   0xffffa3, 0,    0 },
1025
        { 24,   0xffffa1, 0,    0 },   { 28,  0xfffff7f, 0,    0 },
1026
        { 28,  0xfffff7d, 0,    0 },   { 28,  0xfffff7b, 0,    0 },
1027
        { 28,  0xfffff79, 0,    0 },   { 28,  0xfffff77, 0,    0 },
1028
        { 28,  0xfffff75, 0,    0 },   { 28,  0xfffff73, 0,    0 },
1029
        { 28,  0xfffff71, 0,    0 },   { 28,  0xfffff6f, 0,    0 },
1030
        { 28,  0xfffff6d, 0,    0 },   { 28,  0xfffff6b, 0,    0 },
1031
        { 28,  0xfffff69, 0,    0 },   { 28,  0xfffff67, 0,    0 },
1032
        { 28,  0xfffff65, 0,    0 },   { 28,  0xfffff63, 0,    0 },
1033
        { 28,  0xfffff61, 0,    0 },   { 27,  0x7fffff8, 6, 0x3f },
1034
        { 27,  0x7fffff8, 6, 0x3d },   { 27,  0x7fffff8, 6, 0x3b },
1035
        { 27,  0x7fffff8, 6, 0x39 },   { 27,  0x7fffff8, 6, 0x37 },
1036
        { 27,  0x7fffff8, 6, 0x35 },   { 27,  0x7fffff8, 6, 0x33 },
1037
        { 27,  0x7fffff8, 6, 0x31 },   { 27,  0x7fffff8, 6, 0x2f },
1038
        { 27,  0x7fffff8, 6, 0x2d },   { 27,  0x7fffff8, 6, 0x2b },
1039
        { 27,  0x7fffff8, 6, 0x29 },   { 27,  0x7fffff8, 6, 0x27 },
1040
        { 27,  0x7fffff8, 6, 0x25 },   { 27,  0x7fffff8, 6, 0x23 },
1041
        { 27,  0x7fffff8, 6, 0x21 },   { 27,  0x7fffff8, 6, 0x1f },
1042
        { 27,  0x7fffff8, 6, 0x1d },   { 27,  0x7fffff8, 6, 0x1b },
1043
        { 27,  0x7fffff8, 6, 0x19 },   { 27,  0x7fffff8, 6, 0x17 },
1044
        { 27,  0x7fffff8, 6, 0x15 },   { 27,  0x7fffff8, 6, 0x13 },
1045
        { 27,  0x7fffff8, 6, 0x11 },   { 27,  0x7fffff8, 6,  0xf },
1046
        { 27,  0x7fffff8, 6,  0xd },   { 27,  0x7fffff8, 6,  0xb },
1047
        { 27,  0x7fffff8, 6,  0x9 },   { 27,  0x7fffff8, 6,  0x7 },
1048
        { 27,  0x7fffff8, 6,  0x5 },   { 27,  0x7fffff8, 6,  0x3 },
1049
        { 27,  0x7fffff8, 6,  0x1 },   { 30, 0x3ffffffa, 7, 0x7f },
1050
        { 30, 0x3ffffffa, 7, 0x7d },   { 30, 0x3ffffffa, 7, 0x7b },
1051
        { 30, 0x3ffffffa, 7, 0x79 },   { 30, 0x3ffffffa, 7, 0x77 },
1052
        { 30, 0x3ffffffa, 7, 0x75 },   { 30, 0x3ffffffa, 7, 0x73 },
1053
        { 30, 0x3ffffffa, 7, 0x71 },   { 30, 0x3ffffffa, 7, 0x6f },
1054
        { 30, 0x3ffffffa, 7, 0x6d },   { 30, 0x3ffffffa, 7, 0x6b },
1055
        { 30, 0x3ffffffa, 7, 0x69 },   { 30, 0x3ffffffa, 7, 0x67 },
1056
        { 30, 0x3ffffffa, 7, 0x65 },   { 30, 0x3ffffffa, 7, 0x63 },
1057
        { 30, 0x3ffffffa, 7, 0x61 },   { 30, 0x3ffffffa, 7, 0x5f },
1058
        { 30, 0x3ffffffa, 7, 0x5d },   { 30, 0x3ffffffa, 7, 0x5b },
1059
        { 30, 0x3ffffffa, 7, 0x59 },   { 30, 0x3ffffffa, 7, 0x57 },
1060
        { 30, 0x3ffffffa, 7, 0x55 },   { 30, 0x3ffffffa, 7, 0x53 },
1061
        { 30, 0x3ffffffa, 7, 0x51 },   { 30, 0x3ffffffa, 7, 0x4f },
1062
        { 30, 0x3ffffffa, 7, 0x4d },   { 30, 0x3ffffffa, 7, 0x4b },
1063
        { 30, 0x3ffffffa, 7, 0x49 },   { 30, 0x3ffffffa, 7, 0x47 },
1064
        { 30, 0x3ffffffa, 7, 0x45 },   { 30, 0x3ffffffa, 7, 0x43 },
1065
        { 30, 0x3ffffffa, 7, 0x41 },   { 30, 0x3ffffffa, 7, 0x3f },
1066
        { 30, 0x3ffffffa, 7, 0x3d },   { 30, 0x3ffffffa, 7, 0x3b },
1067
        { 30, 0x3ffffffa, 7, 0x39 },   { 30, 0x3ffffffa, 7, 0x37 },
1068
        { 30, 0x3ffffffa, 7, 0x35 },   { 30, 0x3ffffffa, 7, 0x33 },
1069
        { 30, 0x3ffffffa, 7, 0x31 },   { 30, 0x3ffffffa, 7, 0x2f },
1070
        { 30, 0x3ffffffa, 7, 0x2d },   { 30, 0x3ffffffa, 7, 0x2b },
1071
        { 30, 0x3ffffffa, 7, 0x29 },   { 30, 0x3ffffffa, 7, 0x27 },
1072
        { 30, 0x3ffffffa, 7, 0x25 },   { 30, 0x3ffffffa, 7, 0x23 },
1073
        { 30, 0x3ffffffa, 7, 0x21 },   { 30, 0x3ffffffa, 7, 0x1f },
1074
        { 30, 0x3ffffffa, 7, 0x1d },   { 30, 0x3ffffffa, 7, 0x1b },
1075
        { 30, 0x3ffffffa, 7, 0x19 },   { 30, 0x3ffffffa, 7, 0x17 },
1076
        { 30, 0x3ffffffa, 7, 0x15 },   { 30, 0x3ffffffa, 7, 0x13 },
1077
        { 30, 0x3ffffffa, 7, 0x11 },   { 30, 0x3ffffffa, 7,  0xf },
1078
        { 30, 0x3ffffffa, 7,  0xd },   { 30, 0x3ffffffa, 7,  0xb },
1079
        { 30, 0x3ffffffa, 7,  0x9 },   { 30, 0x3ffffffa, 7,  0x7 },
1080
        { 30, 0x3ffffffa, 7,  0x5 },   { 30, 0x3ffffffa, 7,  0x3 },
1081
        { 30, 0x3ffffffa, 7,  0x1 },   {  0,          0, 0,    0 }
1082
    },
1083
1084
    /*
1085
     * prefixed with 15 zeroes
1086
     */
1087
    {
1088
        { 13,     0x1ff3, 0,    0 },   {  2,        0x3, 0,    0 },
1089
        {  2,        0x1, 0,    0 },   {  3,        0x7, 0,    0 },
1090
        {  3,        0x5, 0,    0 },   {  3,        0x3, 0,    0 },
1091
        {  3,        0x1, 0,    0 },   { 31, 0x7ffffffb, 4,  0xf },
1092
        { 31, 0x7ffffffb, 4,  0xd },   { 31, 0x7ffffffb, 4,  0xb },
1093
        { 31, 0x7ffffffb, 4,  0x9 },   { 31, 0x7ffffffb, 4,  0x7 },
1094
        { 31, 0x7ffffffb, 4,  0x5 },   { 31, 0x7ffffffb, 4,  0x3 },
1095
        { 31, 0x7ffffffb, 4,  0x1 },   {  5,       0x1f, 0,    0 },
1096
        {  5,       0x1d, 0,    0 },   {  5,       0x1b, 0,    0 },
1097
        {  5,       0x19, 0,    0 },   {  5,       0x17, 0,    0 },
1098
        {  5,       0x15, 0,    0 },   {  5,       0x13, 0,    0 },
1099
        {  5,       0x11, 0,    0 },   {  5,        0xf, 0,    0 },
1100
        {  5,        0xd, 0,    0 },   {  5,        0xb, 0,    0 },
1101
        {  5,        0x9, 0,    0 },   {  5,        0x7, 0,    0 },
1102
        {  5,        0x5, 0,    0 },   {  5,        0x3, 0,    0 },
1103
        {  5,        0x1, 0,    0 },   {  6,       0x3f, 0,    0 },
1104
        {  6,       0x3d, 0,    0 },   {  6,       0x3b, 0,    0 },
1105
        {  6,       0x39, 0,    0 },   {  6,       0x37, 0,    0 },
1106
        {  6,       0x35, 0,    0 },   {  6,       0x33, 0,    0 },
1107
        {  6,       0x31, 0,    0 },   {  6,       0x2f, 0,    0 },
1108
        {  6,       0x2d, 0,    0 },   {  6,       0x2b, 0,    0 },
1109
        {  6,       0x29, 0,    0 },   {  6,       0x27, 0,    0 },
1110
        {  6,       0x25, 0,    0 },   {  6,       0x23, 0,    0 },
1111
        {  6,       0x21, 0,    0 },   {  6,       0x1f, 0,    0 },
1112
        {  6,       0x1d, 0,    0 },   {  6,       0x1b, 0,    0 },
1113
        {  6,       0x19, 0,    0 },   {  6,       0x17, 0,    0 },
1114
        {  6,       0x15, 0,    0 },   {  6,       0x13, 0,    0 },
1115
        {  6,       0x11, 0,    0 },   {  6,        0xf, 0,    0 },
1116
        {  6,        0xd, 0,    0 },   {  6,        0xb, 0,    0 },
1117
        {  6,        0x9, 0,    0 },   {  6,        0x7, 0,    0 },
1118
        {  6,        0x5, 0,    0 },   {  6,        0x3, 0,    0 },
1119
        {  6,        0x1, 0,    0 },   {  7,       0x7f, 0,    0 },
1120
        {  7,       0x7d, 0,    0 },   {  7,       0x7b, 0,    0 },
1121
        {  7,       0x79, 0,    0 },   {  7,       0x77, 0,    0 },
1122
        {  7,       0x75, 0,    0 },   {  7,       0x73, 0,    0 },
1123
        {  7,       0x71, 0,    0 },   {  7,       0x6f, 0,    0 },
1124
        {  7,       0x6d, 0,    0 },   {  7,       0x6b, 0,    0 },
1125
        {  7,       0x69, 0,    0 },   {  7,       0x67, 0,    0 },
1126
        {  7,       0x65, 0,    0 },   {  7,       0x63, 0,    0 },
1127
        {  7,       0x61, 0,    0 },   {  7,       0x5f, 0,    0 },
1128
        {  7,       0x5d, 0,    0 },   {  7,       0x5b, 0,    0 },
1129
        {  7,       0x59, 0,    0 },   {  7,       0x57, 0,    0 },
1130
        {  7,       0x55, 0,    0 },   {  7,       0x53, 0,    0 },
1131
        {  7,       0x51, 0,    0 },   {  7,       0x4f, 0,    0 },
1132
        {  7,       0x4d, 0,    0 },   {  7,       0x4b, 0,    0 },
1133
        {  7,       0x49, 0,    0 },   {  7,       0x47, 0,    0 },
1134
        {  7,       0x45, 0,    0 },   {  7,       0x43, 0,    0 },
1135
        {  7,       0x41, 0,    0 },   {  7,       0x3f, 0,    0 },
1136
        {  7,       0x3d, 0,    0 },   {  7,       0x3b, 0,    0 },
1137
        {  7,       0x39, 0,    0 },   {  7,       0x37, 0,    0 },
1138
        {  7,       0x35, 0,    0 },   {  7,       0x33, 0,    0 },
1139
        {  7,       0x31, 0,    0 },   {  7,       0x2f, 0,    0 },
1140
        {  7,       0x2d, 0,    0 },   {  7,       0x2b, 0,    0 },
1141
        {  7,       0x29, 0,    0 },   {  7,       0x27, 0,    0 },
1142
        {  7,       0x25, 0,    0 },   {  7,       0x23, 0,    0 },
1143
        {  7,       0x21, 0,    0 },   {  7,       0x1f, 0,    0 },
1144
        {  7,       0x1d, 0,    0 },   {  7,       0x1b, 0,    0 },
1145
        {  7,       0x19, 0,    0 },   {  7,       0x17, 0,    0 },
1146
        {  7,       0x15, 0,    0 },   {  7,       0x13, 0,    0 },
1147
        {  7,       0x11, 0,    0 },   {  7,        0xf, 0,    0 },
1148
        {  7,        0xd, 0,    0 },   {  7,        0xb, 0,    0 },
1149
        {  7,        0x9, 0,    0 },   {  7,        0x7, 0,    0 },
1150
        {  7,        0x5, 0,    0 },   {  7,        0x3, 0,    0 },
1151
        {  7,        0x1, 0,    0 },   {  0,          0, 0,    0 }
1152
    }
1153
};
1154
1155
VlcMagic _magic_values[] = {
1156
    { 0x0, 0, 1 },
1157
    { 0x1, 0, 2 },
1158
    { 0x4, 0, 3 },
1159
    { 0xB, 1, 1 },
1160
    { 0xC, 0, 4 },
1161
    { 0x1A, 0, 5 },
1162
    { 0x1B, 2, 1 },
1163
    { 0x38, 3, 1 },
1164
    { 0x39, 1, 2 },
1165
    { 0x3A, 1, 3 },
1166
    { 0x3B, 0, 6 },
1167
    { 0x78, 4, 1 },
1168
    { 0x79, 5, 1 },
1169
    { 0x7A, 6, 1 },
1170
    { 0x7B, 2, 2 },
1171
    { 0xF8, 1, 4 },
1172
    { 0xF9, 7, 1 },
1173
    { 0xFA, 8, 1 },
1174
    { 0xFB, 3, 2 },
1175
    { 0x1F8, 4, 2 },
1176
    { 0x1F9, 5, 2 },
1177
    { 0x1FA, 2, 3 },
1178
    { 0x1FB, 2, 4 },
1179
    { 0x3F8, 1, 5 },
1180
    { 0x3F9, 1, 6 },
1181
    { 0x3FA, 0, 7 },
1182
    { 0x3FB, 9, 1 },
1183
    { 0x7F8, 10, 1 },
1184
    { 0x7F9, 11, 1 },
1185
    { 0x7FA, 12, 1 },
1186
    { 0x7FB, 13, 1 },
1187
    { 0xFF8, 14, 1 },
1188
    { 0xFF9, 15, 1 },
1189
    { 0xFFA, 6, 2 },
1190
    { 0xFFB, 7, 2 },
1191
    { 0x1FF8, 8, 2 },
1192
    { 0x1FF9, 9, 2 },
1193
    { 0x1FFA, 10, 2 },
1194
    { 0x1FFB, 11, 2 },
1195
    { 0x3FF8, 12, 2 },
1196
    { 0x3FF9, 13, 2 },
1197
    { 0x3FFA, 14, 2 },
1198
    { 0x3FFB, 3, 3 },
1199
    { 0x7FF8, 4, 3 },
1200
    { 0x7FF9, 5, 3 },
1201
    { 0x7FFA, 6, 3 },
1202
    { 0x7FFB, 7, 3 },
1203
    { 0xFFF8, 8, 3 },
1204
    { 0xFFF9, 9, 3 },
1205
    { 0xFFFA, 10, 3 },
1206
    { 0xFFFB, 11, 3 },
1207
    { 0x1FFF8, 12, 3 },
1208
    { 0x1FFF9, 13, 3 },
1209
    { 0x1FFFA, 14, 3 },
1210
    { 0x1FFFB, 3, 4 },
1211
    { 0x3FFF8, 4, 4 },
1212
    { 0x3FFF9, 5, 4 },
1213
    { 0x3FFFA, 6, 4 },
1214
    { 0x3FFFB, 7, 4 },
1215
    { 0x7FFF8, 8, 4 },
1216
    { 0x7FFF9, 9, 4 },
1217
    { 0x7FFFA, 10, 4 },
1218
    { 0x7FFFB, 11, 4 },
1219
    { 0xFFFF8, 12, 4 },
1220
    { 0xFFFF9, 13, 4 },
1221
    { 0xFFFFA, 14, 4 },
1222
    { 0xFFFFB, 2, 5 },
1223
    { 0x1FFFF8, 3, 5 },
1224
    { 0x1FFFF9, 4, 5 },
1225
    { 0x1FFFFA, 5, 5 },
1226
    { 0x1FFFFB, 6, 5 },
1227
    { 0x3FFFF8, 7, 5 },
1228
    { 0x3FFFF9, 8, 5 },
1229
    { 0x3FFFFA, 9, 5 },
1230
    { 0x3FFFFB, 10, 5 },
1231
    { 0x7FFFF8, 11, 5 },
1232
    { 0x7FFFF9, 12, 5 },
1233
    { 0x7FFFFA, 13, 5 },
1234
    { 0x7FFFFB, 14, 5 },
1235
    { 0xFFFFF8, 2, 6 },
1236
    { 0xFFFFF9, 3, 6 },
1237
    { 0xFFFFFA, 4, 6 },
1238
    { 0xFFFFFB, 5, 6 },
1239
    { 0x1FFFFF8, 6, 6 },
1240
    { 0x1FFFFF9, 7, 6 },
1241
    { 0x1FFFFFA, 8, 6 },
1242
    { 0x1FFFFFB, 9, 6 },
1243
    { 0x3FFFFF8, 10, 6 },
1244
    { 0x3FFFFF9, 11, 6 },
1245
    { 0x3FFFFFA, 12, 6 },
1246
    { 0x3FFFFFB, 13, 6 },
1247
    { 0x7FFFFF8, 14, 6 },
1248
    { 0x7FFFFF9, 1, 7 },
1249
    { 0x7FFFFFA, 2, 7 },
1250
    { 0x7FFFFFB, 3, 7 },
1251
    { 0xFFFFFF8, 4, 7 },
1252
    { 0xFFFFFF9, 5, 7 },
1253
    { 0xFFFFFFA, 6, 7 },
1254
    { 0xFFFFFFB, 7, 7 },
1255
    { 0x1FFFFFF8, 8, 7 },
1256
    { 0x1FFFFFF9, 9, 7 },
1257
    { 0x1FFFFFFA, 10, 7 },
1258
    { 0x1FFFFFFB, 11, 7 },
1259
    { 0x3FFFFFF8, 12, 7 },
1260
    { 0x3FFFFFF9, 13, 7 },
1261
    { 0x3FFFFFFA, 14, 7 }
1262
};
1263
1264
/*
1265
 * _find_magic
1266
 *
1267
 * Internal helper-function used to locate a given
1268
 * VlcMagic entry.
1269
 */
1270
VlcMagic *_find_magic(guint magic)
1271
{
1272
    gint low = 0;
1273
    gint high = sizeof(_magic_values) / sizeof(VlcMagic) - 1;
1274
    gint mid;
1275
1276
    while (low <= high) {
1277
        mid = (low + high) / 2;
1278
1279
        if (_magic_values[mid].magic < magic)
1280
            low = mid + 1;
1281
        else if (_magic_values[mid].magic > magic)
1282
            high = mid - 1;
1283
        else
1284
            return &_magic_values[mid];
1285
    }
1286
1287
    return NULL;
1288
}
1289
1290
/*
1291
 * _initialize_vlcdec_lookup
1292
 *
1293
 * Internal helper-function used to initialize
1294
 * the lookup-table used by the VLC-decoder.
1295
 */
1296
void _initialize_vlcdec_lookup(gint8 *lookup_tbl)
1297
{
1298
    gint8 util_buf[3072];
1299
    gint v1_start, v1_end, v1_dec, util_buf_offset;
1300
    gint util_buf_offset_inc, buf1_val, samples_offset;
1301
    gint v1, v2;
1302
    gint8 *p, *p1, *p2, *p3;
1303
1304
    util_buf[0] = 0;
1305
    util_buf[1] = 0;
1306
    util_buf[2] = 0;
1307
    util_buf[3] = 1;
1308
    util_buf[4] = 1;
1309
    util_buf[5] = 1;
1310
    util_buf[765] = 1;
1311
    util_buf[766] = 0;
1312
    util_buf[767] = 1;
1313
    lookup_tbl[255] = 255;
1314
    lookup_tbl[256] = 1;
1315
1316
    v1_start = -3;
1317
    v1_dec = 4;
1318
1319
    util_buf_offset = 11;
1320
    util_buf_offset_inc = 12;
1321
    buf1_val = 2;
1322
1323
    samples_offset = 509;
1324
1325
    do {
1326
        v1 = v1_start;
1327
        v1_end = -(abs(v1_start) + 1) / 2;
1328
        v2 = 0;
1329
1330
        p2 = util_buf + util_buf_offset - 3;
1331
1332
        do {
1333
            p1 = util_buf + ((v1 & 0xff) * 3);
1334
            p1[0] = buf1_val;
1335
            p1[1] = v2;
1336
            p1[2] = buf1_val;
1337
1338
            p2[1] = buf1_val;
1339
            p2[2] = v2 + 1;
1340
            p2[3] = buf1_val;
1341
1342
            p3 = lookup_tbl + samples_offset + v2 + 1;
1343
            p3[0] = v1 & 0xff;
1344
            p3[1] = -(v1 & 0xff);
1345
1346
            v1++;
1347
            v2 += 2;
1348
            p2 -= 3;
1349
        } while (v1 <= v1_end);
1350
1351
        v1_start -= v1_dec;
1352
        v1_dec *= 2;
1353
1354
        util_buf_offset += util_buf_offset_inc;
1355
        util_buf_offset_inc *= 2;
1356
        buf1_val++;
1357
1358
        samples_offset += 255;
1359
    } while (buf1_val <= 7);
1360
1361
    p = lookup_tbl + 1785 + util_buf[388];
1362
    p[0] = 129;
1363
}
1364
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/vlc_decode.c (-119 lines)
Lines 1-119 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <string.h>
19
#include "mimic-private.h"
20
21
extern guchar _col_zag[64];
22
23
/*
24
 * _vlc_decode_block
25
 *
26
 * De-serialize (reconstruct) a variable length coded 8x8 block.
27
 */
28
gboolean _vlc_decode_block(MimCtx *ctx, gint *block, gint num_coeffs)
29
{
30
    guint pos;
31
32
    memset(block, 0, 64 * sizeof(gint));
33
34
    /* The DC-value is read in as is. */
35
    block[0] = _read_bits(ctx, 8);
36
37
    for (pos = 1; pos < num_coeffs; pos++) {
38
        
39
        guint prev_data_index, prev_cur_chunk_len, prev_chunk;
40
        guint value, num_bits;
41
        gboolean prev_read_odd, found_magic;
42
        
43
        /* Save context. */
44
        prev_data_index = ctx->data_index;
45
        prev_cur_chunk_len = ctx->cur_chunk_len;
46
        prev_chunk = ctx->cur_chunk;
47
        prev_read_odd = ctx->read_odd;
48
49
        /* Grab 16 bits. */
50
        value = _read_bits(ctx, 16) << 16;
51
52
        /* Restore context. */
53
        ctx->data_index = prev_data_index;
54
        ctx->cur_chunk_len = prev_cur_chunk_len;
55
        ctx->cur_chunk = prev_chunk;
56
        ctx->read_odd = prev_read_odd;
57
58
        /* Analyze and determine number of bits to read initially. */
59
        num_bits = 3;
60
        if ((value >> 30) == 0 || (value >> 30) == 1) {
61
            num_bits = 2;
62
        } else if ((value & 0xE0000000) != 0x80000000) {
63
            guint nibble = value >> 28;
64
65
            if (nibble == 11 || nibble == 12) {
66
                num_bits = 4;
67
            } else if (nibble == 10) {
68
                _read_bits(ctx, 4);
69
70
                return TRUE;
71
            } else {
72
                if (((value << 2) & 0x8000000) == 0)
73
                    num_bits = 2;
74
75
                num_bits += 2;
76
            }
77
        }
78
79
        /* Read that number of bits. */
80
        value = _read_bits(ctx, num_bits);
81
82
        /*
83
         * Look up the current value against the magic ones,
84
         * and continue extending it bit by bit from the input
85
         * stream until the magic value is found or we have
86
         * read 32 bits (in which case we give up).
87
         */
88
        found_magic = FALSE;
89
        while (!found_magic) {
90
            VlcMagic *magic;
91
92
            if (num_bits > 32)
93
                return FALSE;
94
95
            magic = _find_magic(value);
96
97
            if (magic != NULL) {
98
                pos += magic->pos_add;
99
                num_bits = magic->num_bits;
100
101
                found_magic = TRUE;
102
            } else {
103
                value <<= 1;
104
                value |= _read_bits(ctx, 1);
105
106
                num_bits++;
107
            }
108
        }
109
110
        /* Read the number of bits given by magic value entry. */
111
        value = _read_bits(ctx, num_bits);
112
        
113
        /* Gotcha! :-) */
114
        block[_col_zag[pos]] = ctx->vlcdec_lookup[(num_bits * 255) + value];
115
    }
116
117
    return TRUE;
118
}
119
(-)tdenetwork.ori/kopete/protocols/msn/webcam/libmimic/vlc_encode.c (-84 lines)
Lines 1-84 Link Here
1
/* Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
2
 *
3
 * This library is free software; you can redistribute it and/or
4
 * modify it under the terms of the GNU Lesser General Public
5
 * License as published by the Free Software Foundation; either
6
 * version 2.1 of the License, or (at your option) any later version.
7
 *
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with this library; if not, write to the Free Software
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16
 */
17
18
#include <stdlib.h>
19
#include "mimic-private.h"
20
21
extern guchar _col_zag[64];
22
extern VlcSymbol _vlc_alphabet[16][128];
23
24
/*
25
 * _vlc_encode_block
26
 *
27
 * Serialize an 8x8 block using variable length coding.
28
 */
29
void _vlc_encode_block(MimCtx *ctx, const gint *block, gint num_coeffs)
30
{
31
    gint i, num_zeroes;
32
33
    /* The DC value is written out as is. */
34
    _write_bits(ctx, block[0], 8);
35
36
    /* Number of zeroes prefixing the next non-zero value. */
37
    num_zeroes = 0;
38
39
    for (i = 1; i < num_coeffs && num_zeroes <= 14; i++) {
40
41
        /* Fetch AC coefficients from block in zig-zag order. */
42
        gint value = block[_col_zag[i]];
43
44
        if (value != 0) {
45
            VlcSymbol sym;
46
47
            /* Clip input values to [-128, +128]. */
48
            if (value < -128)
49
                value = -128;
50
            else if (value > 128)
51
                value = 128;
52
53
            /* Look up symbol for the current non-zero value. */
54
            sym = _vlc_alphabet[num_zeroes][abs(value) - 1];
55
56
            /* No symbol? very rare... */
57
            if (sym.length1 <= 0)
58
                break;
59
60
            /* The symbols for negative values are the same as for positives, minus one. */
61
            if (value < 0) {
62
                if (sym.length2 > 0)
63
                    sym.part2 -= 1;
64
                else
65
                    sym.part1 -= 1;
66
            }
67
68
            /* Write out the full symbol. */
69
            _write_bits(ctx, sym.part1, sym.length1);
70
            if (sym.length2 > 0)
71
                _write_bits(ctx, sym.part2, sym.length2);
72
73
            /* Start counting zeroes again. */
74
            num_zeroes = 0;
75
        } else {
76
            num_zeroes++;
77
        }
78
    }
79
80
    /* Write out EOB if necessary. */
81
    if (num_zeroes > 0)
82
        _write_bits(ctx, 0xA, 4);
83
}
84
(-)tdenetwork.ori/kopete/protocols/msn/webcam/Makefile.am (-14 lines)
Lines 1-14 Link Here
1
METASOURCES = AUTO
2
SUBDIRS = libmimic
3
AM_CPPFLAGS =  -I$(srcdir)/libmimic \
4
	$(KOPETE_INCLUDES) \
5
	$(all_includes) \
6
	$(GLIB_CFLAGS)
7
8
noinst_LTLIBRARIES = libmimicwrapper.la
9
10
libmimicwrapper_la_SOURCES = mimicwrapper.cpp msnwebcamdialog.cpp
11
libmimicwrapper_la_LIBADD = ./libmimic/libmimic.la
12
libmimicwrapper_la_LDFLAGS = -no-undefined  $(GLIB_LIBS) $(all_libraries)
13
14
(-)tdenetwork.ori/kopete/protocols/msn/webcam/mimicwrapper.cpp (-105 lines)
Lines 1-105 Link Here
1
/*
2
    Copyright (c) 2005 by Olivier Goffart        <ogoffart@ kde.org>
3
4
    *************************************************************************
5
    *                                                                       *
6
    * This program is free software; you can redistribute it and/or modify  *
7
    * it under the terms of the GNU General Public License as published by  *
8
    * the Free Software Foundation; either version 2 of the License, or     *
9
    * (at your option) any later version.                                   *
10
    *                                                                       *
11
    *************************************************************************
12
*/
13
14
15
#include "mimicwrapper.h"
16
17
#include "libmimic/mimic.h"
18
19
//#include <tqbytearray.h>
20
#include <kdebug.h>
21
#include <tqimage.h>
22
23
MimicWrapper::MimicWrapper()  : m_init(false)
24
{
25
	m_mimctx=mimic_open();
26
}
27
28
MimicWrapper::~MimicWrapper()
29
{
30
	mimic_close(m_mimctx);
31
}
32
33
34
TQPixmap MimicWrapper::decode(const TQByteArray& data)
35
{
36
	if(!m_init)
37
	{
38
		if(!mimic_decoder_init(m_mimctx, (guchar*)(data.data())))
39
		{
40
			kdWarning(14140) << k_funcinfo << "Impossible to init decoder" << endl;
41
			return TQPixmap();
42
		}
43
		if (!mimic_get_property( m_mimctx, "buffer_size", &m_bufferSize) )
44
		{
45
			kdWarning(14140) << k_funcinfo << "Impossible to get buffer size" << endl;
46
			return TQPixmap();
47
		}
48
		m_init=true;
49
	}
50
	
51
	TQByteArray buff(m_bufferSize);
52
	if(!mimic_decode_frame(m_mimctx, (guchar*)(data.data()) , (guchar*)(buff.data()) ) )
53
	{
54
		kdWarning(14140) << k_funcinfo << "Impossible to decode frame" << endl;
55
		return TQPixmap();
56
	}
57
	int width,height;
58
	mimic_get_property(m_mimctx, "width", &width);
59
	mimic_get_property(m_mimctx, "height", &height);
60
	
61
	
62
	TQByteArray buff2(m_bufferSize*4/3);
63
	uint b2=0;
64
	for(uint f=0;f<m_bufferSize;f+=3)
65
	{
66
		buff2[b2+0]=buff[f+2];
67
		buff2[b2+1]=buff[f+1];
68
		buff2[b2+2]=buff[f+0];
69
		buff2[b2+3]=0x00;
70
		b2+=4;
71
	}
72
73
	TQImage img( (uchar*)(buff2.data())   , width , height ,  32  , 0L , 0,  TQImage::BigEndian  );
74
	return TQPixmap(img);
75
}
76
77
TQByteArray MimicWrapper::encode(const TQByteArray& data)
78
{
79
	if(!m_init)
80
	{
81
		if(!mimic_encoder_init(m_mimctx, MIMIC_RES_HIGH))
82
		{
83
			kdWarning(14140) << k_funcinfo << "Impossible to init encoder" << endl;
84
			return TQByteArray();
85
		}
86
		if (!mimic_get_property( m_mimctx, "buffer_size", &m_bufferSize) )
87
		{
88
			kdWarning(14140) << k_funcinfo << "Impossible to get buffer size" << endl;
89
			return TQByteArray();
90
		}
91
		m_init=true;
92
		m_numFrames=0;
93
	}
94
	
95
	TQByteArray buff(m_bufferSize);
96
	int buff_new_size;
97
	if(!mimic_encode_frame(m_mimctx, (guchar*)(data.data()) , (guchar*)(buff.data()) , (gint*)(&buff_new_size) ,  m_numFrames%15==0  ) )
98
	{
99
		kdWarning(14140) << k_funcinfo << "Impossible to decode frame" << endl;
100
		return TQByteArray();
101
	}
102
	buff.resize(buff_new_size);
103
	++m_numFrames;
104
	return buff;
105
}
(-)tdenetwork.ori/kopete/protocols/msn/webcam/mimicwrapper.h (-40 lines)
Lines 1-40 Link Here
1
/*
2
    Copyright (c) 2005 by Olivier Goffart        <ogoffart@ kde.org>
3
4
    *************************************************************************
5
    *                                                                       *
6
    * This program is free software; you can redistribute it and/or modify  *
7
    * it under the terms of the GNU General Public License as published by  *
8
    * the Free Software Foundation; either version 2 of the License, or     *
9
    * (at your option) any later version.                                   *
10
    *                                                                       *
11
    *************************************************************************
12
*/
13
14
#ifndef MIMICWRAPPER_H
15
#define MIMICWREPPER_H
16
17
#include <tqpixmap.h>
18
19
#include "kopete_export.h"
20
21
typedef struct _MimCtx MimCtx;
22
23
class KOPETE_EXPORT MimicWrapper
24
{
25
	public:
26
		MimicWrapper();
27
		~MimicWrapper();
28
		
29
		TQPixmap decode(const TQByteArray &data);
30
		TQByteArray encode(const TQByteArray &data);
31
		
32
	private:
33
		MimCtx *m_mimctx;
34
		bool m_init;
35
		uint m_bufferSize;
36
		uint m_numFrames;
37
};
38
39
#endif
40
(-)tdenetwork.ori/kopete/protocols/msn/webcam/msnwebcamdialog.cpp (-82 lines)
Lines 1-82 Link Here
1
/*
2
    Kopete MSN Protocol
3
	Copyright (c) 2005 by Olivier Goffart            <ogoffart @kde.org>
4
      
5
	Note:  this is just YahooWebcamDialog with s/Yahoo/MSN/g  
6
7
    Copyright (c) 2005 by Matt Rogers                 <mattr@kde.org>
8
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
9
10
    *************************************************************************
11
    *                                                                       *
12
    * This program is free software; you can redistribute it and/or modify  *
13
    * it under the terms of the GNU General Public License as published by  *
14
    * the Free Software Foundation; either version 2 of the License, or     *
15
    * (at your option) any later version.                                   *
16
    *                                                                       *
17
    *************************************************************************
18
*/
19
20
#include "msnwebcamdialog.h"
21
22
#include <tqframe.h>
23
#include <tqobject.h>
24
#include <tqwidget.h>
25
#include <kdebug.h>
26
#include <tdelocale.h>
27
28
29
30
MSNWebcamDialog::MSNWebcamDialog( const TQString& contact, TQWidget * parent, const char * name )
31
	: KDialogBase( KDialogBase::Plain, i18n( "Webcam for %1" ).arg( contact ),
32
                   KDialogBase::Close, KDialogBase::Close, parent, name, false, true /*seperator*/ ),
33
	m_imageContainer( this )
34
{
35
	setInitialSize( TQSize(320,290), true );
36
	
37
	setEscapeButton( KDialogBase::Close );
38
	/*
39
	TQObject::connect( contact, TQT_SIGNAL( signalReceivedWebcamImage( const TQPixmap&  ) ),
40
	                  this, TQT_SLOT( newImage( const TQPixmap& ) ) );
41
	*/
42
	TQObject::connect( this, TQT_SIGNAL( closeClicked() ), this, TQT_SIGNAL( closingWebcamDialog() ) );
43
	/*
44
	TQObject::connect( contact, TQT_SIGNAL( webcamClosed( int ) ), this, TQT_SLOT( webcamClosed( int ) ) );
45
	*/
46
	TQFrame* page = plainPage();
47
	if ( page )
48
	{
49
		kdDebug(14180) << k_funcinfo << "Adding webcam image container" << endl;
50
		//m_imageContainer.setText( i18n( "No webcam image received" ) );
51
		//m_imageContainer.setAlignment( TQt::AlignCenter );
52
		m_imageContainer.setMinimumSize(320,240);
53
	}
54
	show();
55
}
56
57
MSNWebcamDialog::~ MSNWebcamDialog( )
58
{
59
60
}
61
62
void MSNWebcamDialog::newImage( const TQPixmap & image )
63
{
64
	kdDebug(14180) << k_funcinfo << "New image received" << endl;
65
	//	kdDebug(14180) << image << endl;
66
	//m_imageContainer.clear();
67
	m_imageContainer.updatePixmap( image );
68
	//show();
69
}
70
71
void MSNWebcamDialog::webcamClosed( int reason  )
72
{
73
	kdDebug(14180) << k_funcinfo << "webcam closed with reason?? " <<  reason <<endl;
74
	//m_imageContainer.clear();
75
	//m_imageContainer.setText( i18n( "Webcam closed with reason %1" ).arg( TQString::number( reason ) ) );
76
	//m_imageContainer.setAlignment( TQt::AlignCenter );
77
	//show();
78
}
79
80
// kate: indent-mode csands; tab-width 4;
81
82
#include "msnwebcamdialog.moc"
(-)tdenetwork.ori/kopete/protocols/msn/webcam/msnwebcamdialog.h (-56 lines)
Lines 1-56 Link Here
1
/*
2
    Kopete MSN Protocol
3
4
	Copyright (c) 2005 by Olivier Goffart            <ogoffart @kde.org>
5
6
	Note:  this is just YahooWebcamDialog with s/Yahoo/MSN/g  
7
8
    Copyright (c) 2005 by Matt Rogers                 <mattr@kde.org>
9
    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
10
11
    *************************************************************************
12
    *                                                                       *
13
    * This program is free software; you can redistribute it and/or modify  *
14
    * it under the terms of the GNU General Public License as published by  *
15
    * the Free Software Foundation; either version 2 of the License, or     *
16
    * (at your option) any later version.                                   *
17
    *                                                                       *
18
    *************************************************************************
19
*/
20
21
#ifndef YAHOOWEBCAMDIALOG_H_
22
#define YAHOOWEBCAMDIALOG_H_
23
24
//#include <tqlabel.h>
25
#include <webcamwidget.h>
26
#include <kdialogbase.h>
27
28
#include "kopete_export.h"
29
30
31
class TQPixmap;
32
class TQWidget;
33
class MSNContact;
34
35
class KOPETE_EXPORT MSNWebcamDialog : public KDialogBase
36
{
37
Q_OBJECT
38
  
39
public:
40
	MSNWebcamDialog( const TQString& contact, TQWidget* parent = 0, const char* name = 0 );
41
	~MSNWebcamDialog();
42
	
43
public slots:
44
	void newImage( const TQPixmap& image );
45
	void webcamClosed( int );
46
47
signals:
48
	void closingWebcamDialog();
49
	
50
private:
51
	Kopete::WebcamWidget m_imageContainer;
52
	
53
};
54
55
#endif
56
//kate: indent-mode csands; auto-insert-doxygen on;
(-)tdenetwork.ori/kopete/protocols/msn/webcam.cpp (-891 lines)
Lines 1-891 Link Here
1
/*
2
    Copyright (c) 2005 by Olivier Goffart        <ogoffart@ kde.org>
3
4
    *************************************************************************
5
    *                                                                       *
6
    * This program is free software; you can redistribute it and/or modify  *
7
    * it under the terms of the GNU General Public License as published by  *
8
    * the Free Software Foundation; either version 2 of the License, or     *
9
    * (at your option) any later version.                                   *
10
    *                                                                       *
11
    *************************************************************************
12
*/
13
14
15
#include "webcam.h"
16
17
#if MSN_WEBCAM
18
19
#include <stdlib.h>
20
#include <kdebug.h>
21
#include <tqregexp.h>
22
#include <kbufferedsocket.h>
23
#include <tdelocale.h>
24
#include <kserversocket.h>
25
#include <tdemessagebox.h>
26
#include <tqlabel.h>
27
#include <tqguardedptr.h>
28
#include <tqtimer.h>
29
#include <tqevent.h>
30
#include <tqdatetime.h>
31
#include <tdeconfig.h>
32
33
#include "dispatcher.h"
34
35
#include "mimicwrapper.h"
36
#include "msnwebcamdialog.h"
37
38
39
#include "avdevice/videodevicepool.h"
40
41
using namespace KNetwork;
42
43
namespace P2P {
44
45
Webcam::Webcam(Who who, const TQString& to, Dispatcher *parent, TQ_UINT32 sessionId)
46
	: TransferContext(to,parent,sessionId)  , m_who(who) , m_timerId(0)
47
{
48
	setType(P2P::WebcamType);
49
	m_direction = Incoming;
50
	m_listener  = 0l;
51
	m_webcamSocket=0L;
52
//	m_webcamState=wsNegotiating;
53
	
54
	m_mimic=0L;
55
	m_widget=0L;
56
57
	TDEConfig *config = TDEGlobal::config();
58
	config->setGroup( "MSN" );
59
60
	// Read the configuration to get the number of frame per second to send
61
	int webCamFps=config->readNumEntry("WebcamFPS", 25);
62
	m_timerFps = 1000 / webCamFps;
63
}
64
65
Webcam::~Webcam()
66
{
67
	kdDebug(14140) << k_funcinfo<< "################################################" << endl;
68
	m_dispatcher=0l;
69
	delete m_mimic;
70
	delete m_webcamSocket;
71
	delete m_widget;
72
	
73
	if(m_timerId != 0) //if we were sending
74
	{
75
		Kopete::AV::VideoDevicePool *videoDevice = Kopete::AV::VideoDevicePool::self(); 
76
		videoDevice->stopCapturing(); 
77
		videoDevice->close();
78
	}
79
80
}
81
82
void Webcam::askIncommingInvitation()
83
{
84
	m_direction = Incoming;
85
	//protect, in case this is deleted when the messagebox is active
86
	TQGuardedPtr<Webcam> _this = this;
87
	TQString message= (m_who==wProducer)  ?
88
			i18n("<qt>The contact %1 wants to see <b>your</b> webcam, do you want them to see it?</qt>")  :
89
			i18n("The contact %1 wants to show you his/her webcam, do you want to see it?")  ;
90
	int result=KMessageBox::questionYesNo( 0L , message.arg(m_recipient),
91
										   i18n("Webcam invitation - Kopete MSN Plugin") , i18n("Accept") , i18n("Decline"));
92
	if(!_this)
93
		return;
94
	
95
	TQString content = TQString("SessionID: %1\r\n\r\n").arg(m_sessionId);
96
	if(result==KMessageBox::Yes)
97
	{
98
		//Send two message, an OK, and an invite.
99
		//Normaly, the user should decline the invite (i hope)
100
		
101
		// Send a 200 OK message to the recipient.
102
		sendMessage(OK, content);
103
				
104
		
105
		//send an INVITE message we want the user decline
106
		//need to change the branch of the second message
107
		m_branch=Uid::createUid();
108
		m_state = Negotiation;  //set type to application/x-msnmsgr-transreqbody
109
				
110
		content=TQString("Bridges: TRUDPv1 TCPv1\r\n"
111
						"NetID: -1280904111\r\n"
112
						"Conn-Type: Firewall\r\n"
113
						"UPnPNat: false\r\n"
114
						"ICF: false\r\n\r\n");
115
116
		sendMessage(INVITE, content);
117
		
118
	}
119
	else
120
	{
121
		//Decline the invitation
122
		sendMessage(DECLINE, content);
123
		m_state=Finished;
124
	}
125
}
126
127
void Webcam::sendBYEMessage()
128
{
129
	m_state=Finished;
130
	TQString content="Context: dAMAgQ==\r\n";
131
	sendMessage(BYE,content);
132
	
133
	//If ever the opposite client was dead or something, we'll ack anyway, so everything get cleaned
134
	TQTimer::singleShot(60*1000 , this, TQT_SLOT(acknowledged()));
135
}
136
137
138
139
void Webcam::acknowledged()
140
{
141
	kdDebug(14140) << k_funcinfo << endl;
142
	
143
	switch(m_state)
144
	{
145
		case Invitation:
146
		{
147
//			m_state=Negotiation;
148
			break;
149
		}
150
		
151
		/*
152
		case Negotiation:
153
		{
154
			if(m_type == UserDisplayIcon)
155
			{
156
				<<< Data preparation acknowledge message.
157
				m_state = DataTransfer;
158
				m_identifier++;
159
				Start sending data.
160
				slotSendData();
161
			}
162
			break;
163
		}
164
		
165
		case DataTransfer:
166
			NOTE <<< Data acknowledged message.
167
			<<< Bye message should follow.
168
			if(m_type == File)
169
			{
170
				if(m_handshake == 0x01)
171
				{
172
					Data handshake acknowledge message.
173
					Start sending data.
174
					slotSendData();
175
				}
176
				else if(m_handshake == 0x02)
177
				{
178
					Data acknowledge message.
179
					Send the recipient a BYE message.
180
					m_state = Finished;
181
					sendMessage(BYE, "\r\n");
182
				}
183
			}
184
			
185
			break;
186
		*/
187
		case Finished:
188
			//BYE or DECLINE acknowledge message.
189
			m_dispatcher->detach(this);
190
			break;
191
		default:
192
			break;
193
	}
194
}
195
196
197
198
199
void Webcam::processMessage(const Message& message)
200
{
201
	if(message.header.dataOffset+message.header.dataSize >= message.header.totalDataSize)
202
		acknowledge( message ); //aknowledge if needed
203
	
204
	if(message.applicationIdentifier != 4l)
205
	{
206
		TQString body = TQCString(message.body.data(), message.header.dataSize);
207
		kdDebug(14141) << k_funcinfo << "received, " << body << endl;
208
209
		if(body.startsWith("MSNSLP/1.0 200 OK"))
210
		{
211
			m_direction = Outgoing;
212
		}
213
		if(body.startsWith("INVITE"))
214
		{
215
			if(m_direction == Outgoing)
216
			{
217
				TQRegExp regex(";branch=\\{([0-9A-F\\-]*)\\}\r\n");
218
				regex.search(body);
219
				m_branch=regex.cap(1);
220
				//decline
221
				sendMessage(DECLINE);
222
				makeSIPMessage("syn",0x17,0x2a,0x01);
223
			}
224
		}
225
		else if(body.startsWith("MSNSLP/1.0 603 DECLINE"))
226
		{
227
			//if it is the declinaison of the second invite message, we have to don't care
228
			//TODO anyway, if it's the declinaison of our invitation, we have to something
229
		}
230
		else if(body.startsWith("BYE"))
231
		{
232
			m_state = Finished;
233
234
			// Dispose of this transfer context.
235
			m_dispatcher->detach(this);
236
		}
237
		return;
238
	}
239
	
240
	
241
	
242
	//Let's take the fun, we entering into the delicious webcam  negotiation binary protocol
243
244
	//well, there is maybe better to take utf16,  but it's ascii, so no problem.
245
	TQByteArray dataMessage=message.body;
246
	
247
#if 0
248
	TQString echoS="";
249
	unsigned int f=0;
250
	while(f<dataMessage.size())
251
	{
252
		echoS+="\n";
253
		for(unsigned int q=0; q<16 ; q++)
254
		{
255
			if(q+f<dataMessage.size())
256
			{
257
				unsigned int N=(unsigned int) (dataMessage[q+f]);
258
				if(N<16)
259
					echoS+="0";
260
				echoS+=TQString::number( N  ,16)+" ";
261
			}
262
			else
263
				echoS+="   ";
264
		}
265
		echoS+="   ";
266
				
267
		for(unsigned int q=0; (q<16 && (q+f)<dataMessage.size()) ; q++)
268
		{
269
			unsigned char X=dataMessage[q+f];
270
			char C=((char)(( X<128 && X>31 ) ? X : '.'));
271
			echoS+=TQString::fromLatin1(&C,1);
272
		}
273
		f+=16;
274
	}
275
	kdDebug(14141) << k_funcinfo << dataMessage.size() << echoS << endl;
276
#endif
277
	
278
	
279
	
280
	
281
	
282
	for(uint pos=m_content.isNull() ? 10 : 0; pos<dataMessage.size(); pos+=2)
283
	{
284
		if(dataMessage[pos] !=0 )
285
			m_content+=dataMessage[pos];
286
	}
287
288
	if(message.header.dataOffset+message.header.dataSize < message.header.totalDataSize)
289
		return;
290
291
	kdDebug(14141) << k_funcinfo << "Message contents: " << m_content << "\n" << endl;
292
	if(m_content.startsWith("syn"))
293
	{
294
		if(m_direction == Incoming)
295
			makeSIPMessage("syn",0x17,0x2a,0x01);
296
		else
297
			makeSIPMessage("ack",0xea,0x00,0x00);
298
	}
299
	else if(m_content.startsWith("ack"))
300
	{
301
		if(m_direction == Incoming)
302
			makeSIPMessage("ack",0xea,0x00,0x00);
303
		
304
		if(m_who==wProducer)
305
		{
306
			uint sess=rand()%1000+5000;
307
			uint rid=rand()%100+50;
308
			m_myAuth=TQString("recipientid=%1&sessionid=%2\r\n\r\n").arg(rid).arg(sess);
309
			kdDebug(14140) << k_funcinfo << "m_myAuth= " << m_myAuth << endl;
310
			TQString  producerxml=xml(sess , rid);
311
			kdDebug(14140) << k_funcinfo << "producerxml= " << producerxml << endl; 
312
			makeSIPMessage(producerxml);
313
		}
314
	}
315
	else if(m_content.contains("<producer>")   ||  m_content.contains("<viewer>"))
316
	{
317
		TQRegExp rx("<rid>([0-9]*)</rid>.*<session>([0-9]*)</session>");
318
		rx.search(m_content);	
319
		TQString rid=rx.cap(1);
320
		TQString sess=rx.cap(2);
321
		if(m_content.contains("<producer>"))
322
		{
323
			
324
			TQString viewerxml=xml(sess.toUInt() , rid.toUInt());
325
			kdDebug(14140) << k_funcinfo << "vewerxml= " << viewerxml << endl; 
326
			makeSIPMessage(  viewerxml ,0x00,0x09,0x00 );
327
			m_peerAuth=m_myAuth=TQString("recipientid=%1&sessionid=%2\r\n\r\n").arg(rid,sess);
328
			kdDebug(14140) << k_funcinfo << "m_auth= " << m_myAuth << endl;
329
		}
330
		else
331
		{
332
			m_peerAuth=TQString("recipientid=%1&sessionid=%2\r\n\r\n").arg(rid,sess);
333
			
334
			makeSIPMessage("receivedViewerData", 0xec , 0xda , 0x03);
335
		}
336
337
		if(!m_listener)
338
		{
339
			//it should have been creed in xml
340
			sendBYEMessage();
341
			return;
342
		}
343
		//m_listener->setResolutionEnabled(true);
344
				// Create the callback that will try to accept incoming connections.
345
		TQObject::connect(m_listener, TQT_SIGNAL(readyAccept()), this, TQT_SLOT(slotAccept()));
346
		TQObject::connect(m_listener, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotListenError(int)));
347
				// Listen for incoming connections.
348
		bool isListening = m_listener->listen();
349
		kdDebug(14140) << k_funcinfo << (isListening ? TQString("listening %1").arg(m_listener->localAddress().toString()) : TQString("not listening")) << endl;		
350
		
351
		rx=TQRegExp("<tcpport>([^<]*)</tcpport>");
352
		rx.search(m_content);
353
		TQString port1=rx.cap(1);
354
		if(port1=="0")
355
			port1=TQString();
356
		
357
		rx=TQRegExp("<tcplocalport>([^<]*)</tcplocalport>");
358
		rx.search(m_content);
359
		TQString port2=rx.cap(1);
360
		if(port2==port1 || port2=="0")
361
			port2=TQString();
362
		
363
		rx=TQRegExp("<tcpexternalport>([^<]*)</tcpexternalport>");
364
		rx.search(m_content);
365
		TQString port3=rx.cap(1);
366
		if(port3==port1 || port3==port2 || port3=="0")
367
			port3=TQString();
368
369
		int an=0;
370
		while(true)
371
		{
372
			an++;
373
			if(!m_content.contains( TQString("<tcpipaddress%1>").arg(an)  ))
374
				break;
375
			rx=TQRegExp(TQString("<tcpipaddress%1>([^<]*)</tcpipaddress%2>").arg(an).arg(an));
376
			rx.search(m_content);
377
			TQString ip=rx.cap(1);
378
			if(ip.isNull())
379
				continue;
380
			
381
			if(!port1.isNull())
382
			{
383
				kdDebug(14140) << k_funcinfo << "trying to connect on " << ip <<":" << port1 << endl;
384
				TDEBufferedSocket *sock=new TDEBufferedSocket( ip, port1, this );
385
				m_allSockets.append(sock);
386
				TQObject::connect( sock, TQT_SIGNAL( connected( const KResolverEntry&) ), this, TQT_SLOT( slotSocketConnected() ) );
387
				TQObject::connect( sock, TQT_SIGNAL( gotError(int)), this, TQT_SLOT(slotSocketError(int)));
388
				sock->connect(ip, port1);
389
				kdDebug(14140) << k_funcinfo << "okok " << sock << " - " << sock->peerAddress().toString() << " ; " << sock->localAddress().toString()  << endl;
390
			}
391
			if(!port2.isNull())
392
			{
393
				kdDebug(14140) << k_funcinfo << "trying to connect on " << ip <<":" << port2 << endl;
394
				TDEBufferedSocket *sock=new TDEBufferedSocket( ip, port2, this );
395
				m_allSockets.append(sock);
396
				TQObject::connect( sock, TQT_SIGNAL( connected( const KResolverEntry&) ), this, TQT_SLOT( slotSocketConnected() ) );
397
				TQObject::connect( sock, TQT_SIGNAL( gotError(int)), this, TQT_SLOT(slotSocketError(int)));
398
				sock->connect(ip, port2);
399
			}
400
			if(!port3.isNull())
401
			{
402
				kdDebug(14140) << k_funcinfo << "trying to connect on " << ip <<":" << port3 << endl;
403
				TDEBufferedSocket *sock=new TDEBufferedSocket( ip, port3, this );
404
				m_allSockets.append(sock);
405
				TQObject::connect( sock, TQT_SIGNAL( connected( const KResolverEntry&) ), this, TQT_SLOT( slotSocketConnected() ) );
406
				TQObject::connect( sock, TQT_SIGNAL( gotError(int)), this, TQT_SLOT(slotSocketError(int)));
407
				sock->connect(ip, port3);
408
			}
409
		}
410
		TQValueList<TDEBufferedSocket*>::iterator it;
411
		for ( it = m_allSockets.begin(); it != m_allSockets.end(); ++it )
412
		{
413
			TDEBufferedSocket *sock=(*it);
414
			
415
			//sock->enableRead( false );
416
			kdDebug(14140) << k_funcinfo << "connect to "  << sock << " - "<< sock->peerAddress().toString() << " ; " << sock->localAddress().toString()  << endl;
417
		}
418
	}
419
	else if(m_content.contains("receivedViewerData"))
420
	{
421
		//I'm happy you received the xml i sent, really.
422
	}
423
	else
424
		error();
425
	m_content=TQString();
426
}
427
428
void Webcam::makeSIPMessage(const TQString &message, TQ_UINT8 XX, TQ_UINT8 YY , TQ_UINT8 ZZ)
429
{
430
	TQByteArray dataMessage; //(12+message.length()*2);
431
	TQDataStream writer(dataMessage, IO_WriteOnly);
432
	writer.setByteOrder(TQDataStream::LittleEndian);
433
	writer << (TQ_UINT8)0x80;
434
	writer << (TQ_UINT8)XX;
435
	writer << (TQ_UINT8)YY;
436
	writer << (TQ_UINT8)ZZ;
437
	writer << (TQ_UINT8)0x08;
438
	writer << (TQ_UINT8)0x00;
439
	writer << message+'\0';
440
	//writer << (TQ_UINT16)0x0000;
441
442
	/*TQString echoS="";
443
	unsigned int f=0;
444
	while(f<dataMessage.size())
445
	{
446
		echoS+="\n";
447
		for(unsigned int q=0; q<16 ; q++)
448
		{
449
			if(q+f<dataMessage.size())
450
			{
451
				unsigned int N=(unsigned int) (dataMessage[q+f]);
452
				if(N<16)
453
					echoS+="0";
454
				echoS+=TQString::number( N  ,16)+" ";
455
			}
456
			else
457
				echoS+="   ";
458
		}
459
		echoS+="   ";
460
				
461
		for(unsigned int q=0; (q<16 && (q+f)<dataMessage.size()) ; q++)
462
		{
463
			unsigned char X=dataMessage[q+f];
464
			char C=((char)(( X<128 && X>31 ) ? X : '.'));
465
			echoS+=TQString::fromLatin1(&C,1);
466
		}
467
		f+=16;
468
	}
469
	kdDebug(14141) << k_funcinfo << dataMessage.size() << echoS << endl;*/
470
				
471
	
472
	sendBigP2PMessage(dataMessage);
473
}
474
475
void Webcam::sendBigP2PMessage( const TQByteArray & dataMessage)
476
{
477
	unsigned int size=m_totalDataSize=dataMessage.size();
478
	m_offset=0;
479
	++m_identifier;
480
481
	for(unsigned int f=0;f<size;f+=1200)
482
	{
483
		m_offset=f;
484
		TQByteArray dm2;
485
		dm2.duplicate(dataMessage.data()+m_offset, TQMIN(1200,m_totalDataSize-m_offset));
486
		sendData( dm2 );
487
		m_offset+=dm2.size();
488
	}
489
	m_offset=0;
490
	m_totalDataSize=0;
491
}
492
493
494
495
TQString Webcam::xml(uint session , uint rid)
496
{
497
	TQString who= ( m_who == wProducer ) ? TQString("producer") : TQString("viewer");
498
	
499
	TQString ip;
500
	
501
	uint ip_number=1;
502
	TQStringList::iterator it;
503
	TQStringList ips=m_dispatcher->localIp();
504
	for ( it = ips.begin(); it != ips.end(); ++it )
505
	{
506
		ip+=TQString("<tcpipaddress%1>%2</tcpipaddress%3>").arg(ip_number).arg(*it).arg(ip_number);
507
		++ip_number;
508
	}
509
510
        TQString port = TQString::number(getAvailablePort());
511
	
512
	m_listener = new TDEServerSocket(port, this) ;
513
	
514
	return "<" + who + "><version>2.0</version><rid>"+TQString::number(rid)+"</rid><udprid>"+TQString::number(rid+1)+"</udprid><session>"+TQString::number(session)+"</session><ctypes>0</ctypes><cpu>2931</cpu>" +
515
			"<tcp><tcpport>"+port+"</tcpport>\t\t\t\t\t\t\t\t  <tcplocalport>"+port+"</tcplocalport>\t\t\t\t\t\t\t\t  <tcpexternalport>"+port+"</tcpexternalport>"+ip+"</tcp>"+
516
			"<udp><udplocalport>7786</udplocalport><udpexternalport>31863</udpexternalport><udpexternalip>"+ ip +"</udpexternalip><a1_port>31859</a1_port><b1_port>31860</b1_port><b2_port>31861</b2_port><b3_port>31862</b3_port><symmetricallocation>1</symmetricallocation><symmetricallocationincrement>1</symmetricallocationincrement><udpversion>1</udpversion><udpinternalipaddress1>127.0.0.1</udpinternalipaddress1></udp>"+
517
			"<codec></codec><channelmode>1</channelmode></"+who+">\r\n\r\n";
518
}
519
520
int Webcam::getAvailablePort()
521
{
522
    TDEConfig *config = TDEGlobal::config();
523
    config->setGroup( "MSN" );
524
    TQString basePort=config->readEntry("WebcamPort");
525
    if(basePort.isEmpty() || basePort == "0" )
526
		basePort="6891";
527
	
528
    uint firstport = basePort.toInt();
529
    uint maxOffset=config->readUnsignedNumEntry("WebcamMaxPortOffset", 10);
530
    uint lastport = firstport + maxOffset;
531
532
	// try to find an available port
533
	//
534
    TDEServerSocket *ss = new TDEServerSocket();
535
    ss->setFamily(KResolver::InetFamily);
536
    bool found = false;
537
	unsigned int port = firstport;
538
    for( ; port <= lastport; ++port) {
539
		ss->setAddress( TQString::number( port ) );
540
		bool success = ss->listen();
541
		if( found = ( success && ss->error() == TDESocketBase::NoError ) )
542
			break;
543
		ss->close();
544
    }
545
	delete ss;
546
	
547
548
    kdDebug(14140) << k_funcinfo<< "found available port : " << port << endl;
549
550
	return port;
551
}
552
553
554
/* ---------- Now functions about the dirrect connection  --------- */
555
556
void Webcam::slotSocketConnected()
557
{
558
	kdDebug(14140) << k_funcinfo <<"##########################" << endl;
559
	
560
	m_webcamSocket=const_cast<TDEBufferedSocket*>(static_cast<const TDEBufferedSocket*>(sender()));
561
	if(!m_webcamSocket)
562
		return;
563
	
564
	kdDebug(14140) << k_funcinfo << "Connection established on  " <<  m_webcamSocket->peerAddress().toString() << " ; " << m_webcamSocket->localAddress().toString()  << endl;
565
	
566
	m_webcamSocket->setBlocking(false);
567
	m_webcamSocket->enableRead(true);
568
	m_webcamSocket->enableWrite(false);
569
570
	// Create the callback that will try to read bytes from the accepted socket.
571
	TQObject::connect(m_webcamSocket, TQT_SIGNAL(readyRead()),   this, TQT_SLOT(slotSocketRead()));
572
	// Create the callback that will try to handle the socket close event.
573
	TQObject::connect(m_webcamSocket, TQT_SIGNAL(closed()),      this, TQT_SLOT(slotSocketClosed()));
574
	// Create the callback that will try to handle the socket error event.
575
//	TQObject::connect(m_webcamSocket, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int)));
576
577
	m_webcamStates[m_webcamSocket]=wsConnected;
578
	TQCString to_send=m_peerAuth.utf8();
579
	m_webcamSocket->writeBlock(to_send.data(), to_send.length());
580
	kdDebug(14140) << k_funcinfo << "sending "<< m_peerAuth << endl;
581
582
}
583
584
585
void Webcam::slotAccept()
586
{
587
	// Try to accept an incoming connection from the sending client.
588
	m_webcamSocket = static_cast<TDEBufferedSocket*>(m_listener->accept());
589
	if(!m_webcamSocket)
590
	{
591
		// NOTE If direct connection fails, the sending
592
		// client wil transfer the file data through the
593
		// existing session.
594
		kdDebug(14140) << k_funcinfo << "Direct connection failed." << endl;
595
		// Close the listening endpoint.
596
//		m_listener->close();
597
		return;
598
	}
599
600
	kdDebug(14140) << k_funcinfo << "################################  Direct connection established." << endl;
601
602
	// Set the socket to non blocking,
603
	// enable the ready read signal and disable
604
	// ready write signal.
605
	// NOTE readyWrite consumes too much cpu usage.
606
	m_webcamSocket->setBlocking(false);
607
	m_webcamSocket->enableRead(true);
608
	m_webcamSocket->enableWrite(false);
609
610
	// Create the callback that will try to read bytes from the accepted socket.
611
	TQObject::connect(m_webcamSocket, TQT_SIGNAL(readyRead()),   this, TQT_SLOT(slotSocketRead()));
612
	// Create the callback that will try to handle the socket close event.
613
	TQObject::connect(m_webcamSocket, TQT_SIGNAL(closed()),      this, TQT_SLOT(slotSocketClosed()));
614
	// Create the callback that will try to handle the socket error event.
615
	TQObject::connect(m_webcamSocket, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int)));
616
	
617
	m_allSockets.append(m_webcamSocket);
618
	m_webcamStates[m_webcamSocket]=wsNegotiating;
619
}
620
621
void Webcam::slotSocketRead()
622
{
623
	m_webcamSocket=const_cast<TDEBufferedSocket*>(static_cast<const TDEBufferedSocket*>(sender()));
624
625
	uint available = m_webcamSocket->bytesAvailable();
626
	kdDebug(14140) << k_funcinfo  <<  m_webcamSocket <<  "############# " << available << " bytes available." << endl;
627
		
628
	TQByteArray avail_buff(available);
629
	m_webcamSocket->peekBlock(avail_buff.data(), avail_buff.size());
630
	
631
	kdDebug(14140) << k_funcinfo  <<  m_webcamSocket << avail_buff << endl;
632
	
633
	
634
	
635
	const TQString connected_str("connected\r\n\r\n");
636
	switch(m_webcamStates[m_webcamSocket])
637
	{
638
		case wsNegotiating:
639
		{
640
			if(available < m_myAuth.length())
641
			{
642
				kdDebug(14140) << k_funcinfo << "waiting more data   ( " << available << "  of  " <<m_myAuth.length()<< " )"<<  endl;
643
				break;
644
			}
645
			TQByteArray buffer(available);
646
			m_webcamSocket->readBlock(buffer.data(), buffer.size());
647
		
648
			kdDebug(14140) << k_funcinfo << buffer.data() <<  endl;
649
650
			if(TQString(buffer) == m_myAuth )
651
			{
652
				closeAllOtherSockets();
653
				kdDebug(14140) << k_funcinfo << "Sending " << connected_str << endl;
654
				TQCString conne=connected_str.utf8();
655
				m_webcamSocket->writeBlock(conne.data(), conne.length());
656
				m_webcamStates[m_webcamSocket]=wsConnecting;
657
				
658
				//SHOULD NOT BE THERE
659
				m_mimic=new MimicWrapper();
660
				if(m_who==wProducer)
661
				{
662
					Kopete::AV::VideoDevicePool *videoDevice = Kopete::AV::VideoDevicePool::self();
663
					videoDevice->open();
664
					videoDevice->setSize(320, 240);
665
					videoDevice->startCapturing();
666
					
667
					m_timerId=startTimer(m_timerFps);
668
					kdDebug(14140) << k_funcinfo <<  "new timer" << m_timerId << endl;
669
				}
670
				m_widget=new MSNWebcamDialog(m_recipient);
671
				connect(m_widget, TQT_SIGNAL( closingWebcamDialog() ) , this , TQT_SLOT(sendBYEMessage()));
672
673
			}
674
			else
675
			{
676
				kdWarning(14140) << k_funcinfo << "Auth failed" << endl;
677
				m_webcamSocket->disconnect();
678
				m_webcamSocket->deleteLater();
679
				m_allSockets.remove(m_webcamSocket);
680
				m_webcamSocket=0l;
681
				//sendBYEMessage();
682
			}
683
			break;
684
		}
685
		case wsConnecting:
686
		case wsConnected:
687
		{
688
			if(available < connected_str.length())
689
			{
690
				kdDebug(14140) << k_funcinfo << "waiting more data   ( " << available << "  of  " <<connected_str.length()<< " )"<<  endl;
691
				break;
692
			}
693
			TQByteArray buffer(connected_str.length());
694
			m_webcamSocket->readBlock(buffer.data(), buffer.size());
695
			
696
// 			kdDebug(14140) << k_funcinfo << "state " << m_webcamState << " received :" << TQCString(buffer) <<  endl;
697
				
698
	
699
			if(TQString(buffer) == connected_str)
700
			{
701
				if(m_webcamStates[m_webcamSocket]==wsConnected)
702
				{
703
					closeAllOtherSockets();
704
					kdDebug(14140) << k_funcinfo << "Sending " << connected_str << endl;
705
					TQCString conne=connected_str.utf8();
706
					m_webcamSocket->writeBlock(conne.data(), conne.length());
707
												
708
					//SHOULD BE DONE IN ALL CASE
709
				m_mimic=new MimicWrapper();
710
				if(m_who==wProducer)
711
				{
712
					Kopete::AV::VideoDevicePool *videoDevice = Kopete::AV::VideoDevicePool::self();
713
					videoDevice->open();
714
					videoDevice->setSize(320, 240);
715
					videoDevice->startCapturing();
716
					
717
					m_timerId=startTimer(m_timerFps);
718
					kdDebug(14140) << k_funcinfo <<  "new timer" << m_timerId << endl;
719
				}
720
				m_widget=new MSNWebcamDialog(m_recipient);
721
				connect(m_widget, TQT_SIGNAL( closingWebcamDialog() ) , this , TQT_SLOT(sendBYEMessage()));
722
				
723
				}
724
				m_webcamStates[m_webcamSocket]=wsTransfer;
725
726
			}
727
			else
728
			{
729
				kdWarning(14140) << k_funcinfo << "Connecting failed" << endl;
730
				m_webcamSocket->disconnect();
731
				m_webcamSocket->deleteLater();
732
				m_allSockets.remove(m_webcamSocket);
733
				m_webcamSocket=0l;
734
			}
735
			break;
736
		}
737
		case wsTransfer:
738
		{
739
			if(m_who==wProducer)
740
			{
741
				kdWarning(14140) << k_funcinfo << "data received when we are producer"<<  endl;
742
				break;
743
			}
744
			if(available < 24)
745
			{
746
				kdDebug(14140) << k_funcinfo << "waiting more data   ( " << available << "  of  " <<24<< " )"<<  endl;
747
				break;
748
			}
749
			TQByteArray buffer(24);
750
			m_webcamSocket->peekBlock(buffer.data(), buffer.size());
751
			
752
			TQ_UINT32 paysize=(uchar)buffer[8] + ((uchar)buffer[9]<<8) + ((uchar)buffer[10]<<16) + ((uchar)buffer[11]<<24);
753
			
754
			if(available < (paysize+24))
755
			{
756
				kdDebug(14140) << k_funcinfo << "waiting more data   ( " << available << "  of  " <<paysize<< " )"<<  endl;
757
				break;
758
			}
759
			m_webcamSocket->readBlock(buffer.data(), 24); //flush
760
			buffer.resize(paysize);
761
			m_webcamSocket->readBlock(buffer.data(), buffer.size());
762
			
763
			TQPixmap pix=m_mimic->decode(buffer);
764
			if(pix.isNull())
765
			{
766
				kdWarning(14140) << k_funcinfo << "incorrect pixmap returned, better to stop everything"<<  endl;
767
				m_webcamSocket->disconnect();
768
				sendBYEMessage();
769
			}
770
			m_widget->newImage(pix);
771
			break;
772
		}
773
		default:
774
			break;
775
	}
776
777
}
778
779
void Webcam::slotListenError(int errorCode)
780
{
781
	kdWarning(14140) << k_funcinfo << "Error " << errorCode << " : " << m_listener->errorString() << endl;
782
}
783
784
void Webcam::slotSocketClosed()
785
{
786
	if(!m_dispatcher) //we are in this destructor
787
		return; 
788
	
789
	TDEBufferedSocket *m_webcamSocket=const_cast<TDEBufferedSocket*>(static_cast<const TDEBufferedSocket*>(sender()));
790
	
791
	kdDebug(14140) << k_funcinfo <<  m_webcamSocket <<  endl;
792
	
793
	if(m_listener)
794
	{ //if we are still waiting for other socket to connect, just remove this socket from the socket list
795
		m_webcamSocket->disconnect();
796
		m_webcamSocket->deleteLater();
797
		m_allSockets.remove(m_webcamSocket);
798
		m_webcamSocket=0l;
799
	}
800
	else // else, close the session
801
		sendBYEMessage();
802
	
803
}
804
805
void Webcam::slotSocketError(int errorCode)
806
{
807
	TDEBufferedSocket *socket=const_cast<TDEBufferedSocket*>(static_cast<const TDEBufferedSocket*>(sender()));
808
	kdDebug(14140) << k_funcinfo <<  socket << " -  " << errorCode << " : " << socket->TDESocketBase::errorString() << endl;
809
	//sendBYEMessage();
810
}
811
812
void Webcam::closeAllOtherSockets()
813
{
814
	//m_lisener->close();
815
	delete m_listener;
816
	m_listener=0l;
817
	
818
	TQValueList<TDEBufferedSocket*>::iterator it;
819
	for ( it = m_allSockets.begin(); it != m_allSockets.end(); ++it )
820
	{
821
		TDEBufferedSocket *sock=(*it);
822
		if(sock != m_webcamSocket)
823
			delete sock;
824
	}
825
	m_allSockets.clear();
826
}
827
828
829
void Webcam::timerEvent( TQTimerEvent *e )
830
{
831
	if(e->timerId() != m_timerId)
832
		return TransferContext::timerEvent(e);
833
	
834
//	kdDebug(14140) << k_funcinfo << endl;
835
		
836
	Kopete::AV::VideoDevicePool *videoDevice = Kopete::AV::VideoDevicePool::self();
837
	videoDevice->getFrame();
838
	TQImage img;
839
	videoDevice->getImage(&img);
840
	
841
	if(m_widget)
842
		m_widget->newImage(img);
843
	
844
	if(img.width()!=320 || img.height()!=240)
845
	{
846
		kdWarning(14140) << k_funcinfo << "Bad image size " <<img.width() << "x" <<  img.height() << endl;
847
		return;
848
	}
849
850
	uchar *bits=img.bits();
851
	TQByteArray image_data(img.width()*img.height()*3);
852
	uint b2=0;
853
	uint imgsize=img.width()*img.height()*4;
854
	for(uint f=0; f< imgsize; f+=4)
855
	{
856
		image_data[b2+0]=bits[f+2];
857
		image_data[b2+1]=bits[f+1];
858
		image_data[b2+2]=bits[f+0];
859
		b2+=3;
860
	}
861
	
862
	TQByteArray frame=m_mimic->encode(image_data);
863
	
864
	
865
	kdDebug(14140) << k_funcinfo << "Sendinf frame of size " << frame.size() << endl;
866
	//build the header.
867
	TQByteArray header;
868
	
869
	TQDataStream writer(header, IO_WriteOnly);
870
	writer.setByteOrder(TQDataStream::LittleEndian);
871
	writer << (TQ_UINT16)24;  // header size
872
	writer << (TQ_UINT16)img.width();
873
	writer << (TQ_UINT16)img.height();
874
	writer << (TQ_UINT16)0x0000; //wtf .?
875
	writer << (TQ_UINT32)frame.size();
876
	writer << (TQ_UINT8)('M') << (TQ_UINT8)('L') << (TQ_UINT8)('2') << (TQ_UINT8)('0');
877
	writer << (TQ_UINT32)0x00000000; //wtf .?
878
	writer << TQTime::currentTime();  //FIXME:  possible midnight bug ?
879
880
	m_webcamSocket->writeBlock(header.data(), header.size());
881
	m_webcamSocket->writeBlock(frame.data(), frame.size());
882
}
883
884
885
}
886
887
888
#include "webcam.moc"
889
890
#endif
891
(-)tdenetwork.ori/kopete/protocols/msn/webcam.h (-92 lines)
Lines 1-92 Link Here
1
/*
2
    Copyright (c) 2005 by Olivier Goffart        <ogoffart@ kde.org>
3
4
    *************************************************************************
5
    *                                                                       *
6
    * This program is free software; you can redistribute it and/or modify  *
7
    * it under the terms of the GNU General Public License as published by  *
8
    * the Free Software Foundation; either version 2 of the License, or     *
9
    * (at your option) any later version.                                   *
10
    *                                                                       *
11
    *************************************************************************
12
*/
13
14
#ifndef P2PWEBCAM_H
15
#define P2PWEBCAM_H
16
17
#include "p2p.h"
18
19
#if MSN_WEBCAM
20
21
namespace KNetwork{ class TDEServerSocket; class TDEBufferedSocket;  }
22
23
class MimicWrapper;
24
class TQLabel;
25
class MSNWebcamDialog;
26
class TQTimerEvent;
27
28
namespace P2P {
29
30
31
class Webcam  : public TransferContext
32
{  Q_OBJECT
33
  
34
	public:
35
		enum Who { wProducer , wViewer };
36
		
37
		Webcam( Who who , const TQString& to, Dispatcher *parent, TQ_UINT32 sessionID);
38
		~Webcam( );
39
40
		virtual void processMessage(const Message& message);
41
		
42
	public slots:
43
		void askIncommingInvitation();
44
		virtual void acknowledged();
45
		void sendBYEMessage();
46
	
47
	private:
48
		void makeSIPMessage(const TQString &message, TQ_UINT8 XX=0, TQ_UINT8 YY=9 , TQ_UINT8 ZZ=0);
49
		void sendBigP2PMessage( const TQByteArray& dataMessage );
50
		void closeAllOtherSockets();
51
		TQString m_content;
52
		
53
		TQString xml(uint session , uint rid);
54
		int getAvailablePort();
55
56
		
57
		KNetwork::TDEServerSocket   *m_listener;
58
		KNetwork::TDEBufferedSocket *m_webcamSocket;
59
		
60
		enum WebcamStatus { wsNegotiating , wsConnecting, wsConnected, wsTransfer  } ;
61
		
62
		Who m_who;
63
		
64
		TQString m_myAuth;
65
		TQString m_peerAuth;
66
		
67
		MimicWrapper *m_mimic;
68
		MSNWebcamDialog *m_widget;
69
				
70
		TQValueList<KNetwork::TDEBufferedSocket* > m_allSockets;
71
		TQMap<KNetwork::TDEBufferedSocket*, WebcamStatus> m_webcamStates;
72
		
73
		int m_timerId;
74
		int m_timerFps;
75
76
	private slots:
77
		void slotListenError(int errorCode);
78
		void slotAccept();
79
		void slotSocketRead();
80
		void slotSocketClosed();
81
		void slotSocketError(int errorCode);
82
		void slotSocketConnected();
83
//		void slotReadyWrite();
84
	protected:
85
		virtual void timerEvent( TQTimerEvent * );
86
};
87
88
}
89
90
#endif
91
92
#endif
(-)tdenetwork.ori/kopete/protocols/yahoo/libkyahoo/yabentry.cpp (-3 lines)
Lines 60-66 Link Here
60
	imGoogleTalk = e.attribute("img");
60
	imGoogleTalk = e.attribute("img");
61
	imICQ = e.attribute("imq");
61
	imICQ = e.attribute("imq");
62
	imIRC = e.attribute("imc");
62
	imIRC = e.attribute("imc");
63
	imMSN = e.attribute("imm");
64
	imQQ = e.attribute("imqq");
63
	imQQ = e.attribute("imqq");
65
	imSkype = e.attribute("imk");
64
	imSkype = e.attribute("imk");
66
}
65
}
Lines 110-116 Link Here
110
	imGoogleTalk = d.elementsByTagName("img").item(0).toElement().text();
109
	imGoogleTalk = d.elementsByTagName("img").item(0).toElement().text();
111
	imICQ = d.elementsByTagName("imq").item(0).toElement().text();
110
	imICQ = d.elementsByTagName("imq").item(0).toElement().text();
112
	imIRC = d.elementsByTagName("imc").item(0).toElement().text();
111
	imIRC = d.elementsByTagName("imc").item(0).toElement().text();
113
	imMSN = d.elementsByTagName("imm").item(0).toElement().text();
114
	imQQ = d.elementsByTagName("imqq").item(0).toElement().text();
112
	imQQ = d.elementsByTagName("imqq").item(0).toElement().text();
115
	imSkype = d.elementsByTagName("imk").item(0).toElement().text();
113
	imSkype = d.elementsByTagName("imk").item(0).toElement().text();
116
}
114
}
Lines 157-163 Link Here
157
	e.setAttribute( "img", imGoogleTalk );
155
	e.setAttribute( "img", imGoogleTalk );
158
	e.setAttribute( "imq", imICQ );
156
	e.setAttribute( "imq", imICQ );
159
	e.setAttribute( "imc", imIRC );
157
	e.setAttribute( "imc", imIRC );
160
	e.setAttribute( "imm", imMSN );
161
	e.setAttribute( "imqq", imQQ );
158
	e.setAttribute( "imqq", imQQ );
162
	e.setAttribute( "imk", imSkype );
159
	e.setAttribute( "imk", imSkype );
163
}
160
}
(-)tdenetwork.ori/kopete/protocols/yahoo/libkyahoo/yabentry.h (-1 lines)
Lines 46-52 Link Here
46
	TQString		altEmail2;
46
	TQString		altEmail2;
47
	TQString		imAIM;
47
	TQString		imAIM;
48
	TQString		imICQ;
48
	TQString		imICQ;
49
	TQString		imMSN;
50
	TQString		imGoogleTalk;
49
	TQString		imGoogleTalk;
51
	TQString		imSkype;
50
	TQString		imSkype;
52
	TQString		imIRC;
51
	TQString		imIRC;
(-)tdenetwork.ori/kopete/protocols/yahoo/ui/yahoouserinfodialog.cpp (-2 lines)
Lines 120-126 Link Here
120
// 	entry.imGoogleTalk = m_genInfoWidget->firstNameEdit->text();
120
// 	entry.imGoogleTalk = m_genInfoWidget->firstNameEdit->text();
121
// 	entry.imICQ = m_genInfoWidget->firstNameEdit->text();
121
// 	entry.imICQ = m_genInfoWidget->firstNameEdit->text();
122
// 	entry.imIRC = m_genInfoWidget->firstNameEdit->text();
122
// 	entry.imIRC = m_genInfoWidget->firstNameEdit->text();
123
// 	entry.imMSN = m_genInfoWidget->firstNameEdit->text();
124
// 	entry.imQQ = m_genInfoWidget->firstNameEdit->text();
123
// 	entry.imQQ = m_genInfoWidget->firstNameEdit->text();
125
// 	entry.imSkype = m_genInfoWidget->firstNameEdit->text();
124
// 	entry.imSkype = m_genInfoWidget->firstNameEdit->text();
126
		
125
		
Lines 191-197 Link Here
191
	// 	entry.imGoogleTalk = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
190
	// 	entry.imGoogleTalk = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
192
	// 	entry.imICQ = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
191
	// 	entry.imICQ = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
193
	// 	entry.imIRC = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
192
	// 	entry.imIRC = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
194
	// 	entry.imMSN = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
195
	// 	entry.imQQ = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
193
	// 	entry.imQQ = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
196
	// 	entry.imSkype = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
194
	// 	entry.imSkype = m_genInfoWidget->firstNameEdit->text().isEmpty() ? oldEntry->notes : m_otherInfoWidget->commentsEdit->text();
197
		
195
		
(-)tdenetwork.ori/kopete/protocols/yahoo/yahoocontact.cpp (-2 lines)
Lines 737-743 Link Here
737
	setProperty( YahooProtocol::protocol()->propAltEmail2, m_YABEntry->altEmail2 );
737
	setProperty( YahooProtocol::protocol()->propAltEmail2, m_YABEntry->altEmail2 );
738
	setProperty( YahooProtocol::protocol()->propImAIM, m_YABEntry->imAIM );
738
	setProperty( YahooProtocol::protocol()->propImAIM, m_YABEntry->imAIM );
739
	setProperty( YahooProtocol::protocol()->propImICQ, m_YABEntry->imICQ );
739
	setProperty( YahooProtocol::protocol()->propImICQ, m_YABEntry->imICQ );
740
	setProperty( YahooProtocol::protocol()->propImMSN, m_YABEntry->imMSN );
741
	setProperty( YahooProtocol::protocol()->propImGoogleTalk, m_YABEntry->imGoogleTalk );
740
	setProperty( YahooProtocol::protocol()->propImGoogleTalk, m_YABEntry->imGoogleTalk );
742
	setProperty( YahooProtocol::protocol()->propImSkype, m_YABEntry->imSkype );
741
	setProperty( YahooProtocol::protocol()->propImSkype, m_YABEntry->imSkype );
743
	setProperty( YahooProtocol::protocol()->propImIRC, m_YABEntry->imIRC );
742
	setProperty( YahooProtocol::protocol()->propImIRC, m_YABEntry->imIRC );
Lines 800-806 Link Here
800
	m_YABEntry->altEmail2 = property( YahooProtocol::protocol()->propAltEmail2 ).value().toString();
799
	m_YABEntry->altEmail2 = property( YahooProtocol::protocol()->propAltEmail2 ).value().toString();
801
	m_YABEntry->imAIM = property( YahooProtocol::protocol()->propImAIM ).value().toString();
800
	m_YABEntry->imAIM = property( YahooProtocol::protocol()->propImAIM ).value().toString();
802
	m_YABEntry->imICQ = property( YahooProtocol::protocol()->propImICQ ).value().toString();
801
	m_YABEntry->imICQ = property( YahooProtocol::protocol()->propImICQ ).value().toString();
803
	m_YABEntry->imMSN = property( YahooProtocol::protocol()->propImMSN ).value().toString();
804
	m_YABEntry->imGoogleTalk = property( YahooProtocol::protocol()->propImGoogleTalk ).value().toString();
802
	m_YABEntry->imGoogleTalk = property( YahooProtocol::protocol()->propImGoogleTalk ).value().toString();
805
	m_YABEntry->imSkype = property( YahooProtocol::protocol()->propImSkype ).value().toString();
803
	m_YABEntry->imSkype = property( YahooProtocol::protocol()->propImSkype ).value().toString();
806
	m_YABEntry->imIRC = property( YahooProtocol::protocol()->propImIRC ).value().toString();
804
	m_YABEntry->imIRC = property( YahooProtocol::protocol()->propImIRC ).value().toString();
(-)tdenetwork.ori/kopete/protocols/yahoo/yahooprotocol.cpp (-1 lines)
Lines 73-79 Link Here
73
	propAltEmail2("YABAlternativeEmail2", i18n("Alternative email 1"), TQString(), true, false),
73
	propAltEmail2("YABAlternativeEmail2", i18n("Alternative email 1"), TQString(), true, false),
74
	propImAIM("YABIMAIM", i18n("AIM"), TQString(), true, false),
74
	propImAIM("YABIMAIM", i18n("AIM"), TQString(), true, false),
75
	propImICQ("YABIMICQ", i18n("ICQ"), TQString(), true, false),
75
	propImICQ("YABIMICQ", i18n("ICQ"), TQString(), true, false),
76
	propImMSN("YABIMMSN", i18n("MSN"), TQString(), true, false),
77
	propImGoogleTalk("YABIMGoogleTalk", i18n("GoogleTalk"), TQString(), true, false),
76
	propImGoogleTalk("YABIMGoogleTalk", i18n("GoogleTalk"), TQString(), true, false),
78
	propImSkype("YABIMSkype", i18n("Skype"), TQString(), true, false),
77
	propImSkype("YABIMSkype", i18n("Skype"), TQString(), true, false),
79
	propImIRC("YABIMIRC", i18n("IRC"), TQString(), true, false),
78
	propImIRC("YABIMIRC", i18n("IRC"), TQString(), true, false),
(-)tdenetwork.ori/kopete/protocols/yahoo/yahooprotocol.h (-1 lines)
Lines 89-95 Link Here
89
	const Kopete::ContactPropertyTmpl	propAltEmail2;
89
	const Kopete::ContactPropertyTmpl	propAltEmail2;
90
	const Kopete::ContactPropertyTmpl	propImAIM;
90
	const Kopete::ContactPropertyTmpl	propImAIM;
91
	const Kopete::ContactPropertyTmpl	propImICQ;
91
	const Kopete::ContactPropertyTmpl	propImICQ;
92
	const Kopete::ContactPropertyTmpl	propImMSN;
93
	const Kopete::ContactPropertyTmpl	propImGoogleTalk;
92
	const Kopete::ContactPropertyTmpl	propImGoogleTalk;
94
	const Kopete::ContactPropertyTmpl	propImSkype;
93
	const Kopete::ContactPropertyTmpl	propImSkype;
95
	const Kopete::ContactPropertyTmpl	propImIRC;
94
	const Kopete::ContactPropertyTmpl	propImIRC;
(-)tdenetwork.ori/kopete/TODO (-12 lines)
Lines 76-90 Link Here
76
76
77
77
78
================================================================================
78
================================================================================
79
80
81
 MSN TODO  (for the Kopete 1.0 release)
82
---------------------------------------
83
84
	- Handle the MSN PLUS! color codes
85
	- Show internals messages in chat window when filetransfers (go with
86
	  the new interface for invitation in libkopete)
87
88
	- Search for an MSN User (not for Kopete 1.0)
89
90
================================================================================

Return to bug 1547