Mercurial > pidgin
changeset 25676:394252b681bc
propagate from branch 'im.pidgin.pidgin' (head be64dc9cd9d255a5a6a0f790f5fc505091313e6d)
to branch 'im.pidgin.cpw.darkrain42.xmpp.bosh' (head 6ea1275dfc036db492ab63dcbef17f47a40a94d7)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Tue, 17 Feb 2009 03:39:22 +0000 |
parents | 6a369035fd20 (current diff) 93463c6114aa (diff) |
children | 7d2e85f78aec |
files | libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/jabber.c |
diffstat | 35 files changed, 345 insertions(+), 152 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Tue Feb 10 06:42:42 2009 +0000 +++ b/COPYRIGHT Tue Feb 17 03:39:22 2009 +0000 @@ -14,6 +14,7 @@ Patrick Aussems Anibal Avelar Ali Albazaz +Kosta Arvanitis Christopher Ayoup Alex Badea John Bailey @@ -66,6 +67,7 @@ Ludovico Cavedon Steve Cavilia Julien Cegarra +Matěj Cepl Cerulean Studios, LLC Jonathan Champ Christophe Chapuis @@ -204,6 +206,7 @@ Intel Corporation Scott Jackson Hans Petter Jansson +David Jedelsky Henry Jen Benjamin Kahn Anders Kaseorg @@ -212,6 +215,7 @@ John Kelm Jochen Kemnade Yann Kerherve +Gordian Klein Akuke Kok Kir Kolyshkin Konstantin Korikov @@ -418,6 +422,7 @@ Andreas Stührk Oleg Sukhodolsky Sun Microsystems +Marcus Sundberg Mårten Svantesson (fursten) Amir Szekely (kichik) Robert T.
--- a/ChangeLog Tue Feb 10 06:42:42 2009 +0000 +++ b/ChangeLog Tue Feb 17 03:39:22 2009 +0000 @@ -7,6 +7,8 @@ enable, check the "Use SSL" option from the Advanced tab when editing your AIM or ICQ account. (Paul Aurich) * Fix a memory leak in SILC. (Luke Petre) + * Fix some string handling in the SIMPLE prpl, which fixes some buddy name + handling and other issues. (Paul Aurich, Marcus Sundberg) ICQ: * Fix retrieval of status messages from users of ICQ 6.x, Miranda, and @@ -15,6 +17,7 @@ of buddy icons and available messages. * Properly publish status messages for statuses other than Available. ICQ 6.x users can now see these status messages. (Daniel Ljungborg) + * Fix recipt of messages from the mobile client Slick. (David Jedelsky) MSN: * Fix transfer of buddy icons, custom smileys, and files from the @@ -23,9 +26,24 @@ * Large (multi-part) messages are now correctly re-combined. * Federated/Yahoo! buddies should now stop creating sync issues at every signin. You may need to remove duplicates in the Address - Book. See the FAQ for more information. + Book. See the FAQ for more information. Thanks to Jason Lingohr + for lots of debugging and testing. * Messages from Yahoo! buddies are no longer silently dropped. + XMPP: + * Resources using __HOSTNAME__ substitution will now grab only the short + hostname instead of the FQDN on systems which put the FQDN in the + hostname. (Matěj Cepl) + * No longer send a 'to' attribute on an outgoing stanza when we haven't + received one. This fixes a registration bug as described in ticket + #6635. + + Pidgin: + * Tooltip windows now appear below the mouse cursor. (Kosta Arvanitis) + * Tooltip windows now disappear on keypress events. (Kosta Arvanitis) + * Tooltip windows no longer linger when scrolling the buddy list. (Kosta + Arvanitis) + Finch: * Allow rebinding keys to change the focused widget (details in the man-page, look for GntBox::binding)
--- a/finch/libgnt/gntwm.c Tue Feb 10 06:42:42 2009 +0000 +++ b/finch/libgnt/gntwm.c Tue Feb 17 03:39:22 2009 +0000 @@ -353,7 +353,8 @@ p->y = y; g_hash_table_replace(wm->positions, g_strdup(title + 1), p); } else { - gnt_warning("Invalid number of arguments (%d) for positioning a window.", l); + gnt_warning("Invalid number of arguments (%" G_GSIZE_FORMAT + ") for positioning a window.", l); } g_strfreev(coords); }
--- a/libpurple/account.h Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/account.h Tue Feb 17 03:39:22 2009 +0000 @@ -132,6 +132,14 @@ /* to NULL when the account inherits */ /* proxy settings from global prefs. */ + /* + * TODO: Supplementing the next two linked lists with hash tables + * should help performance a lot when these lists are long. This + * matters quite a bit for protocols like MSN, where all your + * buddies are added to your permit list. Currently we have to + * iterate through the entire list if we want to check if someone + * is permitted or denied. We should do this for 3.0.0. + */ GSList *permit; /**< Permit list. */ GSList *deny; /**< Deny list. */ int perm_deny; /**< The permit/deny setting. */
--- a/libpurple/privacy.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/privacy.c Tue Feb 17 03:39:22 2009 +0000 @@ -42,12 +42,14 @@ name = g_strdup(purple_normalize(account, who)); for (l = account->permit; l != NULL; l = l->next) { - if (!purple_utf8_strcasecmp(name, (char *)l->data)) + if (g_str_equal(name, l->data)) + /* This buddy already exists */ break; } if (l != NULL) { + /* This buddy already exists, so bail out */ g_free(name); return FALSE; } @@ -86,11 +88,13 @@ name = purple_normalize(account, who); for (l = account->permit; l != NULL; l = l->next) { - if (!purple_utf8_strcasecmp(name, (char *)l->data)) + if (g_str_equal(name, l->data)) + /* We found the buddy we were looking for */ break; } if (l == NULL) + /* We didn't find the buddy we were looking for, so bail out */ return FALSE; /* We should not free l->data just yet. There can be occasions where @@ -130,12 +134,14 @@ name = g_strdup(purple_normalize(account, who)); for (l = account->deny; l != NULL; l = l->next) { - if (!purple_utf8_strcasecmp(name, purple_normalize(account, (char *)l->data))) + if (g_str_equal(name, l->data)) + /* This buddy already exists */ break; } if (l != NULL) { + /* This buddy already exists, so bail out */ g_free(name); return FALSE; } @@ -173,14 +179,16 @@ normalized = purple_normalize(account, who); for (l = account->deny; l != NULL; l = l->next) { - if (!purple_utf8_strcasecmp(normalized, (char *)l->data)) + if (g_str_equal(normalized, l->data)) + /* We found the buddy we were looking for */ break; } - buddy = purple_find_buddy(account, normalized); + if (l == NULL) + /* We didn't find the buddy we were looking for, so bail out */ + return FALSE; - if (l == NULL) - return FALSE; + buddy = purple_find_buddy(account, normalized); name = l->data; account->deny = g_slist_delete_link(account->deny, l); @@ -349,7 +357,7 @@ case PURPLE_PRIVACY_ALLOW_USERS: who = purple_normalize(account, who); for (list=account->permit; list!=NULL; list=list->next) { - if (!purple_utf8_strcasecmp(who, (char *)list->data)) + if (g_str_equal(who, list->data)) return TRUE; } return FALSE; @@ -357,7 +365,7 @@ case PURPLE_PRIVACY_DENY_USERS: who = purple_normalize(account, who); for (list=account->deny; list!=NULL; list=list->next) { - if (!purple_utf8_strcasecmp(who, (char *)list->data )) + if (g_str_equal(who, list->data)) return FALSE; } return TRUE;
--- a/libpurple/protocols/jabber/adhoccommands.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/jabber/adhoccommands.c Tue Feb 17 03:39:22 2009 +0000 @@ -229,7 +229,7 @@ JabberAdHocCommands *cmd = js->commands->data; g_free(cmd->jid); g_free(cmd->node); - g_free(cmd->node); + g_free(cmd->name); g_free(cmd); js->commands = g_list_delete_link(js->commands, js->commands); }
--- a/libpurple/protocols/jabber/buddy.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/jabber/buddy.c Tue Feb 17 03:39:22 2009 +0000 @@ -1783,7 +1783,7 @@ if (!jid) return; - if (jabber_chat_find(js, jid->node, jid->domain)) { + if (jid->node && jabber_chat_find(js, jid->node, jid->domain)) { /* For a conversation, include the resource (indicates the user). */ jabber_buddy_get_info_for_jid(js, who); } else {
--- a/libpurple/protocols/jabber/jabber.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Tue Feb 17 03:39:22 2009 +0000 @@ -151,7 +151,8 @@ } static char *jabber_prep_resource(char *input) { - char hostname[256]; /* current hostname */ + char hostname[256], /* current hostname */ + *dot = NULL; /* Empty resource == don't send any */ if (input == NULL || *input == '\0') @@ -173,6 +174,12 @@ } hostname[sizeof(hostname) - 1] = '\0'; + /* We want only the short hostname, not the FQDN - this will prevent the + * resource string from being unreasonably long on systems which stuff the + * whole FQDN in the hostname */ + if((dot = strchr(hostname, '.'))) + dot = '\0'; + return purple_strreplace(input, "__HOSTNAME__", hostname); } @@ -860,10 +867,11 @@ js->user->node, js->user->domain); if(account->registration_cb) (account->registration_cb)(account, TRUE, account->registration_cb_user_data); - } - else + } else { + g_return_if_fail(to != NULL); buf = g_strdup_printf(_("Registration to %s successful"), to); + } purple_notify_info(NULL, _("Registration Successful"), _("Registration Successful"), buf); g_free(buf); @@ -890,7 +898,11 @@ const char *type = xmlnode_get_attrib(packet, "type"); char *buf; char *to = data; - + + /* This function is never called for unregistering our XMPP account from + * the server, so there should always be a 'to' address. */ + g_return_if_fail(to != NULL); + if(!strcmp(type, "result")) { buf = g_strdup_printf(_("Registration from %s successfully removed"), to); @@ -925,7 +937,8 @@ iq = jabber_iq_new_query(cbdata->js, JABBER_IQ_SET, "jabber:iq:register"); query = xmlnode_get_child(iq->node, "query"); - xmlnode_set_attrib(iq->node, "to", cbdata->who); + if (cbdata->who) + xmlnode_set_attrib(iq->node, "to", cbdata->who); for(groups = purple_request_fields_get_groups(fields); groups; groups = groups->next) { @@ -941,7 +954,8 @@ jabber_iq_free(iq); iq = jabber_iq_new_query(cbdata->js, JABBER_IQ_SET, "jabber:iq:register"); query = xmlnode_get_child(iq->node, "query"); - xmlnode_set_attrib(iq->node,"to",cbdata->who); + if (cbdata->who) + xmlnode_set_attrib(iq->node,"to",cbdata->who); xmlnode_new_child(query, "remove"); jabber_iq_set_callback(iq, jabber_unregistration_result_cb, cbdata->who); @@ -986,8 +1000,7 @@ } xmlnode_insert_data(y, value, -1); if(cbdata->js->registration && !strcmp(id, "username")) { - if(cbdata->js->user->node) - g_free(cbdata->js->user->node); + g_free(cbdata->js->user->node); cbdata->js->user->node = g_strdup(value); } if(cbdata->js->registration && !strcmp(id, "password")) @@ -1030,7 +1043,8 @@ iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); query = xmlnode_get_child(iq->node, "query"); - xmlnode_set_attrib(iq->node,"to",to); + if (to) + xmlnode_set_attrib(iq->node,"to",to); xmlnode_insert_child(query, result); @@ -1055,10 +1069,7 @@ return; from = xmlnode_get_attrib(packet, "from"); - if (!from) - from = js->serverFQDN; - g_return_if_fail(from != NULL); - + if(js->registration) { /* get rid of the login thingy */ purple_connection_set_state(js->gc, PURPLE_CONNECTED); @@ -1079,11 +1090,11 @@ } } - if((x = xmlnode_get_child_with_namespace(packet, "x", "jabber:x:data"))) { + if((x = xmlnode_get_child_with_namespace(query, "x", "jabber:x:data"))) { jabber_x_data_request(js, x, jabber_register_x_data_cb, g_strdup(from)); return; - } else if((x = xmlnode_get_child_with_namespace(packet, "x", "jabber:x:oob"))) { + } else if((x = xmlnode_get_child_with_namespace(query, "x", "jabber:x:oob"))) { xmlnode *url; if((url = xmlnode_get_child(x, "url"))) { @@ -1203,7 +1214,9 @@ purple_connection_get_account(js->gc), NULL, NULL, cbdata); else { - char *title = registered?g_strdup_printf(_("Change Account Registration at %s"), from) + char *title; + g_return_if_fail(from != NULL); + title = registered ? g_strdup_printf(_("Change Account Registration at %s"), from) :g_strdup_printf(_("Register New Account at %s"), from); purple_request_fields(js->gc, title, title, instructions, fields,
--- a/libpurple/protocols/msn/contact.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/contact.c Tue Feb 17 03:39:22 2009 +0000 @@ -198,6 +198,8 @@ MsnCallbackState *state = data; xmlnode *fault; char *faultcode_str; + xmlnode *cachekey; + char *changed; if (resp == NULL) { purple_debug_error("msn", @@ -206,12 +208,27 @@ return; } + /* Update CacheKey if necessary */ + cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKeyChanged"); + if (cachekey != NULL) { + changed = xmlnode_get_data(cachekey); + if (changed && !strcmp(changed, "true")) { + cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKey"); + g_free(state->session->abch_cachekey); + state->session->abch_cachekey = xmlnode_get_data(cachekey); + purple_debug_info("msn", "Updated CacheKey for %s to '%s'.\n", + purple_account_get_username(state->session->account), + state->session->abch_cachekey); + } + g_free(changed); + } + fault = xmlnode_get_child(resp->xml, "Body/Fault"); if (fault == NULL) { /* No errors */ if (state->cb) - ((MsnSoapCallback)state->cb)(req, resp, data); + state->cb(req, resp, data); msn_callback_state_free(state); return; } @@ -230,7 +247,7 @@ else { if (state->cb) { - ((MsnSoapCallback)state->cb)(req, resp, data); + state->cb(req, resp, data); } else { /* We don't know how to respond to this faultcode, so log it */ char *str = xmlnode_to_str(fault, NULL); @@ -247,6 +264,14 @@ static gboolean msn_contact_request(MsnCallbackState *state) { + xmlnode *cachekey = xmlnode_get_child(state->body, + "Header/ABApplicationHeader/CacheKey"); + if (cachekey != NULL) + xmlnode_free(cachekey); + if (state->session->abch_cachekey != NULL) { + cachekey = xmlnode_new_child(xmlnode_get_child(state->body, "Header/ABApplicationHeader"), "CacheKey"); + xmlnode_insert_data(cachekey, state->session->abch_cachekey, -1); + } if (state->token == NULL) state->token = xmlnode_get_child(state->body, "Header/ABAuthHeader/TicketToken");
--- a/libpurple/protocols/msn/msg.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/msg.c Tue Feb 17 03:39:22 2009 +0000 @@ -80,7 +80,7 @@ msg->ref_count++; #ifdef MSN_DEBUG_MSG - purple_debug_info("msn", "message ref (%p)[%d]\n", msg, msg->ref_count); + purple_debug_info("msn", "message ref (%p)[%" G_GSIZE_FORMAT "]\n", msg, msg->ref_count); #endif return msg; @@ -95,7 +95,7 @@ msg->ref_count--; #ifdef MSN_DEBUG_MSG - purple_debug_info("msn", "message unref (%p)[%d]\n", msg, msg->ref_count); + purple_debug_info("msn", "message unref (%p)[%" G_GSIZE_FORMAT "]\n", msg, msg->ref_count); #endif if (msg->ref_count == 0) @@ -352,6 +352,14 @@ memcpy(msg->body, tmp, msg->body_len); msg->body[msg->body_len] = '\0'; } + + if (msg->charset == NULL) { + char *body = g_convert(msg->body, msg->body_len, "UTF-8", + "ISO-8859-1", NULL, &msg->body_len, NULL); + g_free(msg->body); + msg->body = body; + msg->charset = g_strdup("UTF-8"); + } } g_free(tmp_base);
--- a/libpurple/protocols/msn/msnutils.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/msnutils.c Tue Feb 17 03:39:22 2009 +0000 @@ -446,7 +446,7 @@ } if (fontface == NULL) - fontface = g_strdup("MS Sans Serif"); + fontface = g_strdup("Segoe UI"); *attributes = g_strdup_printf("FN=%s; EF=%s; CO=%s; PF=0; RL=%c", encode_spaces(fontface),
--- a/libpurple/protocols/msn/nexus.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/nexus.c Tue Feb 17 03:39:22 2009 +0000 @@ -74,6 +74,7 @@ for (i = 0; i < nexus->token_len; i++) { g_hash_table_destroy(nexus->tokens[i].token); g_free(nexus->tokens[i].secret); + g_slist_free(nexus->tokens[i].updates); } g_free(nexus->tokens); @@ -235,6 +236,10 @@ struct _MsnNexusUpdateData { MsnNexus *nexus; int id; +}; + +typedef struct _MsnNexusUpdateCallback MsnNexusUpdateCallback; +struct _MsnNexusUpdateCallback { GSourceFunc cb; gpointer data; }; @@ -428,6 +433,7 @@ char *nonce; gsize len; char *key; + GSList *updates; #if 0 char *decrypted_pp; @@ -489,8 +495,15 @@ g_free(decrypted_data); } - if (ud->cb) - purple_timeout_add(0, ud->cb, ud->data); + updates = nexus->tokens[ud->id].updates; + nexus->tokens[ud->id].updates = NULL; + while (updates != NULL) { + MsnNexusUpdateCallback *update = updates->data; + if (update->cb) + purple_timeout_add(0, update->cb, update->data); + g_free(update); + updates = g_slist_delete_link(updates, updates); + } g_free(ud); } @@ -500,6 +513,7 @@ { MsnSession *session = nexus->session; MsnNexusUpdateData *ud; + MsnNexusUpdateCallback *update; PurpleCipherContext *sha1; PurpleCipherContext *hmac; @@ -526,16 +540,31 @@ char *request; MsnSoapMessage *soap; - purple_debug_info("msn", - "Updating ticket for user '%s' on domain '%s'\n", - purple_account_get_username(session->account), - ticket_domains[id][SSO_VALID_TICKET_DOMAIN]); + update = g_new0(MsnNexusUpdateCallback, 1); + update->cb = cb; + update->data = data; + + if (nexus->tokens[id].updates != NULL) { + /* Update already in progress. Just add to list and return. */ + purple_debug_info("msn", + "Ticket update for user '%s' on domain '%s' in progress. Adding request to queue.\n", + purple_account_get_username(session->account), + ticket_domains[id][SSO_VALID_TICKET_DOMAIN]); + nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates, + update); + return; + } else { + purple_debug_info("msn", + "Updating ticket for user '%s' on domain '%s'\n", + purple_account_get_username(session->account), + ticket_domains[id][SSO_VALID_TICKET_DOMAIN]); + nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates, + update); + } ud = g_new0(MsnNexusUpdateData, 1); ud->nexus = nexus; ud->id = id; - ud->cb = cb; - ud->data = data; sha1 = purple_cipher_context_new_by_name("sha1", NULL);
--- a/libpurple/protocols/msn/nexus.h Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/nexus.h Tue Feb 17 03:39:22 2009 +0000 @@ -204,6 +204,7 @@ GHashTable *token; char *secret; time_t expiry; + GSList *updates; }; typedef struct _MsnNexus MsnNexus;
--- a/libpurple/protocols/msn/notification.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/notification.c Tue Feb 17 03:39:22 2009 +0000 @@ -1619,19 +1619,25 @@ return; } - psm_str = msn_get_psm(cmd->payload,len); - msn_user_set_statusline(user, psm_str); - g_free(psm_str); + if (len != 0) { + psm_str = msn_get_psm(cmd->payload,len); + msn_user_set_statusline(user, psm_str); + g_free(psm_str); - str = msn_get_currentmedia(cmd->payload, len); - if (msn_parse_currentmedia(str, &media)) - msn_user_set_currentmedia(user, &media); - else + str = msn_get_currentmedia(cmd->payload, len); + if (msn_parse_currentmedia(str, &media)) + msn_user_set_currentmedia(user, &media); + else + msn_user_set_currentmedia(user, NULL); + g_free(media.title); + g_free(media.album); + g_free(media.artist); + g_free(str); + + } else { + msn_user_set_statusline(user, NULL); msn_user_set_currentmedia(user, NULL); - g_free(media.title); - g_free(media.album); - g_free(media.artist); - g_free(str); + } msn_user_update(user); }
--- a/libpurple/protocols/msn/session.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/session.c Tue Feb 17 03:39:22 2009 +0000 @@ -90,8 +90,10 @@ msn_userlist_destroy(session->userlist); g_free(session->psm); - + g_free(session->abch_cachekey); +#if 0 g_free(session->blocked_text); +#endif g_free(session->passport_info.kv); g_free(session->passport_info.sid);
--- a/libpurple/protocols/msn/session.h Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/session.h Tue Feb 17 03:39:22 2009 +0000 @@ -94,11 +94,11 @@ gboolean http_method; MsnNotification *notification; - MsnNexus *nexus; - MsnOim *oim; - MsnSync *sync; - - MsnUserList *userlist; + MsnNexus *nexus; + MsnOim *oim; + MsnSync *sync; + MsnUserList *userlist; + char *abch_cachekey; int servconns_count; /**< The count of server connections. */ GList *switches; /**< The list of all the switchboards. */ @@ -107,7 +107,9 @@ /*psm info*/ char *psm; +#if 0 char *blocked_text; +#endif struct {
--- a/libpurple/protocols/msn/slpcall.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/slpcall.c Tue Feb 17 03:39:22 2009 +0000 @@ -47,6 +47,7 @@ if (!slpcall->pending && !slpcall->progress) { msn_slpcall_destroy(slpcall); + slpcall->timer = 0; return FALSE; } @@ -222,8 +223,10 @@ if (slpcall != NULL) { - if (slpcall->timer) + if (slpcall->timer) { purple_timeout_remove(slpcall->timer); + slpcall->timer = 0; + } slpcall->cb(slpcall, body, body_len);
--- a/libpurple/protocols/msn/transaction.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/msn/transaction.c Tue Feb 17 03:39:22 2009 +0000 @@ -199,6 +199,7 @@ if (trans->timeout_cb != NULL) trans->timeout_cb(trans->cmdproc, trans); + trans->timer = 0; return FALSE; }
--- a/libpurple/protocols/oscar/family_icbm.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Tue Feb 17 03:39:22 2009 +0000 @@ -1566,9 +1566,10 @@ static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, ByteStream *bs, guint8 *cookie) { - guint16 type, length; + guint16 type, length, magic1, msglen; aim_rxcallback_t userfunc; int ret = 0; + int rev = 0; struct aim_incomingim_ch1_args args; unsigned int endpos; @@ -1603,10 +1604,30 @@ * - 0101 -- Unknown * - Message * + * Slick and possible others reverse 'Features' and 'Messages' section. + * Thus, the TLV could have following layout: + * - 0101 -- Unknown (possibly magic for message section) + * - Message + * - 0501 -- Unknown (possibly magic for features section) + * - Features: Don't know how to interpret these */ - byte_stream_get8(bs); /* 05 */ - byte_stream_get8(bs); /* 01 */ + magic1 = byte_stream_get16(bs); /* 0501 or 0101 */ + if (magic1 == 0x101) /* Bad, message comes before attributes */ + { + /* Jump to the features section */ + msglen = byte_stream_get16(bs); + bs->offset += msglen; + rev = 1; + + magic1 = byte_stream_get16(bs); /* 0501 */ + } + + if (magic1 != 0x501) + { + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + break; + } args.featureslen = byte_stream_get16(bs); if (args.featureslen > byte_stream_empty(bs)) @@ -1624,11 +1645,25 @@ args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES; } + if (rev) + { + /* Fix buffer back to message */ + bs->offset -= args.featureslen + 2 + 2 + msglen + 2 + 2; + } + + magic1 = byte_stream_get16(bs); /* 01 01 */ + if (magic1 != 0x101) /* Bad, message comes before attributes */ + { + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + break; + } + msglen = byte_stream_get16(bs); + /* * The rest of the TLV contains one or more message * blocks... */ - incomingim_ch1_parsemsgs(od, userinfo, bs->data + bs->offset /* XXX evil!!! */, length - 2 - 2 - args.featureslen, &args); + incomingim_ch1_parsemsgs(od, userinfo, bs->data + bs->offset - 2 - 2 /* XXX evil!!! */, msglen + 2 + 2, &args); } else if (type == 0x0003) { /* Server Ack Requested */
--- a/libpurple/protocols/qq/ChangeLog Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/ChangeLog Tue Feb 17 03:39:22 2009 +0000 @@ -1,3 +1,6 @@ +2009.02.08 - flos <lonicerae(at)gmail.com> + * Fixed showing message of chat room when message comes in + 2008.12.28 - flos <lonicerae(at)gmail.com> * Fixes #7908
--- a/libpurple/protocols/qq/buddy_info.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/buddy_info.c Tue Feb 17 03:39:22 2009 +0000 @@ -108,41 +108,41 @@ } QQ_FIELD_INFO; static const QQ_FIELD_INFO field_infos[] = { - { QQ_FIELD_BASE, QQ_FIELD_STRING, "uid", N_("QQ Number"), NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_STRING, "nick", N_("Nickname"), NULL, 0 }, - { QQ_FIELD_ADDR, QQ_FIELD_STRING, "country", N_("Country/Region"), NULL, 0 }, - { QQ_FIELD_ADDR, QQ_FIELD_STRING, "province", N_("Province/State"), NULL, 0 }, - { QQ_FIELD_ADDR, QQ_FIELD_STRING, "zipcode", N_("Zipcode"), NULL, 0 }, - { QQ_FIELD_ADDR, QQ_FIELD_STRING, "address", N_("Address"), NULL, 0 }, - { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "tel", N_("Phone Number"), NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_STRING, "age", N_("Age"), NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_CHOICE, "gender", N_("Gender"), genders, QQ_GENDER_SIZE }, - { QQ_FIELD_BASE, QQ_FIELD_STRING, "name", N_("Name"), NULL, 0 }, - { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "email", N_("Email"), NULL, 0 }, - { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sn", "Pager Serial Num", NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_STRING, "uid", N_("QQ Number"), NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_STRING, "nick", N_("Nickname"), NULL, 0 }, + { QQ_FIELD_ADDR, QQ_FIELD_STRING, "country", N_("Country/Region"), NULL, 0 }, + { QQ_FIELD_ADDR, QQ_FIELD_STRING, "province", N_("Province/State"), NULL, 0 }, + { QQ_FIELD_ADDR, QQ_FIELD_STRING, "zipcode", N_("Zipcode"), NULL, 0 }, + { QQ_FIELD_ADDR, QQ_FIELD_STRING, "address", N_("Address"), NULL, 0 }, + { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "tel", N_("Phone Number"), NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_STRING, "age", N_("Age"), NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_CHOICE, "gender", N_("Gender"), genders, QQ_GENDER_SIZE }, + { QQ_FIELD_BASE, QQ_FIELD_STRING, "name", N_("Name"), NULL, 0 }, + { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "email", N_("Email"), NULL, 0 }, + { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sn", "Pager Serial Num", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_num", "Pager Num", NULL, 0 }, - { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sp", "Pager Serivce Provider", NULL, 0 }, - { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sta", "Pager Station Num", NULL, 0 }, + { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sp", "Pager Serivce Provider", NULL, 0 }, + { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_sta", "Pager Station Num", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "pg_type", "Pager Type", NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_STRING, "occupation", N_("Occupation"), NULL, 0 }, - { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", N_("Homepage"), NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_BOOL, "auth", N_("Authorize adding"), NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_STRING, "occupation", N_("Occupation"), NULL, 0 }, + { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "homepage", N_("Homepage"), NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_BOOL, "auth", N_("Authorize adding"), NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow1", "Unknow1", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow2", "Unknow2", NULL, 0 }, - { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "face", "Face", NULL, 0 }, - { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile", N_("Cellphone Number"), NULL, 0 }, - { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "mobile_type","Cellphone Type", NULL, 0 }, - { QQ_FIELD_BASE, QQ_FIELD_MULTI, "intro", N_("Personal Introduction"), NULL, 0 }, - { QQ_FIELD_ADDR, QQ_FIELD_STRING, "city", N_("City/Area"), NULL, 0 }, + { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "face", "Face", NULL, 0 }, + { QQ_FIELD_CONTACT, QQ_FIELD_STRING, "mobile", N_("Cellphone Number"), NULL, 0 }, + { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "mobile_type", "Cellphone Type", NULL, 0 }, + { QQ_FIELD_BASE, QQ_FIELD_MULTI, "intro", N_("Personal Introduction"), NULL, 0 }, + { QQ_FIELD_ADDR, QQ_FIELD_STRING, "city", N_("City/Area"), NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow3", "Unknow3", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow4", "Unknow4", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow5", "Unknow5", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_CHOICE, "pub_mobile", N_("Publish Mobile"), publish_types, QQ_PUBLISH_SIZE }, - { QQ_FIELD_CONTACT, QQ_FIELD_CHOICE, "pub_contact", N_("Publish Contact"), publish_types, QQ_PUBLISH_SIZE }, - { QQ_FIELD_EXT, QQ_FIELD_STRING, "college", N_("College"), NULL, 0 }, - { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "horoscope", N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE }, - { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "zodiac", N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE }, - { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "blood", N_("Blood"), blood_types, QQ_BLOOD_SIZE }, + { QQ_FIELD_CONTACT, QQ_FIELD_CHOICE, "pub_contact", N_("Publish Contact"), publish_types, QQ_PUBLISH_SIZE }, + { QQ_FIELD_EXT, QQ_FIELD_STRING, "college", N_("College"), NULL, 0 }, + { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "horoscope", N_("Horoscope"), horoscope_names, QQ_HOROSCOPE_SIZE }, + { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "zodiac", N_("Zodiac"), zodiac_names, QQ_ZODIAC_SIZE }, + { QQ_FIELD_EXT, QQ_FIELD_CHOICE, "blood", N_("Blood"), blood_types, QQ_BLOOD_SIZE }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "qq_show", "QQ Show", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "unknow6", "Unknow6", NULL, 0 }, { QQ_FIELD_UNUSED, QQ_FIELD_STRING, "LAST_2005", "LAST_2005", NULL, 0 } @@ -196,7 +196,9 @@ break; case QQ_FIELD_CHOICE: choice_num = strtol(segments[index], NULL, 10); - if (choice_num < 0 || choice_num >= field_infos[index].choice_size) choice_num = 0; + if (choice_num < 0 || choice_num >= field_infos[index].choice_size) { + choice_num = 0; + } purple_notify_user_info_add_pair(user_info, field_infos[index].text, field_infos[index].choice[choice_num]); break;
--- a/libpurple/protocols/qq/buddy_info.h Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/buddy_info.h Tue Feb 17 03:39:22 2009 +0000 @@ -31,7 +31,7 @@ #include "buddy_opt.h" #include "qq.h" -/* use is openq2005 +/* use in qq2005 * ext_flag: (0-7) * bit1 => qq space * comm_flag: (0-7)
--- a/libpurple/protocols/qq/group_im.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/group_im.c Tue Feb 17 03:39:22 2009 +0000 @@ -165,6 +165,7 @@ guint32 room_id, guint32 uid_from, const gchar *msg, time_t in_time) { PurpleConversation *conv; + qq_data *qd; qq_buddy_data *bd; qq_room_data *rmd; gchar *from; @@ -172,15 +173,17 @@ g_return_if_fail(gc != NULL && room_id != 0); g_return_if_fail(msg != NULL); + qd = (qq_data *)gc->proto_data; conv = purple_find_chat(gc, room_id); rmd = qq_room_data_find(gc, room_id); g_return_if_fail(rmd != NULL); - if (conv == NULL && purple_prefs_get_bool("/plugins/prpl/qq/auto_popup_conversation")) { + purple_debug_info("QQ", "is_show_chat:%d\n", qd->is_show_chat); + if (NULL == conv && qd->is_show_chat) { conv = qq_room_conv_open(gc, rmd); } - if (conv == NULL) { + if (NULL == conv) { purple_debug_info("QQ", "Conversion of %u is not open, missing from %d:/n%s/v", room_id, uid_from, msg); return;
--- a/libpurple/protocols/qq/qq.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/qq.c Tue Feb 17 03:39:22 2009 +0000 @@ -173,6 +173,7 @@ qd->is_show_notice = purple_account_get_bool(account, "show_notice", TRUE); qd->is_show_news = purple_account_get_bool(account, "show_news", TRUE); + qd->is_show_chat = purple_account_get_bool(account, "show_chat", TRUE); qd->resend_times = purple_prefs_get_int("/plugins/prpl/qq/resend_times"); if (qd->resend_times <= 1) qd->itv_config.resend = 4; @@ -1095,6 +1096,9 @@ option = purple_account_option_bool_new(_("Show server news"), "show_news", TRUE); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = purple_account_option_bool_new(_("Show chat room when msg comes"), "show_chat", TRUE); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = purple_account_option_int_new(_("Keep alive interval (seconds)"), "keep_alive_interval", 60); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); @@ -1104,7 +1108,6 @@ purple_prefs_add_none("/plugins/prpl/qq"); purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE); purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE); - purple_prefs_add_bool("/plugins/prpl/qq/auto_popup_conversation", TRUE); purple_prefs_add_bool("/plugins/prpl/qq/auto_get_authorize_info", TRUE); purple_prefs_add_int("/plugins/prpl/qq/resend_interval", 3); purple_prefs_add_int("/plugins/prpl/qq/resend_times", 10);
--- a/libpurple/protocols/qq/qq.h Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/qq.h Tue Feb 17 03:39:22 2009 +0000 @@ -182,6 +182,7 @@ gboolean is_show_notice; gboolean is_show_news; + gboolean is_show_chat; guint16 send_im_id; /* send IM sequence number */ };
--- a/libpurple/protocols/qq/qq_network.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/qq/qq_network.c Tue Feb 17 03:39:22 2009 +0000 @@ -214,7 +214,7 @@ qd->connect_retry = QQ_CONNECT_MAX; } - segments = g_strsplit(qd->curr_server, ":", 0); + segments = g_strsplit_set(qd->curr_server, ":", 0); tmp_server = g_strdup(segments[0]); if (NULL != segments[1]) { port = atoi(segments[1]);
--- a/libpurple/protocols/simple/simple.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/protocols/simple/simple.c Tue Feb 17 03:39:22 2009 +0000 @@ -196,7 +196,7 @@ { struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; struct simple_buddy *b; - if(strcmp("sip:", buddy->name)) { + if(strncmp(buddy->name, "sip:", 4)) { gchar *buf = g_strdup_printf("sip:%s", buddy->name); purple_blist_rename_buddy(buddy, buf); g_free(buf); @@ -834,10 +834,10 @@ "Event: presence\r\n", expiration); - if(strstr(buddy->name, "sip:")) + if(strncmp(buddy->name, "sip:", 4)) + to = g_strdup_printf("sip:%s", buddy->name); + else to = g_strdup(buddy->name); - else - to = g_strdup_printf("sip:%s", buddy->name); tmp = get_contact(sip); contact = g_strdup_printf("%sContact: %s\r\n", tmp2, tmp); @@ -881,7 +881,7 @@ tmp = sipmsg_find_header(msg, "Event"); - if(tmp && !strcmp(tmp, "vnd-microsoft-roaming-contacts")){ + if(tmp && !strncmp(tmp, "vnd-microsoft-roaming-contacts", 30)){ purple_debug_info("simple", "simple_add_lcs_contacts->%s-%d\n", msg->body, len); /*Convert the contact from XML to Purple Buddies*/ @@ -1013,11 +1013,11 @@ static void simple_send_message(struct simple_account_data *sip, const char *to, const char *msg, const char *type) { gchar *hdr; gchar *fullto; - if(strcmp("sip:", to)) { + if(strncmp(to, "sip:", 4)) fullto = g_strdup_printf("sip:%s", to); - } else { + else fullto = g_strdup(to); - } + if(type) { hdr = g_strdup_printf("Content-Type: %s\r\n", type); } else { @@ -1050,12 +1050,12 @@ purple_debug(PURPLE_DEBUG_MISC, "simple", "got message from %s: %s\n", from, msg->body); contenttype = sipmsg_find_header(msg, "Content-Type"); - if(!contenttype || !strcmp(contenttype, "text/plain") || !strcmp(contenttype, "text/html")) { + if(!contenttype || !strncmp(contenttype, "text/plain", 10) || !strncmp(contenttype, "text/html", 9)) { serv_got_im(sip->gc, from, msg->body, 0, time(NULL)); send_sip_response(sip->gc, msg, 200, "OK", NULL); found = TRUE; } - else if(!strcmp(contenttype, "application/im-iscomposing+xml")) { + else if(!strncmp(contenttype, "application/im-iscomposing+xml", 30)) { xmlnode *isc = xmlnode_from_str(msg->body, msg->bodylen); xmlnode *state; gchar *statedata;
--- a/libpurple/savedstatuses.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/savedstatuses.c Tue Feb 17 03:39:22 2009 +0000 @@ -148,11 +148,11 @@ /* Avoid using 0 because it's an invalid hash key */ status->creation_time = creation_time != 0 ? creation_time : 1; - while (g_hash_table_lookup(creation_times, &status->creation_time) != NULL) + while (g_hash_table_lookup(creation_times, (gconstpointer)status->creation_time) != NULL) status->creation_time++; g_hash_table_insert(creation_times, - &status->creation_time, + (gpointer)status->creation_time, status); } @@ -217,7 +217,7 @@ { saved_statuses = g_list_remove(saved_statuses, saved_status); creation_time = purple_savedstatus_get_creation_time(saved_status); - g_hash_table_remove(creation_times, &creation_time); + g_hash_table_remove(creation_times, (gconstpointer)creation_time); free_saved_status(saved_status); } } @@ -713,7 +713,7 @@ saved_statuses = g_list_remove(saved_statuses, status); creation_time = purple_savedstatus_get_creation_time(status); - g_hash_table_remove(creation_times, &creation_time); + g_hash_table_remove(creation_times, (gconstpointer)creation_time); free_saved_status(status); schedule_save(); @@ -801,13 +801,13 @@ PurpleSavedStatus * purple_savedstatus_get_default() { - int creation_time; + time_t creation_time; PurpleSavedStatus *saved_status = NULL; creation_time = purple_prefs_get_int("/purple/savedstatus/default"); if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, &creation_time); + saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); if (saved_status == NULL) { @@ -828,13 +828,13 @@ PurpleSavedStatus * purple_savedstatus_get_idleaway() { - int creation_time; + time_t creation_time; PurpleSavedStatus *saved_status = NULL; creation_time = purple_prefs_get_int("/purple/savedstatus/idleaway"); if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, &creation_time); + saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); if (saved_status == NULL) { @@ -907,13 +907,13 @@ PurpleSavedStatus * purple_savedstatus_get_startup() { - int creation_time; + time_t creation_time; PurpleSavedStatus *saved_status = NULL; creation_time = purple_prefs_get_int("/purple/savedstatus/startup"); if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, &creation_time); + saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); if (saved_status == NULL) { @@ -1187,7 +1187,7 @@ { void *handle = purple_savedstatuses_get_handle(); - creation_times = g_hash_table_new(g_int_hash, g_int_equal); + creation_times = g_hash_table_new(g_direct_hash, g_direct_equal); /* * Using 0 as the creation_time is a special case.
--- a/libpurple/upnp.c Tue Feb 10 06:42:42 2009 +0000 +++ b/libpurple/upnp.c Tue Feb 17 03:39:22 2009 +0000 @@ -567,7 +567,7 @@ purple_upnp_discover_send_broadcast(UPnPDiscoveryData *dd) { gchar *sendMessage = NULL; - gsize totalSize; + size_t totalSize; gboolean sentSuccess; /* because we are sending over UDP, if there is a failure @@ -693,6 +693,7 @@ /* XXX: This should probably be async */ if(cb) cb(NULL, cb_data, NULL, 0, NULL); + return NULL; } if(port == 0 || port == -1) { port = DEFAULT_HTTP_PORT; @@ -711,11 +712,11 @@ g_free(soapMessage); gfud = purple_util_fetch_url_request_len(control_info.control_url, FALSE, NULL, TRUE, - totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data); + totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data); g_free(totalSendMessage); g_free(addressOfControl); - + return gfud; }
--- a/pidgin/gtkblist.c Tue Feb 10 06:42:42 2009 +0000 +++ b/pidgin/gtkblist.c Tue Feb 17 03:39:22 2009 +0000 @@ -66,7 +66,7 @@ #include <gtk/gtk.h> #include <gdk/gdk.h> -#define HEADLINE_CLOSE_SIZE 12 +#define HEADLINE_CLOSE_SIZE 11 typedef struct { @@ -4554,6 +4554,9 @@ if (!gtkblist) return FALSE; + /* clear any tooltips */ + pidgin_blist_tooltip_destroy(); + widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window)); if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) { @@ -5387,7 +5390,8 @@ NULL); gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips"); - gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE, HEADLINE_CLOSE_SIZE, NULL); + gtkblist->headline_close = gtk_widget_render_icon(ebox, GTK_STOCK_CLOSE, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC), NULL); gtkblist->hand_cursor = gdk_cursor_new (GDK_HAND2); gtkblist->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); @@ -7676,13 +7680,11 @@ if (!disabled_accounts) { menuitem = gtk_menu_item_new_with_label(_("Enable Account")); gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem); - gtk_widget_show(menuitem); submenu = gtk_menu_new(); gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - gtk_widget_show(submenu); disabled_accounts = TRUE; } @@ -7704,7 +7706,6 @@ g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(enable_account_cb), account); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_show(menuitem); } else { enabled_accounts = TRUE; } @@ -7746,21 +7747,18 @@ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); } gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem); - gtk_widget_show(menuitem); submenu = gtk_menu_new(); gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf); g_free(accel_path_buf); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - gtk_widget_show(submenu); menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account")); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(modify_account_cb), account); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_show(menuitem); pidgin_separator(submenu); @@ -7772,7 +7770,6 @@ menuitem = gtk_menu_item_new_with_label(_("No actions available")); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); gtk_widget_set_sensitive(menuitem, FALSE); - gtk_widget_show(menuitem); } pidgin_separator(submenu); @@ -7781,8 +7778,8 @@ g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(disable_account_cb), account); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_show(menuitem); - } + } + gtk_widget_show_all(accountmenu); } static GList *plugin_submenus = NULL; @@ -7821,13 +7818,11 @@ menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name)); gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem); - gtk_widget_show(menuitem); plugin_submenus = g_list_append(plugin_submenus, menuitem); submenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - gtk_widget_show(submenu); gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); path = g_strdup_printf("%s/Tools/%s", gtkblist->ift->path, plugin->info->name); @@ -7836,6 +7831,7 @@ build_plugin_actions(submenu, plugin, NULL); } + gtk_widget_show_all(pluginmenu); } static void
--- a/pidgin/gtkconv.c Tue Feb 10 06:42:42 2009 +0000 +++ b/pidgin/gtkconv.c Tue Feb 17 03:39:22 2009 +0000 @@ -1959,6 +1959,9 @@ win = gtkconv->win; curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook)); + /* clear any tooltips */ + pidgin_tooltip_destroy(); + /* If CTRL was held down... */ if (event->state & GDK_CONTROL_MASK) { switch (event->keyval) {
--- a/pidgin/gtkdialogs.c Tue Feb 10 06:42:42 2009 +0000 +++ b/pidgin/gtkdialogs.c Tue Feb 17 03:39:22 2009 +0000 @@ -457,12 +457,17 @@ "warranty for this program.<BR><BR>"), PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME); g_string_append(str, "<FONT SIZE=\"4\">URL:</FONT> <A HREF=\"" - PURPLE_WEBSITE "\">" PURPLE_WEBSITE "</A><BR/><BR/>"); - g_string_append(str, "<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"" - "http://developer.pidgin.im/wiki/FAQ\">" - "http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"); - g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC:</FONT> " - "#pidgin on irc.freenode.net<BR><BR>")); + PURPLE_WEBSITE "\">" PURPLE_WEBSITE "</A><BR/><BR/>"); + g_string_append_printf(str, _("<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"" + "http://developer.pidgin.im/wiki/FAQ\">" + "http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>")); + g_string_append_printf(str, _("<FONT SIZE=\"4\">Help via e-mail:</FONT>" + " <A HREF=\"mailto:support@pidgin.im\">support@pidgin.im</A>" + "<BR/><BR/>")); + g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC Channel:</FONT> " + "#pidgin on irc.freenode.net<BR><BR>")); + g_string_append_printf(str, _("<FONT SIZE=\"4\">XMPP MUC:</FONT> " + "devel@conference.pidgin.im<BR><BR>")); /* Current Developers */ g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
--- a/pidgin/gtkdocklet.c Tue Feb 10 06:42:42 2009 +0000 +++ b/pidgin/gtkdocklet.c Tue Feb 17 03:39:22 2009 +0000 @@ -88,13 +88,16 @@ static GList * get_pending_list(guint max) { - GList *l_im = NULL; - GList *l_chat = NULL; + GList *l_im, *l_chat; l_im = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, FALSE, max); + /* Short circuit if we have our information already */ + if (max == 1 && l_im != NULL) + return l_im; + l_chat = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_CHAT, PIDGIN_UNSEEN_NICK, FALSE, max); @@ -344,7 +347,9 @@ docklet_menu_leave_enter(GtkWidget *menu, GdkEventCrossing *event, void *data) { static guint hide_docklet_timer = 0; - if (event->type == GDK_LEAVE_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { + + if (event->type == GDK_LEAVE_NOTIFY && (event->detail == GDK_NOTIFY_ANCESTOR || + event->detail == GDK_NOTIFY_UNKNOWN)) { purple_debug(PURPLE_DEBUG_INFO, "docklet", "menu leave-notify-event\n"); /* Add some slop so that the menu doesn't annoyingly disappear when mousing around */ if (hide_docklet_timer == 0) { @@ -652,11 +657,9 @@ menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name)); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - gtk_widget_show(menuitem); submenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - gtk_widget_show(submenu); build_plugin_actions(submenu, plugin, NULL);
--- a/pidgin/pidgintooltip.c Tue Feb 10 06:42:42 2009 +0000 +++ b/pidgin/pidgintooltip.c Tue Feb 17 03:39:22 2009 +0000 @@ -135,14 +135,14 @@ setup_tooltip_window_position(gpointer data, int w, int h) { int sig; - int scr_w, scr_h, x, y; + int scr_w, scr_h, x, y, dy; #if GTK_CHECK_VERSION(2,2,0) int mon_num; GdkScreen *screen = NULL; #endif GdkRectangle mon_size; GtkWidget *tipwindow = pidgin_tooltip.tipwindow; - + #if GTK_CHECK_VERSION(2,2,0) gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL); mon_num = gdk_screen_get_monitor_at_point(screen, x, y); @@ -158,6 +158,12 @@ mon_size.y = 0; #endif +#if GTK_CHECK_VERSION(2,4,0) + dy = gdk_display_get_default_cursor_size(gdk_display_get_default()) / 2; +#else + dy = 0; +#endif + #if GTK_CHECK_VERSION(2,2,0) if (w > mon_size.width) w = mon_size.width - 10; @@ -168,9 +174,9 @@ x -= ((w >> 1) + 4); if ((y + h + 4) > scr_h) - y = y - h - 5; + y = y - h - dy - 5; else - y = y + 6; + y = y + dy + 6; if (y < mon_size.y) y = mon_size.y; @@ -353,6 +359,7 @@ g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), tdata); g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); + g_signal_connect(G_OBJECT(tree), "scroll-event", G_CALLBACK(widget_leave_cb), NULL); g_signal_connect_swapped(G_OBJECT(tree), "destroy", G_CALLBACK(destroy_tooltip_data), tdata); return TRUE; } @@ -381,6 +388,7 @@ g_signal_connect(G_OBJECT(widget), "motion-notify-event", G_CALLBACK(widget_motion_cb), wdata); g_signal_connect(G_OBJECT(widget), "leave-notify-event", G_CALLBACK(widget_leave_cb), NULL); + g_signal_connect(G_OBJECT(widget), "scroll-event", G_CALLBACK(widget_leave_cb), NULL); g_signal_connect_swapped(G_OBJECT(widget), "destroy", G_CALLBACK(destroy_tooltip_data), wdata); return TRUE; }
--- a/po/de.po Tue Feb 10 06:42:42 2009 +0000 +++ b/po/de.po Tue Feb 17 03:39:22 2009 +0000 @@ -11,8 +11,8 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-09 00:39+0100\n" -"PO-Revision-Date: 2009-01-09 00:38+0100\n" +"POT-Creation-Date: 2009-02-06 15:18+0100\n" +"PO-Revision-Date: 2009-02-06 15:15+0100\n" "Last-Translator: Bjoern Voigt <bjoern@cs.tu-berlin.de>\n" "Language-Team: Deutsch <de@li.org>\n" "MIME-Version: 1.0\n" @@ -11908,7 +11908,7 @@ msgstr "Dieses Thema verfügt über keine Smileys." msgid "_Font" -msgstr "_Schrift" +msgstr "S_chrift" msgid "Group Items" msgstr "Elemente gruppieren"