# HG changeset patch # User Yoshiki Yazawa # Date 1269930423 -32400 # Node ID 70b0f46f2966ee447890791b83f887cf68a48109 # Parent fdeb9a9543ce4de674fff212021853fd198ec754# Parent 0646207f360f6992428653d2d797e4c10214104e merged with im.pidgin.pidgin diff -r fdeb9a9543ce -r 70b0f46f2966 COPYRIGHT --- a/COPYRIGHT Thu Mar 25 18:03:55 2010 +0900 +++ b/COPYRIGHT Tue Mar 30 15:27:03 2010 +0900 @@ -383,6 +383,7 @@ Mart Raudsepp Etan Reisner Luoh Ren-Shan +Daniele Ricci Kristian Rietveld Pekka Riikonen Tim Ringenbach diff -r fdeb9a9543ce -r 70b0f46f2966 ChangeLog --- a/ChangeLog Thu Mar 25 18:03:55 2010 +0900 +++ b/ChangeLog Tue Mar 30 15:27:03 2010 +0900 @@ -29,7 +29,9 @@ conversation windows. This can be changed in .gtkrc-2.0. For example, Ctrl+v can be bound to 'Paste as Plain Text' by default. * Plugins can now handle markup in buddy names by attaching to the signal - "drawing-buddy". + "drawing-buddy". (Daniele Ricci, Andrea Piccinelli) + * Be more accommodating when scaling down large images for use as + buddy icons. Bonjour: * Added support for IPv6. (Thanks to T_X for testing) diff -r fdeb9a9543ce -r 70b0f46f2966 ChangeLog.API --- a/ChangeLog.API Thu Mar 25 18:03:55 2010 +0900 +++ b/ChangeLog.API Tue Mar 30 15:27:03 2010 +0900 @@ -24,6 +24,9 @@ * sent-attention conversation signal * got-attention conversation signal * PurpleMood struct in status.h + * purple_certificates_import for importing multiple certificates from + a single file (and corresponding import_certificates member of + PurpleCertificateScheme struct) Pidgin: Added: diff -r fdeb9a9543ce -r 70b0f46f2966 configure.ac --- a/configure.ac Thu Mar 25 18:03:55 2010 +0900 +++ b/configure.ac Tue Mar 30 15:27:03 2010 +0900 @@ -1684,6 +1684,9 @@ SSL_CERTIFICATES_DIR="" if ! test -z "$ssl_certificates_dir" ; then + if test "x$ssl_certificates_dir" = "xyes" ; then + AC_MSG_ERROR([--with-system-ssl-certs requires that a location is specified, eg. --with-system-ssl-certs=/etc/pki/tls/certs]) + fi if ! test -d "$ssl_certificates_dir" ; then AC_MSG_ERROR([$ssl_certificates_dir does not exist, if this is the correct location please make sure that it exists.]) fi diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/certificate.c --- a/libpurple/certificate.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/certificate.c Tue Mar 30 15:27:03 2010 +0900 @@ -377,6 +377,16 @@ return (scheme->import_certificate)(filename); } +GSList * +purple_certificates_import(PurpleCertificateScheme *scheme, const gchar *filename) +{ + g_return_val_if_fail(scheme, NULL); + g_return_val_if_fail(scheme->import_certificates, NULL); + g_return_val_if_fail(filename, NULL); + + return (scheme->import_certificates)(filename); +} + gboolean purple_certificate_export(const gchar *filename, PurpleCertificate *crt) { @@ -800,8 +810,9 @@ PurpleCertificateScheme *x509; GDir *certdir; const gchar *entry; - GPatternSpec *pempat; + GPatternSpec *pempat, *crtpat; GList *iter = NULL; + GSList *crts = NULL; if (x509_ca_initialized) return TRUE; @@ -817,6 +828,7 @@ /* Use a glob to only read .pem files */ pempat = g_pattern_spec_new("*.pem"); + crtpat = g_pattern_spec_new("*.crt"); /* Populate the certificates pool from the search path(s) */ for (iter = x509_ca_paths; iter; iter = iter->next) { @@ -830,32 +842,39 @@ gchar *fullpath; PurpleCertificate *crt; - if ( !g_pattern_match_string(pempat, entry) ) { + if (!g_pattern_match_string(pempat, entry) && !g_pattern_match_string(crtpat, entry)) { continue; } fullpath = g_build_filename(iter->data, entry, NULL); /* TODO: Respond to a failure in the following? */ - crt = purple_certificate_import(x509, fullpath); + crts = purple_certificates_import(x509, fullpath); - if (x509_ca_quiet_put_cert(crt)) { - purple_debug_info("certificate/x509/ca", - "Loaded %s\n", - fullpath); - } else { - purple_debug_error("certificate/x509/ca", - "Failed to load %s\n", - fullpath); + while (crts && crts->data) { + crt = crts->data; + if (x509_ca_quiet_put_cert(crt)) { + gchar *name; + name = purple_certificate_get_subject_name(crt); + purple_debug_info("certificate/x509/ca", + "Loaded %s from %s\n", + name ? name : "(unknown)", fullpath); + } else { + purple_debug_error("certificate/x509/ca", + "Failed to load certificate from %s\n", + fullpath); + } + purple_certificate_destroy(crt); + crts = g_slist_delete_link(crts, crts); } - purple_certificate_destroy(crt); g_free(fullpath); } g_dir_close(certdir); } g_pattern_spec_free(pempat); + g_pattern_spec_free(crtpat); purple_debug_info("certificate/x509/ca", "Lazy init completed.\n"); diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/certificate.h --- a/libpurple/certificate.h Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/certificate.h Tue Mar 30 15:27:03 2010 +0900 @@ -250,10 +250,17 @@ /** Retrieve the certificate activation/expiration times */ gboolean (* get_times)(PurpleCertificate *crt, time_t *activation, time_t *expiration); + /** Imports certificates from a file + * + * @param filename File to import the certificates from + * @return GSList of pointers to the newly allocated Certificate structs + * or NULL on failure. + */ + GSList * (* import_certificates)(const gchar * filename); + void (*_purple_reserved1)(void); void (*_purple_reserved2)(void); void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); }; /** A set of operations used to provide logic for verifying a Certificate's @@ -492,6 +499,16 @@ purple_certificate_import(PurpleCertificateScheme *scheme, const gchar *filename); /** + * Imports a list of PurpleCertificates from a file + * + * @param scheme Scheme to import under + * @param filename File path to import from + * @return Pointer to a GSList of new PurpleCertificates, or NULL on failure + */ +GSList * +purple_certificates_import(PurpleCertificateScheme *scheme, const gchar *filename); + +/** * Exports a PurpleCertificate to a file * * @param filename File to export the certificate to diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/perl/scripts/account.pl --- a/libpurple/plugins/perl/scripts/account.pl Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/perl/scripts/account.pl Tue Mar 30 15:27:03 2010 +0900 @@ -27,7 +27,7 @@ # We will create these on load then destroy them on unload my $TEST_NAME = "perlTestName"; - my $PROTOCOL_ID = "prpl-oscar"; + my $PROTOCOL_ID = "prpl-aim"; sub plugin_init { diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/perl/scripts/buddy_list.pl --- a/libpurple/plugins/perl/scripts/buddy_list.pl Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/perl/scripts/buddy_list.pl Tue Mar 30 15:27:03 2010 +0900 @@ -24,7 +24,7 @@ my $TEST_GROUP = "UConn Buddies"; my $TEST_NAME = "johnhkelm"; my $TEST_ALIAS = "John Kelm"; - my $PROTOCOL_ID = "prpl-oscar"; + my $PROTOCOL_ID = "prpl-aim"; sub plugin_init { diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/perl/scripts/conversation.pl --- a/libpurple/plugins/perl/scripts/conversation.pl Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/perl/scripts/conversation.pl Tue Mar 30 15:27:03 2010 +0900 @@ -30,7 +30,7 @@ my $TEST_GROUP = "UConn Buddies"; my $TEST_NAME = "johnhkelm"; my $TEST_ALIAS = "John Kelm"; - my $PROTOCOL_ID = "prpl-oscar"; + my $PROTOCOL_ID = "prpl-aim"; sub plugin_init { diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/perl/scripts/plugin_pref.pl --- a/libpurple/plugins/perl/scripts/plugin_pref.pl Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/perl/scripts/plugin_pref.pl Tue Mar 30 15:27:03 2010 +0900 @@ -28,7 +28,7 @@ my $TEST_GROUP = "perlTestGroup"; my $TEST_NAME = "perlTestName"; my $TEST_ALIAS = "perlTestAlias"; - my $PROTOCOL_ID = "prpl-oscar"; + my $PROTOCOL_ID = "prpl-aim"; sub foo { $frame = Purple::PluginPref::Frame->new(); diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/ssl/ssl-gnutls.c --- a/libpurple/plugins/ssl/ssl-gnutls.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/ssl/ssl-gnutls.c Tue Mar 30 15:27:03 2010 +0900 @@ -548,6 +548,55 @@ return crt; } +/** Imports a number of PEM-formatted X.509 certificates from the specified file. + * @param filename Filename to import from. Format is PEM + * + * @return A newly allocated GSList of Certificate structures of the x509_gnutls scheme + */ +static GSList * +x509_importcerts_from_file(const gchar * filename) +{ + PurpleCertificate *crt; /* Certificate being constructed */ + gchar *buf; /* Used to load the raw file data */ + gchar *begin, *end; + GSList *crts = NULL; + gsize buf_sz; /* Size of the above */ + gnutls_datum dt; /* Struct to pass down to GnuTLS */ + + purple_debug_info("gnutls", + "Attempting to load X.509 certificates from %s\n", + filename); + + /* Next, we'll simply yank the entire contents of the file + into memory */ + /* TODO: Should I worry about very large files here? */ + g_return_val_if_fail( + g_file_get_contents(filename, + &buf, + &buf_sz, + NULL /* No error checking for now */ + ), + NULL); + + begin = buf; + while((end = strstr(begin, "-----END CERTIFICATE-----")) != NULL) { + end += sizeof("-----END CERTIFICATE-----")-1; + /* Load the datum struct */ + dt.data = (unsigned char *) begin; + dt.size = (end-begin); + + /* Perform the conversion; files should be in PEM format */ + crt = x509_import_from_datum(dt, GNUTLS_X509_FMT_PEM); + crts = g_slist_prepend(crts, crt); + begin = end; + } + + /* Cleanup */ + g_free(buf); + + return crts; +} + /** * Exports a PEM-formatted X.509 certificate to the specified file. * @param filename Filename to export to. Format will be PEM @@ -964,10 +1013,10 @@ x509_common_name, /* Subject name */ x509_check_name, /* Check subject name */ x509_times, /* Activation/Expiration time */ + x509_importcerts_from_file, /* Multiple certificates import function */ NULL, NULL, - NULL, NULL }; diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/plugins/ssl/ssl-nss.c --- a/libpurple/plugins/ssl/ssl-nss.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/plugins/ssl/ssl-nss.c Tue Mar 30 15:27:03 2010 +0900 @@ -530,7 +530,7 @@ /** Imports a PEM-formatted X.509 certificate from the specified file. * @param filename Filename to import from. Format is PEM * - * @return A newly allocated Certificate structure of the x509_gnutls scheme + * @return A newly allocated Certificate structure of the x509_nss scheme */ static PurpleCertificate * x509_import_from_file(const gchar *filename) @@ -575,6 +575,60 @@ return crt; } +/** Imports a number of PEM-formatted X.509 certificates from the specified file. + * @param filename Filename to import from. Format is PEM + * + * @return A GSList of newly allocated Certificate structures of the x509_nss scheme + */ +static GSList * +x509_importcerts_from_file(const gchar *filename) +{ + gchar *rawcert, *begin, *end; + gsize len = 0; + GSList *crts = NULL; + CERTCertificate *crt_dat; + PurpleCertificate *crt; + + g_return_val_if_fail(filename != NULL, NULL); + + purple_debug_info("nss/x509", + "Loading certificate from %s\n", + filename); + + /* Load the raw data up */ + if (!g_file_get_contents(filename, + &rawcert, &len, + NULL)) { + purple_debug_error("nss/x509", "Unable to read certificate file.\n"); + return NULL; + } + + if (len == 0) { + purple_debug_error("nss/x509", + "Certificate file has no contents!\n"); + if (rawcert) + g_free(rawcert); + return NULL; + } + + begin = rawcert; + while((end = strstr(begin, "-----END CERTIFICATE-----")) != NULL) { + end += sizeof("-----END CERTIFICATE-----")-1; + /* Decode the certificate */ + crt_dat = CERT_DecodeCertFromPackage(begin, (end-begin)); + + g_return_val_if_fail(crt_dat != NULL, NULL); + + crt = g_new0(PurpleCertificate, 1); + crt->scheme = &x509_nss; + crt->data = crt_dat; + crts = g_slist_prepend(crts, crt); + begin = end; + } + g_free(rawcert); + + return crts; +} /** * Exports a PEM-formatted X.509 certificate to the specified file. * @param filename Filename to export to. Format will be PEM @@ -874,10 +928,10 @@ x509_common_name, /* Subject name */ x509_check_name, /* Check subject name */ x509_times, /* Activation/Expiration time */ + x509_importcerts_from_file, /* Multiple certificate import function */ NULL, NULL, - NULL, NULL }; diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/protocols/bonjour/jabber.c Tue Mar 30 15:27:03 2010 +0900 @@ -1185,6 +1185,9 @@ for (l = buddies; l; l = l->next) { BonjourBuddy *bb = purple_buddy_get_protocol_data((PurpleBuddy*) l->data); if (bb != NULL) { + /* Any ongoing connection attempt is cancelled + * by _purple_connection_destroy */ + bb->conversation->connect_data = NULL; bonjour_jabber_close_conversation(bb->conversation); bb->conversation = NULL; } diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/protocols/oscar/oscar.h Tue Mar 30 15:27:03 2010 +0900 @@ -344,39 +344,39 @@ OSCAR_DISCONNECT_RETRYING /* peer connections only */ } OscarDisconnectReason; -#define OSCAR_CAPABILITY_BUDDYICON 0x0000000000000001 -#define OSCAR_CAPABILITY_TALK 0x0000000000000002 -#define OSCAR_CAPABILITY_DIRECTIM 0x0000000000000004 -#define OSCAR_CAPABILITY_CHAT 0x0000000000000008 -#define OSCAR_CAPABILITY_GETFILE 0x0000000000000010 -#define OSCAR_CAPABILITY_SENDFILE 0x0000000000000020 -#define OSCAR_CAPABILITY_GAMES 0x0000000000000040 -#define OSCAR_CAPABILITY_ADDINS 0x0000000000000080 -#define OSCAR_CAPABILITY_SENDBUDDYLIST 0x0000000000000100 -#define OSCAR_CAPABILITY_GAMES2 0x0000000000000200 -#define OSCAR_CAPABILITY_ICQ_DIRECT 0x0000000000000400 -#define OSCAR_CAPABILITY_APINFO 0x0000000000000800 -#define OSCAR_CAPABILITY_ICQRTF 0x0000000000001000 -#define OSCAR_CAPABILITY_EMPTY 0x0000000000002000 -#define OSCAR_CAPABILITY_ICQSERVERRELAY 0x0000000000004000 -#define OSCAR_CAPABILITY_UNICODEOLD 0x0000000000008000 -#define OSCAR_CAPABILITY_TRILLIANCRYPT 0x0000000000010000 -#define OSCAR_CAPABILITY_UNICODE 0x0000000000020000 -#define OSCAR_CAPABILITY_INTEROPERATE 0x0000000000040000 -#define OSCAR_CAPABILITY_SHORTCAPS 0x0000000000080000 -#define OSCAR_CAPABILITY_HIPTOP 0x0000000000100000 -#define OSCAR_CAPABILITY_SECUREIM 0x0000000000200000 -#define OSCAR_CAPABILITY_SMS 0x0000000000400000 -#define OSCAR_CAPABILITY_VIDEO 0x0000000000800000 -#define OSCAR_CAPABILITY_ICHATAV 0x0000000001000000 -#define OSCAR_CAPABILITY_LIVEVIDEO 0x0000000002000000 -#define OSCAR_CAPABILITY_CAMERA 0x0000000004000000 -#define OSCAR_CAPABILITY_ICHAT_SCREENSHARE 0x0000000008000000 -#define OSCAR_CAPABILITY_TYPING 0x0000000010000000 -#define OSCAR_CAPABILITY_NEWCAPS 0x0000000020000000 -#define OSCAR_CAPABILITY_XTRAZ 0x0000000040000000 -#define OSCAR_CAPABILITY_GENERICUNKNOWN 0x0000000080000000 -#define OSCAR_CAPABILITY_LAST 0x0000000100000000 +#define OSCAR_CAPABILITY_BUDDYICON 0x0000000000000001LL +#define OSCAR_CAPABILITY_TALK 0x0000000000000002LL +#define OSCAR_CAPABILITY_DIRECTIM 0x0000000000000004LL +#define OSCAR_CAPABILITY_CHAT 0x0000000000000008LL +#define OSCAR_CAPABILITY_GETFILE 0x0000000000000010LL +#define OSCAR_CAPABILITY_SENDFILE 0x0000000000000020LL +#define OSCAR_CAPABILITY_GAMES 0x0000000000000040LL +#define OSCAR_CAPABILITY_ADDINS 0x0000000000000080LL +#define OSCAR_CAPABILITY_SENDBUDDYLIST 0x0000000000000100LL +#define OSCAR_CAPABILITY_GAMES2 0x0000000000000200LL +#define OSCAR_CAPABILITY_ICQ_DIRECT 0x0000000000000400LL +#define OSCAR_CAPABILITY_APINFO 0x0000000000000800LL +#define OSCAR_CAPABILITY_ICQRTF 0x0000000000001000LL +#define OSCAR_CAPABILITY_EMPTY 0x0000000000002000LL +#define OSCAR_CAPABILITY_ICQSERVERRELAY 0x0000000000004000LL +#define OSCAR_CAPABILITY_UNICODEOLD 0x0000000000008000LL +#define OSCAR_CAPABILITY_TRILLIANCRYPT 0x0000000000010000LL +#define OSCAR_CAPABILITY_UNICODE 0x0000000000020000LL +#define OSCAR_CAPABILITY_INTEROPERATE 0x0000000000040000LL +#define OSCAR_CAPABILITY_SHORTCAPS 0x0000000000080000LL +#define OSCAR_CAPABILITY_HIPTOP 0x0000000000100000LL +#define OSCAR_CAPABILITY_SECUREIM 0x0000000000200000LL +#define OSCAR_CAPABILITY_SMS 0x0000000000400000LL +#define OSCAR_CAPABILITY_VIDEO 0x0000000000800000LL +#define OSCAR_CAPABILITY_ICHATAV 0x0000000001000000LL +#define OSCAR_CAPABILITY_LIVEVIDEO 0x0000000002000000LL +#define OSCAR_CAPABILITY_CAMERA 0x0000000004000000LL +#define OSCAR_CAPABILITY_ICHAT_SCREENSHARE 0x0000000008000000LL +#define OSCAR_CAPABILITY_TYPING 0x0000000010000000LL +#define OSCAR_CAPABILITY_NEWCAPS 0x0000000020000000LL +#define OSCAR_CAPABILITY_XTRAZ 0x0000000040000000LL +#define OSCAR_CAPABILITY_GENERICUNKNOWN 0x0000000080000000LL +#define OSCAR_CAPABILITY_LAST 0x0000000100000000LL /* * Byte Stream type. Sort of. diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/protocols/qq/qq.c --- a/libpurple/protocols/qq/qq.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/protocols/qq/qq.c Tue Mar 30 15:27:03 2010 +0900 @@ -221,6 +221,9 @@ qd->connect_watcher = 0; } + /* This is cancelled by _purple_connection_destroy */ + qd->conn_data = NULL; + qq_disconnect(gc); if (qd->redirect) g_free(qd->redirect); diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/savedstatuses.c --- a/libpurple/savedstatuses.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/savedstatuses.c Tue Mar 30 15:27:03 2010 +0900 @@ -436,12 +436,12 @@ * And I can always make them smile * From White Castle to the Nile * - * markdoliner + * markdoliner * available * The ladies man is here to answer your queries. * * - * giantgraypanda + * giantgraypanda * away * A.C. ain't in charge no more. * diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/util.c --- a/libpurple/util.c Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/util.c Tue Mar 30 15:27:03 2010 +0900 @@ -1959,13 +1959,14 @@ } } - /* Check for tags which should be mapped to newline */ - else if (g_ascii_strncasecmp(str2 + i, "

", 3) == 0 - || g_ascii_strncasecmp(str2 + i, "", 3) == 0 + || g_ascii_strncasecmp(str2 + i, "", 8) == 0) { str2[j++] = '\n'; diff -r fdeb9a9543ce -r 70b0f46f2966 libpurple/util.h --- a/libpurple/util.h Thu Mar 25 18:03:55 2010 +0900 +++ b/libpurple/util.h Tue Mar 30 15:27:03 2010 +0900 @@ -1429,6 +1429,10 @@ /** * This is added temporarily to assist the split of oscar into aim and icq. * This should not be used by plugins. + * + * @deprecated This function should not be used in new code and should be + * removed in 3.0.0. The aim/icq prpl split happened a long + * time ago, and we don't need to keep migrating old data. */ const char *_purple_oscar_convert(const char *act, const char *protocol); diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/gtkblist.c Tue Mar 30 15:27:03 2010 +0900 @@ -123,7 +123,6 @@ PidginMiniDialog *signed_on_elsewhere; PidginBlistTheme *current_theme; - } PidginBuddyListPrivate; #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \ @@ -2235,8 +2234,8 @@ return FALSE; } - add_buddies_from_vcard("prpl-oscar", group, aims, alias); - add_buddies_from_vcard("prpl-oscar", group, icqs, alias); + add_buddies_from_vcard("prpl-aim", group, aims, alias); + add_buddies_from_vcard("prpl-icq", group, icqs, alias); add_buddies_from_vcard("prpl-yahoo", group, yahoos, alias); add_buddies_from_vcard("prpl-msn", group, msns, alias); add_buddies_from_vcard("prpl-jabber", group, jabbers, alias); @@ -3410,7 +3409,7 @@ update_status_with_mood(PurpleAccount *account, const gchar *mood, const gchar *text) { - if (mood != NULL && !purple_strequal(mood, "")) { + if (mood && *mood) { if (text) { purple_account_set_status(account, "mood", TRUE, PURPLE_MOOD_NAME, mood, @@ -3429,20 +3428,27 @@ static void edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields) { - PurpleRequestField *mood_field, *text_field; + PurpleRequestField *mood_field; GList *l; mood_field = purple_request_fields_get_field(fields, "mood"); - text_field = purple_request_fields_get_field(fields, "text"); l = purple_request_field_list_get_selected(mood_field); if (l) { const char *mood = purple_request_field_list_get_data(mood_field, l->data); - const char *text = purple_request_field_string_get_value(text_field); if (gc) { + const char *text; PurpleAccount *account = purple_connection_get_account(gc); + if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) { + PurpleRequestField *text_field; + text_field = purple_request_fields_get_field(fields, "text"); + text = purple_request_field_string_get_value(text_field); + } else { + text = NULL; + } + update_status_with_mood(account, mood, text); } else { GList *accounts = purple_accounts_get_all_active(); @@ -3451,8 +3457,8 @@ PurpleAccount *account = (PurpleAccount *) accounts->data; PurpleConnection *gc = purple_account_get_connection(account); - if (gc->flags && PURPLE_CONNECTION_SUPPORT_MOODS) { - update_status_with_mood(account, mood, text); + if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) { + update_status_with_mood(account, mood, NULL); } } } @@ -3472,9 +3478,9 @@ get_global_moods(void) { GHashTable *global_moods = - g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); GHashTable *mood_counts = - g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); GList *accounts = purple_accounts_get_all_active(); PurpleMood *result = NULL; GList *out_moods = NULL; @@ -3489,16 +3495,19 @@ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); PurpleMood *mood = NULL; - + + /* PURPLE_CONNECTION_SUPPORT_MOODS would not be set if the prpl doesn't + * have get_moods, so using PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary + * here */ for (mood = prpl_info->get_moods(account) ; mood->mood != NULL ; mood++) { int mood_count = GPOINTER_TO_INT(g_hash_table_lookup(mood_counts, mood->mood)); if (!g_hash_table_lookup(global_moods, mood->mood)) { - g_hash_table_insert(global_moods, g_strdup(mood->mood), mood); + g_hash_table_insert(global_moods, (gpointer)mood->mood, mood); } - g_hash_table_insert(mood_counts, g_strdup(mood->mood), + g_hash_table_insert(mood_counts, (gpointer)mood->mood, GINT_TO_POINTER(mood_count + 1)); } @@ -3591,6 +3600,9 @@ purple_request_field_list_add_selected(f, _("None")); /* TODO: rlaager wants this sorted. */ + /* The connection is checked for PURPLE_CONNECTION_SUPPORT_MOODS flag before + * this function is called for a non-null account. So using + * PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary here */ for (mood = account ? prpl_info->get_moods(account) : global_moods; mood->mood != NULL ; mood++) { char *path; @@ -8158,22 +8170,12 @@ PURPLE_PLUGIN_HAS_ACTIONS(plugin))) { if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) && gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) { - GList *types; - - for (types = purple_account_get_status_types(account); - types != NULL ; types = types->next) { - PurpleStatusType *type = types->data; - - if (strcmp(purple_status_type_get_id(type), "mood") != 0) - continue; - + + if (purple_account_get_status(account, "mood")) { menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood...")); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(set_mood_cb), account); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - - /* Be safe. It shouldn't match more than once anyway */ - break; } } if (PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/gtkutils.c Tue Mar 30 15:27:03 2010 +0900 @@ -2332,7 +2332,9 @@ return dialog->icon_filesel; } - +/** + * @return True if any string from array a exists in array b. + */ static gboolean str_array_match(char **a, char **b) { @@ -2351,165 +2353,171 @@ pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len) { PurplePluginProtocolInfo *prpl_info; + PurpleBuddyIconSpec *spec; + int orig_width, orig_height, new_width, new_height; + GdkPixbufFormat *format; + char **pixbuf_formats; char **prpl_formats; - int width, height; - char **pixbuf_formats = NULL; - GdkPixbufFormat *format; - GdkPixbuf *pixbuf; + GError *error = NULL; gchar *contents; gsize length; + GdkPixbuf *pixbuf, *original; + float scale_factor; + int i; + gchar *tmp; prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); - - g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL); - - - format = gdk_pixbuf_get_file_info(path, &width, &height); - - if (format == NULL) + spec = &prpl_info->icon_spec; + g_return_val_if_fail(spec->format != NULL, NULL); + + format = gdk_pixbuf_get_file_info(path, &orig_width, &orig_height); + if (format == NULL) { + purple_debug_warning("buddyicon", "Could not get file info of %s\n", path); return NULL; + } pixbuf_formats = gdk_pixbuf_format_get_extensions(format); - prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0); - if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ - (!(prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ - (prpl_info->icon_spec.min_width <= width && - prpl_info->icon_spec.max_width >= width && - prpl_info->icon_spec.min_height <= height && - prpl_info->icon_spec.max_height >= height))) /* The icon is the correct size */ + prpl_formats = g_strsplit(spec->format, ",", 0); + + if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ + (!(spec->scale_rules & PURPLE_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ + (spec->min_width <= orig_width && spec->max_width >= orig_width && + spec->min_height <= orig_height && spec->max_height >= orig_height))) /* The icon is the correct size */ { - g_strfreev(prpl_formats); g_strfreev(pixbuf_formats); - /* We don't need to scale the image. */ - contents = NULL; - if (!g_file_get_contents(path, &contents, &length, NULL)) - { - g_free(contents); - return NULL; - } - } - else - { - int i; - GError *error = NULL; - GdkPixbuf *scale; - gboolean success = FALSE; - char *filename = NULL; - - g_strfreev(pixbuf_formats); - - pixbuf = gdk_pixbuf_new_from_file(path, &error); - if (error) { - purple_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message); - g_error_free(error); + if (!g_file_get_contents(path, &contents, &length, &error)) { + purple_debug_warning("buddyicon", "Could not get file contents " + "of %s: %s\n", path, error->message); g_strfreev(prpl_formats); return NULL; } - if ((prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_SEND) && - (width < prpl_info->icon_spec.min_width || - width > prpl_info->icon_spec.max_width || - height < prpl_info->icon_spec.min_height || - height > prpl_info->icon_spec.max_height)) - { - int new_width = width; - int new_height = height; - - purple_buddy_icon_get_scale_size(&prpl_info->icon_spec, &new_width, &new_height); - - scale = gdk_pixbuf_scale_simple(pixbuf, new_width, new_height, - GDK_INTERP_HYPER); - g_object_unref(G_OBJECT(pixbuf)); - pixbuf = scale; + if (spec->max_filesize == 0 || length < spec->max_filesize) { + /* The supplied image fits the file size, dimensions and type + constraints. Great! Return it without making any changes. */ + if (len) + *len = length; + g_strfreev(prpl_formats); + return contents; } + /* The image was too big. Fall-through and try scaling it down. */ + g_free(contents); + } else { + g_strfreev(pixbuf_formats); + } + + /* The original image wasn't compatible. Scale it or convert file type. */ + pixbuf = gdk_pixbuf_new_from_file(path, &error); + if (error) { + purple_debug_warning("buddyicon", "Could not open icon '%s' for " + "conversion: %s\n", path, error->message); + g_error_free(error); + g_strfreev(prpl_formats); + return NULL; + } + original = g_object_ref(G_OBJECT(pixbuf)); + + new_width = orig_width; + new_height = orig_height; + + /* Make sure the image is the correct dimensions */ + if (spec->scale_rules & PURPLE_ICON_SCALE_SEND && + (orig_width < spec->min_width || orig_width > spec->max_width || + orig_height < spec->min_height || orig_height > spec->max_height)) + { + purple_buddy_icon_get_scale_size(spec, &new_width, &new_height); + + g_object_unref(G_OBJECT(pixbuf)); + pixbuf = gdk_pixbuf_scale_simple(original, new_width, new_height, GDK_INTERP_HYPER); + } + + scale_factor = 1; + do { for (i = 0; prpl_formats[i]; i++) { - FILE *fp; - - g_free(filename); - fp = purple_mkstemp(&filename, TRUE); - if (!fp) - { - g_free(filename); - return NULL; - } - fclose(fp); - - purple_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); - /* The "compression" param wasn't supported until gdk-pixbuf 2.8. - * Using it in previous versions causes the save to fail (and an assert message). */ - if ((gdk_pixbuf_major_version > 2 || (gdk_pixbuf_major_version == 2 - && gdk_pixbuf_minor_version >= 8)) - && strcmp(prpl_formats[i], "png") == 0) { - if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], - &error, "compression", "9", NULL)) { - success = TRUE; + int quality = 100; + do { + const char *key = NULL; + const char *value = NULL; + gchar tmp_buf[4]; + + purple_debug_info("buddyicon", "Converting buddy icon to %s\n", prpl_formats[i]); + + if (g_str_equal(prpl_formats[i], "png")) { + key = "compression"; + value = "9"; + } else if (g_str_equal(prpl_formats[i], "jpeg")) { + sprintf(tmp_buf, "%u", quality); + key = "quality"; + value = tmp_buf; + } + + if (!gdk_pixbuf_save_to_buffer(pixbuf, &contents, &length, + prpl_formats[i], &error, key, value, NULL)) + { + /* The NULL checking of error is necessary due to this bug: + * http://bugzilla.gnome.org/show_bug.cgi?id=405539 */ + purple_debug_warning("buddyicon", + "Could not convert to %s: %s\n", prpl_formats[i], + (error && error->message) ? error->message : "Unknown error"); + g_error_free(error); + error = NULL; + + /* We couldn't convert to this image type. Try the next + image type. */ break; } - } else if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], - &error, NULL)) { - success = TRUE; - break; - } - - /* The NULL checking is necessary due to this bug: - * http://bugzilla.gnome.org/show_bug.cgi?id=405539 */ - purple_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], - (error && error->message) ? error->message : "Unknown error"); - g_error_free(error); - error = NULL; - } - g_strfreev(prpl_formats); - g_object_unref(G_OBJECT(pixbuf)); - if (!success) { - purple_debug_error("buddyicon", "Could not convert icon to usable format.\n"); - g_free(filename); - return NULL; - } - - contents = NULL; - if (!g_file_get_contents(filename, &contents, &length, NULL)) - { - purple_debug_error("buddyicon", - "Could not read '%s', which we just wrote to disk.\n", - filename); - - g_free(contents); - g_free(filename); - return NULL; + + if (spec->max_filesize == 0 || length < spec->max_filesize) { + /* We were able to save the image as this image type and + have it be within the size constraints. Great! Return + the image. */ + purple_debug_info("buddyicon", "Converted image from " + "%dx%d to %dx%d, format=%s, quality=%u, " + "filesize=%zu\n", orig_width, orig_height, + new_width, new_height, prpl_formats[i], quality, + length); + if (len) + *len = length; + g_strfreev(prpl_formats); + g_object_unref(G_OBJECT(pixbuf)); + g_object_unref(G_OBJECT(original)); + return contents; + } + + g_free(contents); + + if (!g_str_equal(prpl_formats[i], "jpeg")) { + /* File size was too big and we can't lower the quality, + so skip to the next image type. */ + break; + } + + /* File size was too big, but we're dealing with jpeg so try + lowering the quality. */ + quality -= 5; + } while (quality >= 70); } - g_unlink(filename); - g_free(filename); - } - - /* Check the image size */ - /* - * TODO: If the file is too big, it would be cool if we checked if - * the prpl supported jpeg, and then we could convert to that - * and use a lower quality setting. - */ - if ((prpl_info->icon_spec.max_filesize != 0) && - (length > prpl_info->icon_spec.max_filesize)) - { - gchar *tmp; - tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"), - path, plugin->info->name); - purple_notify_error(NULL, _("Icon Error"), - _("Could not set icon"), tmp); - purple_debug_info("buddyicon", - "'%s' was converted to an image which is %" G_GSIZE_FORMAT - " bytes, but the maximum icon size for %s is %" G_GSIZE_FORMAT - " bytes\n", path, length, plugin->info->name, - prpl_info->icon_spec.max_filesize); - g_free(tmp); - return NULL; - } - - if (len) - *len = length; - return contents; + /* We couldn't save the image in any format that was below the max + file size. Maybe we can reduce the image dimensions? */ + scale_factor *= 0.8; + new_width = orig_width * scale_factor; + new_height = orig_height * scale_factor; + g_object_unref(G_OBJECT(pixbuf)); + pixbuf = gdk_pixbuf_scale_simple(original, new_width, new_height, GDK_INTERP_HYPER); + } while (new_width > 10 || new_height > 10); + g_strfreev(prpl_formats); + g_object_unref(G_OBJECT(pixbuf)); + g_object_unref(G_OBJECT(original)); + + tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"), + path, plugin->info->name); + purple_notify_error(NULL, _("Icon Error"), _("Could not set icon"), tmp); + g_free(tmp); + + return NULL; } void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename) diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/plugins/gevolution/add_buddy_dialog.c --- a/pidgin/plugins/gevolution/add_buddy_dialog.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/plugins/gevolution/add_buddy_dialog.c Tue Mar 30 15:27:03 2010 +0900 @@ -314,13 +314,11 @@ } else { - add_ims(dialog, contact, name, aims, "prpl-oscar"); add_ims(dialog, contact, name, aims, "prpl-aim"); add_ims(dialog, contact, name, jabbers, "prpl-jabber"); add_ims(dialog, contact, name, yahoos, "prpl-yahoo"); add_ims(dialog, contact, name, msns, "prpl-msn"); add_ims(dialog, contact, name, icqs, "prpl-icq"); - add_ims(dialog, contact, name, icqs, "prpl-oscar"); add_ims(dialog, contact, name, novells, "prpl-novell"); } } @@ -399,12 +397,10 @@ else { add_ims(dialog, contact, name, aims, "prpl-aim"); - add_ims(dialog, contact, name, aims, "prpl-oscar"); add_ims(dialog, contact, name, jabbers, "prpl-jabber"); add_ims(dialog, contact, name, yahoos, "prpl-yahoo"); add_ims(dialog, contact, name, msns, "prpl-msn"); add_ims(dialog, contact, name, icqs, "prpl-icq"); - add_ims(dialog, contact, name, icqs, "prpl-oscar"); add_ims(dialog, contact, name, novells, "prpl-novell"); } } diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/plugins/gevolution/gevo-util.c --- a/pidgin/plugins/gevolution/gevo-util.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/plugins/gevolution/gevo-util.c Tue Mar 30 15:27:03 2010 +0900 @@ -99,23 +99,7 @@ protocol_id = purple_account_get_protocol_id(account); - if (!strcmp(protocol_id, "prpl-oscar")) - { - PurpleConnection *gc; - PurplePluginProtocolInfo *prpl_info; - - gc = purple_account_get_connection(account); - - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); - - if (!strcmp("aim", prpl_info->list_icon(account, buddy))) - { - protocol_field = E_CONTACT_IM_AIM; - } - else - protocol_field = E_CONTACT_IM_ICQ; - } - else if (!strcmp(protocol_id, "prpl-aim")) + if (!strcmp(protocol_id, "prpl-aim")) protocol_field = E_CONTACT_IM_AIM; else if (!strcmp(protocol_id, "prpl-icq")) protocol_field = E_CONTACT_IM_ICQ; diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/plugins/gevolution/gevolution.c --- a/pidgin/plugins/gevolution/gevolution.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/plugins/gevolution/gevolution.c Tue Mar 30 15:27:03 2010 +0900 @@ -111,12 +111,10 @@ name = e_contact_get_const(contact, E_CONTACT_FULL_NAME); update_ims_from_contact(contact, name, "prpl-aim", E_CONTACT_IM_AIM); - update_ims_from_contact(contact, name, "prpl-oscar", E_CONTACT_IM_AIM); update_ims_from_contact(contact, name, "prpl-jabber", E_CONTACT_IM_JABBER); update_ims_from_contact(contact, name, "prpl-yahoo", E_CONTACT_IM_YAHOO); update_ims_from_contact(contact, name, "prpl-msn", E_CONTACT_IM_MSN); update_ims_from_contact(contact, name, "prpl-icq", E_CONTACT_IM_ICQ); - update_ims_from_contact(contact, name, "prpl-oscar", E_CONTACT_IM_ICQ); update_ims_from_contact(contact, name, "prpl-novell", E_CONTACT_IM_GROUPWISE); } diff -r fdeb9a9543ce -r 70b0f46f2966 pidgin/plugins/gevolution/new_person_dialog.c --- a/pidgin/plugins/gevolution/new_person_dialog.c Thu Mar 25 18:03:55 2010 +0900 +++ b/pidgin/plugins/gevolution/new_person_dialog.c Tue Mar 30 15:27:03 2010 +0900 @@ -141,14 +141,7 @@ if (*email) e_contact_set(contact, E_CONTACT_EMAIL_1, (gpointer)email); - if (!strcmp(im_service, "prpl-oscar")) - { - if (isdigit(*username)) - field = E_CONTACT_IM_ICQ; - else - field = E_CONTACT_IM_AIM; - } - else if (!strcmp(im_service, "prpl-aim")) + if (!strcmp(im_service, "prpl-aim")) field = E_CONTACT_IM_AIM; else if (!strcmp(im_service, "prpl-icq")) field = E_CONTACT_IM_ICQ; diff -r fdeb9a9543ce -r 70b0f46f2966 po/POTFILES.in --- a/po/POTFILES.in Thu Mar 25 18:03:55 2010 +0900 +++ b/po/POTFILES.in Tue Mar 30 15:27:03 2010 +0900 @@ -95,6 +95,7 @@ libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/chat.c libpurple/protocols/jabber/jabber.c +libpurple/protocols/jabber/jutil.c libpurple/protocols/jabber/libxmpp.c libpurple/protocols/jabber/message.c libpurple/protocols/jabber/parser.c