# HG changeset patch # User andrew.victor@mxit.com # Date 1291100862 0 # Node ID c7f0decf419b303dbedb449ad7ba47e08e3112c9 # Parent 1203778744d03b289cd4be60a2c16a25d71c23f1# Parent 0e9b252f1769b8c4d26ea13d82538c034d0b97df propagate from branch 'im.pidgin.pidgin' (head 3f7ce0979147c5415dbc19906d2fd83bc5b5bfd0) to branch 'im.pidgin.pidgin.mxit' (head e36185e551bee7dc046fc10038046d07d41006e6) diff -r 0e9b252f1769 -r c7f0decf419b ChangeLog --- a/ChangeLog Tue Nov 23 07:50:25 2010 +0000 +++ b/ChangeLog Tue Nov 30 07:07:42 2010 +0000 @@ -1,22 +1,46 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.7.7 (??/??/????): +version 2.7.8 (??/??/????): General: - * Allow multiple certificates to share the same Distinguished Name (DN). + * Fix the exceptions in purple-remote on Python 2.6+. (Ari Pollak) + (#12151) + + Pidgin: + * When a conversation has reached the maximum limit on the number + of smileys, display the text representation of the smiley properly + when it contains HTML-escapable characters (e.g. "<3" was previously + displayed as "<3"). + + libpurple: + * Fix multipart parsing when '=' is included in the boundary for + purple_mime_document_parse. (Jakub Adam) (#11598) + + Gadu-Gadu: + * Updated our bundled libgadu and minimum requirement for external + libgadu to 1.9.0. (#12789) + + MSN: + * Stop showing ourselves in the list of endpoints that can be + disconnected. + * Allow full-size display names, by not escaping (most) non-English + characters. (#8508) + +version 2.7.7 (11/23/2010): + General: + * Allow multiple CA certificates to share the same Distinguished Name + (DN). Partially fixes remaining MSN issues from #12906. + * The GNUTLS SSL plugin now discards any certificate (and all subsequent + certificates) in a chain if it did not sign the previous certificate. Partially fixes remaining MSN issues from #12906. - * The GNUTLS SSL plugin now discards any certificate in a chain that did - not sign the previous certificate. Once one certificate is discarded, - all subsequent certificates are discarded. Partially fixes remaining - MSN issues from #12906. + * Open requests related to a file transfer are now closed when the request + is cancelled locally. (#11666) AIM and ICQ: - * AIM should now connect if "Use clientLogin" is off and the "Server" - field is set to anything but "login.oscar.aol.com". (#12948) + * AIM should now connect if "Use clientLogin" is turned off and the + "Server" field is set to anything other than "login.oscar.aol.com" or + "slogin.oscar.aol.com". (#12948) * Fix a crash on connection loss. (#5927) - MSN: - * Don't show ourselves in the list of endpoints that can be disconnected. - version 2.7.6 (11/21/2010): General: * Included Microsoft Internet Authority 2010 and Microsoft Secure Server diff -r 0e9b252f1769 -r c7f0decf419b ChangeLog.API --- a/ChangeLog.API Tue Nov 23 07:50:25 2010 +0000 +++ b/ChangeLog.API Tue Nov 30 07:07:42 2010 +0000 @@ -1,5 +1,11 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.7.8 (??/??/????): + * No changes + +version 2.7.7 (11/23/2010): + * No changes + version 2.7.6 (11/21/2010): * No changes diff -r 0e9b252f1769 -r c7f0decf419b NEWS --- a/NEWS Tue Nov 23 07:50:25 2010 +0000 +++ b/NEWS Tue Nov 30 07:07:42 2010 +0000 @@ -2,6 +2,15 @@ Our development blog is available at: http://planet.pidgin.im +2.7.8 (??/??/????): + +2.7.7 (11/23/2010): + John: Well, this time around, we should finally have the certificate + issue really and fully fixed for all of you MSN users. Also, we have + a few AIM-related fixes in this release, most notably the fix for the + new "SSL Handshake Failure" message some of you got after upgrading. + That one was an oversight on our part. Enjoy the fixes! + 2.7.6 (11/21/2010): Jorge: In this release I have merged two branches where I have spent most of my time in the last months, the MSNP16 and SLP-rewrite. I diff -r 0e9b252f1769 -r c7f0decf419b configure.ac --- a/configure.ac Tue Nov 23 07:50:25 2010 +0000 +++ b/configure.ac Tue Nov 30 07:07:42 2010 +0000 @@ -46,7 +46,7 @@ m4_define([purple_lt_current], [7]) m4_define([purple_major_version], [2]) m4_define([purple_minor_version], [7]) -m4_define([purple_micro_version], [7]) +m4_define([purple_micro_version], [8]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) @@ -55,7 +55,7 @@ m4_define([gnt_lt_current], [8]) m4_define([gnt_major_version], [2]) m4_define([gnt_minor_version], [8]) -m4_define([gnt_micro_version], [4]) +m4_define([gnt_micro_version], [5]) m4_define([gnt_version_suffix], [devel]) m4_define([gnt_version], [gnt_major_version.gnt_minor_version.gnt_micro_version]) @@ -1046,7 +1046,7 @@ gadu_manual_check="no" fi if test "x$gadu_manual_check" = "xno"; then - PKG_CHECK_MODULES(GADU, [libgadu >= 1.9.0-rc2], [ + PKG_CHECK_MODULES(GADU, [libgadu >= 1.9.0], [ gadu_includes="yes" gadu_libs="yes" ], [ diff -r 0e9b252f1769 -r c7f0decf419b libpurple/mime.c --- a/libpurple/mime.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/mime.c Tue Nov 30 07:07:42 2010 +0000 @@ -436,6 +436,34 @@ g_free(bnd); } +#define BOUNDARY "boundary=" +static char * +parse_boundary(const char *ct) +{ + char *boundary_begin = g_strstr_len(ct, -1, BOUNDARY); + char *boundary_end; + + if (!boundary_begin) + return NULL; + + boundary_begin += sizeof(BOUNDARY) - 1; + + if (*boundary_begin == '"') { + boundary_end = strchr(++boundary_begin, '"'); + if (!boundary_end) + return NULL; + } else { + boundary_end = strchr(boundary_begin, ' '); + if (!boundary_end) { + boundary_end = strchr(boundary_begin, ';'); + if (!boundary_end) + boundary_end = boundary_begin + strlen(boundary_begin); + } + } + + return g_strndup(boundary_begin, boundary_end - boundary_begin); +} +#undef BOUNDARY PurpleMimeDocument * purple_mime_document_parsen(const char *buf, gsize len) @@ -456,10 +484,11 @@ { const char *ct = fields_get(&doc->fields, "content-type"); - if(ct && purple_str_has_prefix(ct, "multipart")) { - char *bd = strrchr(ct, '='); - if(bd++) { + if (ct && purple_str_has_prefix(ct, "multipart")) { + char *bd = parse_boundary(ct); + if (bd) { doc_parts_load(doc, bd, b, n); + g_free(bd); } } } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/network.c --- a/libpurple/network.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/network.c Tue Nov 30 07:07:42 2010 +0000 @@ -350,17 +350,15 @@ if (success) { /* add port mapping to hash table */ - gint *key = g_new(gint, 1); - gint *value = g_new(gint, 1); - *key = purple_network_get_port_from_fd(listen_data->listenfd); - *value = listen_data->socket_type; - g_hash_table_insert(upnp_port_mappings, key, value); + gint key = purple_network_get_port_from_fd(listen_data->listenfd); + gint value = listen_data->socket_type; + g_hash_table_insert(upnp_port_mappings, GINT_TO_POINTER(key), GINT_TO_POINTER(value)); } if (listen_data->cb) listen_data->cb(listen_data->listenfd, listen_data->cb_data); - /* Clear the UPnP mapping data, since it's complete and purple_netweork_listen_cancel() will try to cancel + /* Clear the UPnP mapping data, since it's complete and purple_network_listen_cancel() will try to cancel * it otherwise. */ listen_data->mapping_data = NULL; purple_network_listen_cancel(listen_data); @@ -370,16 +368,16 @@ purple_network_finish_pmp_map_cb(gpointer data) { PurpleNetworkListenData *listen_data; - gint *key = g_new(gint, 1); - gint *value = g_new(gint, 1); + gint key; + gint value; listen_data = data; listen_data->timer = 0; /* add port mapping to hash table */ - *key = purple_network_get_port_from_fd(listen_data->listenfd); - *value = listen_data->socket_type; - g_hash_table_insert(nat_pmp_port_mappings, key, value); + key = purple_network_get_port_from_fd(listen_data->listenfd); + value = listen_data->socket_type; + g_hash_table_insert(nat_pmp_port_mappings, GINT_TO_POINTER(key), GINT_TO_POINTER(value)); if (listen_data->cb) listen_data->cb(listen_data->listenfd, listen_data->cb_data); @@ -1045,42 +1043,42 @@ purple_network_upnp_mapping_remove(gpointer key, gpointer value, gpointer user_data) { - gint port = (gint) *((gint *) key); - gint protocol = (gint) *((gint *) value); + gint port = GPOINTER_TO_INT(key); + gint protocol = GPOINTER_TO_INT(value); purple_debug_info("network", "removing UPnP port mapping for port %d\n", port); - purple_upnp_remove_port_mapping(port, - protocol == SOCK_STREAM ? "TCP" : "UDP", + purple_upnp_remove_port_mapping(port, + protocol == SOCK_STREAM ? "TCP" : "UDP", purple_network_upnp_mapping_remove_cb, NULL); - g_hash_table_remove(upnp_port_mappings, key); + g_hash_table_remove(upnp_port_mappings, GINT_TO_POINTER(port)); } static void purple_network_nat_pmp_mapping_remove(gpointer key, gpointer value, gpointer user_data) { - gint port = (gint) *((gint *) key); - gint protocol = (gint) *((gint *) value); + gint port = GPOINTER_TO_INT(key); + gint protocol = GPOINTER_TO_INT(value); purple_debug_info("network", "removing NAT-PMP port mapping for port %d\n", port); purple_pmp_destroy_map( - protocol == SOCK_STREAM ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP, + protocol == SOCK_STREAM ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP, port); - g_hash_table_remove(nat_pmp_port_mappings, key); + g_hash_table_remove(nat_pmp_port_mappings, GINT_TO_POINTER(port)); } void purple_network_remove_port_mapping(gint fd) { int port = purple_network_get_port_from_fd(fd); - gint *protocol = g_hash_table_lookup(upnp_port_mappings, &port); + gint protocol = GPOINTER_TO_INT(g_hash_table_lookup(upnp_port_mappings, GINT_TO_POINTER(port))); if (protocol) { - purple_network_upnp_mapping_remove(&port, protocol, NULL); + purple_network_upnp_mapping_remove(GINT_TO_POINTER(port), GINT_TO_POINTER(protocol), NULL); } else { - protocol = g_hash_table_lookup(nat_pmp_port_mappings, &port); + protocol = GPOINTER_TO_INT(g_hash_table_lookup(nat_pmp_port_mappings, GINT_TO_POINTER(port))); if (protocol) { - purple_network_nat_pmp_mapping_remove(&port, protocol, NULL); + purple_network_nat_pmp_mapping_remove(GINT_TO_POINTER(port), GINT_TO_POINTER(protocol), NULL); } } } @@ -1178,16 +1176,14 @@ purple_pmp_init(); purple_upnp_init(); - + purple_network_set_stun_server( purple_prefs_get_string("/purple/network/stun_server")); purple_network_set_turn_server( purple_prefs_get_string("/purple/network/turn_server")); - upnp_port_mappings = - g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); - nat_pmp_port_mappings = - g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + upnp_port_mappings = g_hash_table_new(g_direct_hash, g_direct_equal); + nat_pmp_port_mappings = g_hash_table_new(g_direct_hash, g_direct_equal); } @@ -1231,13 +1227,13 @@ #endif purple_signal_unregister(purple_network_get_handle(), "network-configuration-changed"); - + if (stun_ip) g_free(stun_ip); g_hash_table_destroy(upnp_port_mappings); g_hash_table_destroy(nat_pmp_port_mappings); - /* TODO: clean up remaining port mappings, note calling + /* TODO: clean up remaining port mappings, note calling purple_upnp_remove_port_mapping from here doesn't quite work... */ } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/gg/lib/dcc7.c --- a/libpurple/protocols/gg/lib/dcc7.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/gg/lib/dcc7.c Tue Nov 30 07:07:42 2010 +0000 @@ -731,6 +731,7 @@ e->event.dcc7_accept.remote_port = dcc->remote_port; } else { e->type = GG_EVENT_DCC7_PENDING; + e->event.dcc7_pending.dcc7 = dcc; } if (gg_dcc7_connect(sess, dcc) == -1) { @@ -1004,6 +1005,7 @@ if (gg_dcc7_reverse_connect(dcc) != -1) { e->type = GG_EVENT_DCC7_PENDING; + e->event.dcc7_pending.dcc7 = dcc; } else { e->type = GG_EVENT_DCC7_ERROR; e->event.dcc_error = GG_ERROR_DCC7_NET; diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/gg/lib/events.c --- a/libpurple/protocols/gg/lib/events.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/gg/lib/events.c Tue Nov 30 07:07:42 2010 +0000 @@ -1149,6 +1149,7 @@ e->type = GG_EVENT_NOTIFY60; e->event.notify60 = malloc(sizeof(*e->event.notify60)); + if (!e->event.notify60) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); goto fail; @@ -1159,7 +1160,7 @@ while (length >= sizeof(struct gg_notify_reply80)) { uint32_t descr_len; char *tmp; - + e->event.notify60[i].uin = gg_fix32(n->uin); e->event.notify60[i].status = gg_fix32(n->status); e->event.notify60[i].remote_ip = n->remote_ip; @@ -1169,7 +1170,6 @@ e->event.notify60[i].version = 0x00; /* not-supported */ e->event.notify60[i].time = 0; /* not-supported */ - descr_len = gg_fix32(n->descr_len); length -= sizeof(struct gg_notify_reply80); diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/gg/lib/libgadu.c --- a/libpurple/protocols/gg/lib/libgadu.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/gg/lib/libgadu.c Tue Nov 30 07:07:42 2010 +0000 @@ -69,7 +69,7 @@ # include #endif -#define GG_LIBGADU_VERSION "1.9.0-rc2" +#define GG_LIBGADU_VERSION "1.9.0" /** * Poziom rejestracji informacji odpluskwiających. Zmienna jest maską bitową @@ -180,7 +180,7 @@ #ifdef __GNUC__ __attribute__ ((unused)) #endif -= "$Id: libgadu.c 878 2009-11-16 23:48:19Z wojtekka $"; += "$Id: libgadu.c 923 2010-03-09 20:03:29Z wojtekka $"; #endif #endif /* DOXYGEN */ @@ -1316,41 +1316,65 @@ * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML. * * \param dst Bufor wynikowy (może być \c NULL) - * \param utf_msg Tekst źródłowy + * \param src Tekst źródłowy w UTF-8 * \param format Atrybuty tekstu źródłowego * \param format_len Długość bloku atrybutów tekstu źródłowego * + * \note Wynikowy tekst nie jest idealnym kodem HTML, ponieważ ma jak + * dokładniej odzwierciedlać to, co wygenerowałby oryginalny klient. + * * \note Dokleja \c \\0 na końcu bufora wynikowego. * * \return Długość tekstu wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL). */ -static int gg_convert_to_html(char *dst, const char *utf_msg, const unsigned char *format, int format_len) +static int gg_convert_to_html(char *dst, const char *src, const unsigned char *format, int format_len) { const char span_fmt[] = ""; const int span_len = 75; - const char img_fmt[] = ""; - const int img_len = 28; + const char img_fmt[] = ""; + const int img_len = 29; int char_pos = 0; - int format_idx = 3; + int format_idx = 0; unsigned char old_attr = 0; const unsigned char *color = (const unsigned char*) "\x00\x00\x00"; int len, i; len = 0; - for (i = 0; utf_msg[i] != 0; i++) { - unsigned char attr; - int attr_pos; + /* Nie mamy atrybutów dla pierwsze znaku, a tekst nie jest pusty, więc + * tak czy inaczej trzeba otworzyć . */ + + if (src[0] != 0 && (format_idx + 3 > format_len || (format[format_idx] | (format[format_idx + 1] << 8)) != 0)) { + if (dst != NULL) + sprintf(&dst[len], span_fmt, 0, 0, 0); + + len += span_len; + } + + /* Pętla przechodzi też przez kończące \0, żeby móc dokleić obrazek + * na końcu tekstu. */ - if (format_idx + 3 <= format_len) { + for (i = 0; ; i++) { + /* Analizuj atrybuty tak długo jak dotyczą aktualnego znaku. */ + for (;;) { + unsigned char attr; + int attr_pos; + + if (format_idx + 3 > format_len) + break; + attr_pos = format[format_idx] | (format[format_idx + 1] << 8); + + if (attr_pos != char_pos) + break; + attr = format[format_idx + 2]; - } else { - attr_pos = -1; - attr = 0; - } + + /* Nie doklejaj atrybutów na końcu, co najwyżej obrazki. */ - if (attr_pos == char_pos) { + if (src[i] == 0) + attr &= ~(GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR); + format_idx += 3; if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) { @@ -1377,7 +1401,7 @@ if (dst != NULL) sprintf(&dst[len], span_fmt, color[0], color[1], color[2]); len += span_len; - } else if (char_pos == 0) { + } else if (char_pos == 0 && src[0] != 0) { if (dst != NULL) sprintf(&dst[len], span_fmt, 0, 0, 0); len += span_len; @@ -1410,14 +1434,11 @@ } old_attr = attr; - } else if (i == 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - - len += span_len; } - switch (utf_msg[i]) { + /* Doklej znak zachowując htmlowe escapowanie. */ + + switch (src[i]) { case '&': gg_append(dst, &len, "&", 5); break; @@ -1437,19 +1458,25 @@ gg_append(dst, &len, "
", 4); break; case '\r': + case 0: break; default: if (dst != NULL) - dst[len] = utf_msg[i]; + dst[len] = src[i]; len++; } /* Sprawdź, czy bajt nie jest kontynuacją znaku unikodowego. */ - if ((utf_msg[i] & 0xc0) != 0xc0) + if ((src[i] & 0xc0) != 0xc0) char_pos++; + + if (src[i] == 0) + break; } + /* Zamknij tagi. */ + if ((old_attr & GG_FONT_UNDERLINE) != 0) gg_append(dst, &len, "", 4); @@ -1459,16 +1486,8 @@ if ((old_attr & GG_FONT_BOLD) != 0) gg_append(dst, &len, "", 4); - /* Dla pustych tekstów dodaj pusty . */ - - if (i == 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - - len += span_len; - } - - gg_append(dst, &len, "", 7); + if (src[0] != 0) + gg_append(dst, &len, "
", 7); if (dst != NULL) dst[len] = 0; @@ -1564,7 +1583,7 @@ formatlen = 9; } - len = gg_convert_to_html(NULL, utf_msg, format, formatlen); + len = gg_convert_to_html(NULL, utf_msg, format + 3, formatlen - 3); html_msg = malloc(len + 1); @@ -1573,7 +1592,7 @@ goto cleanup; } - gg_convert_to_html(html_msg, utf_msg, format, formatlen); + gg_convert_to_html(html_msg, utf_msg, format + 3, formatlen - 3); s80.seq = gg_fix32(seq_no); s80.msgclass = gg_fix32(msgclass); diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/gg/lib/libgadu.h --- a/libpurple/protocols/gg/lib/libgadu.h Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/gg/lib/libgadu.h Tue Nov 30 07:07:42 2010 +0000 @@ -865,6 +865,13 @@ }; /** + * Opis zdarzenia \c GG_EVENT_DCC7_PENDING. + */ +struct gg_event_dcc7_pending { + struct gg_dcc7 *dcc7; /**< Struktura połączenia */ +}; + +/** * Opis zdarzenia \c GG_EVENT_DCC7_REJECT. */ struct gg_event_dcc7_reject { @@ -908,6 +915,7 @@ struct gg_dcc7 *dcc7_new; /**< Nowe połączenie bezpośrednie (\c GG_EVENT_DCC7_NEW) */ enum gg_error_t dcc7_error; /**< Błąd połączenia bezpośredniego (\c GG_EVENT_DCC7_ERROR) */ struct gg_event_dcc7_connected dcc7_connected; /**< Informacja o zestawieniu połączenia bezpośredniego (\c GG_EVENT_DCC7_CONNECTED) */ + struct gg_event_dcc7_pending dcc7_pending; /**< Trwa próba połączenia bezpośredniego (\c GG_EVENT_DCC7_PENDING) */ struct gg_event_dcc7_reject dcc7_reject; /**< Odrzucono połączenia bezpośredniego (\c GG_EVENT_DCC7_REJECT) */ struct gg_event_dcc7_accept dcc7_accept; /**< Zaakceptowano połączenie bezpośrednie (\c GG_EVENT_DCC7_ACCEPT) */ }; diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/cmdproc.c --- a/libpurple/protocols/msn/cmdproc.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/cmdproc.c Tue Nov 30 07:07:42 2010 +0000 @@ -122,7 +122,7 @@ servconn = cmdproc->servconn; if (!servconn->connected) { - /* TODO: Need to free trans */ + msn_transaction_destroy(trans); return; } @@ -156,6 +156,8 @@ msn_servconn_write(servconn, data, len); + if (!trans->saveable) + msn_transaction_destroy(trans); g_free(data); } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/httpconn.c --- a/libpurple/protocols/msn/httpconn.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/httpconn.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,5 +1,5 @@ /** - * @file httpmethod.c HTTP connection method + * @file httpconn.c HTTP connection method * * purple * diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/msn.c Tue Nov 30 07:07:42 2010 +0000 @@ -250,24 +250,44 @@ MsnSession *session; MsnTransaction *trans; PurpleAccount *account; - const char *real_alias; + char real_alias[BUDDY_ALIAS_MAXLEN+1]; struct public_alias_closure *closure; session = purple_connection_get_protocol_data(pc); cmdproc = session->notification->cmdproc; account = purple_connection_get_account(pc); - if (alias && *alias) - { - char *tmp = g_strdup(alias); - real_alias = purple_url_encode(g_strstrip(tmp)); - g_free(tmp); - } - else - real_alias = ""; - - if (strlen(real_alias) > BUDDY_ALIAS_MAXLEN) - { + if (alias && *alias) { + int i = 0; + while (isspace(*alias)) + alias++; + + for (; *alias && i < BUDDY_ALIAS_MAXLEN; alias++) { + if (*alias == '%') { + if (i > BUF_LEN - 4) + break; + real_alias[i++] = '%'; + real_alias[i++] = '2'; + real_alias[i++] = '5'; + } else if (*alias == ' ') { + if (i > BUF_LEN - 4) + break; + real_alias[i++] = '%'; + real_alias[i++] = '2'; + real_alias[i++] = '0'; + } else { + real_alias[i++] = *alias; + } + } + + while (i && isspace(real_alias[i - 1])) + i--; + + real_alias[i] = '\0'; + } else + real_alias[0] = '\0'; + + if (*alias) { if (failure_cb) { struct public_alias_closure *closure = g_new0(struct public_alias_closure, 1); @@ -282,8 +302,8 @@ return; } - if (*real_alias == '\0') { - real_alias = purple_url_encode(purple_account_get_username(account)); + if (real_alias[0] == '\0') { + strcpy(real_alias, purple_account_get_username(account)); } closure = g_new0(struct public_alias_closure, 1); @@ -1168,18 +1188,26 @@ static GList * msn_actions(PurplePlugin *plugin, gpointer context) { + PurpleConnection *gc; + MsnSession *session; GList *m = NULL; PurplePluginAction *act; + gc = (PurpleConnection *) context; + session = gc->proto_data; + act = purple_plugin_action_new(_("Set Friendly Name..."), msn_show_set_friendly_name); m = g_list_append(m, act); m = g_list_append(m, NULL); - act = purple_plugin_action_new(_("View Locations..."), - msn_show_locations); - m = g_list_append(m, act); - m = g_list_append(m, NULL); + if (session->protocol_ver >= 16) + { + act = purple_plugin_action_new(_("View Locations..."), + msn_show_locations); + m = g_list_append(m, act); + m = g_list_append(m, NULL); + } act = purple_plugin_action_new(_("Set Home Phone Number..."), msn_show_set_home_phone); @@ -2100,7 +2128,6 @@ trans = msn_transaction_new(cmdproc, "PNG", NULL); msn_transaction_set_saveable(trans, FALSE); msn_cmdproc_send_trans(cmdproc, trans); - msn_transaction_destroy(trans); } } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/notification.c Tue Nov 30 07:07:42 2010 +0000 @@ -309,7 +309,6 @@ trans = msn_transaction_new(notification->cmdproc, "OUT", NULL); msn_transaction_set_saveable(trans, FALSE); msn_cmdproc_send_trans(notification->cmdproc, trans); - msn_transaction_destroy(trans); msn_notification_disconnect(notification); } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/p2p.c --- a/libpurple/protocols/msn/p2p.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/p2p.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file p2p.c MSN P2P functions + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include "internal.h" #include "p2p.h" @@ -71,6 +95,6 @@ msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags) { return (flags == P2P_MSN_OBJ_DATA || - flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || + flags == (P2P_WLM2009_COMP | P2P_MSN_OBJ_DATA) || flags == P2P_FILE_DATA); } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/p2p.h --- a/libpurple/protocols/msn/p2p.h Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/p2p.h Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file p2p.h MSN P2P functions + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #ifndef MSN_P2P_H #define MSN_P2P_H @@ -49,7 +73,7 @@ P2P_CLOSE = 0x40, /**< Close session */ P2P_TLP_ERROR = 0x80, /**< Error at transport layer protocol */ P2P_DC_HANDSHAKE = 0x100, /**< Direct Handshake */ - P2P_WML2009_COMP = 0x1000000, /**< Compatibility with WLM 2009 */ + P2P_WLM2009_COMP = 0x1000000, /**< Compatibility with WLM 2009 */ P2P_FILE_DATA = 0x1000030 /**< File transfer data */ } MsnP2PHeaderFlag; /* Info From: diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/sbconn.c --- a/libpurple/protocols/msn/sbconn.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/sbconn.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file sbconn.c MSN Switchboard Connection + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include "internal.h" #include "debug.h" diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/sbconn.h --- a/libpurple/protocols/msn/sbconn.h Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/sbconn.h Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file sbconn.h MSN Switchboard Connection + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #ifndef MSN_SBCONN_H #define MSN_SBCONN_H diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/slpcall.c --- a/libpurple/protocols/msn/slpcall.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/slpcall.c Tue Nov 30 07:07:42 2010 +0000 @@ -1061,7 +1061,7 @@ body = slpmsg->buffer; body_len = slpmsg->header->offset; - if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WML2009_COMP) + if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP) { char *body_str; diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/slplink.c --- a/libpurple/protocols/msn/slplink.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/slplink.c Tue Nov 30 07:07:42 2010 +0000 @@ -518,7 +518,7 @@ msn_directconn_send_handshake(directconn); #endif } - else if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WML2009_COMP || + else if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP || msn_p2p_msg_is_data(slpmsg->header->flags)) { /* Release all the messages and send the ACK */ diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/slpmsg.c --- a/libpurple/protocols/msn/slpmsg.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/slpmsg.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,5 +1,5 @@ /** - * @file slpmsg.h SLP Message functions + * @file slpmsg.c SLP Message functions * * purple * diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/slpmsg_part.c --- a/libpurple/protocols/msn/slpmsg_part.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/slpmsg_part.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file slpmsg_part.c MSNSLP Parts + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include "internal.h" #include "debug.h" diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/slpmsg_part.h --- a/libpurple/protocols/msn/slpmsg_part.h Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/slpmsg_part.h Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file slpmsg_part.h MSNSLP Parts + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #ifndef MSN_SLPMSG_PART_H #define MSN_SLPMSG_PART_H diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/switchboard.c --- a/libpurple/protocols/msn/switchboard.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/switchboard.c Tue Nov 30 07:07:42 2010 +0000 @@ -1147,7 +1147,6 @@ trans = msn_transaction_new(cmdproc, "OUT", NULL); msn_transaction_set_saveable(trans, FALSE); msn_cmdproc_send_trans(cmdproc, trans); - msn_transaction_destroy(trans); msn_switchboard_destroy(swboard); } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/user.c --- a/libpurple/protocols/msn/user.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/user.c Tue Nov 30 07:07:42 2010 +0000 @@ -203,6 +203,8 @@ status = "phone"; else if (!g_ascii_strcasecmp(state, "LUN")) status = "lunch"; + else if (!g_ascii_strcasecmp(state, "HDN")) + status = NULL; else status = "available"; diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/xfer.c --- a/libpurple/protocols/msn/xfer.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/xfer.c Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file xfer.c MSN File Transfer functions + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include "internal.h" #include "debug.h" diff -r 0e9b252f1769 -r c7f0decf419b libpurple/protocols/msn/xfer.h --- a/libpurple/protocols/msn/xfer.h Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/protocols/msn/xfer.h Tue Nov 30 07:07:42 2010 +0000 @@ -1,3 +1,27 @@ +/** + * @file xfer.h MSN File Transfer functions + * + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include "slpcall.h" diff -r 0e9b252f1769 -r c7f0decf419b libpurple/purple-remote --- a/libpurple/purple-remote Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/purple-remote Tue Nov 30 07:07:42 2010 +0000 @@ -36,7 +36,8 @@ def __call__(self, *args): result = self.cobj.obj.__getattr__(self.attr)(*args) if result == 0: - raise "Error: " + self.attr + " " + str(args) + " returned " + str(result) + raise Exception("Error: %s %s returned %s" % + (self.attr, args, result)) return result def show_help(requested=False): @@ -223,7 +224,7 @@ elif type == "i": methodparams.append(int(value)) else: - raise "Don't know how to handle type \"%s\"" % type + raise Exception("Don't know how to handle type \"%s\"" % type) return purple.__getattr__(command)(*methodparams) show_help() diff -r 0e9b252f1769 -r c7f0decf419b libpurple/upnp.c --- a/libpurple/upnp.c Tue Nov 23 07:50:25 2010 +0000 +++ b/libpurple/upnp.c Tue Nov 30 07:07:42 2010 +0000 @@ -162,9 +162,9 @@ while(discovery_callbacks) { gpointer data; PurpleUPnPCallback cb = discovery_callbacks->data; - discovery_callbacks = g_slist_remove(discovery_callbacks, cb); + discovery_callbacks = g_slist_delete_link(discovery_callbacks, discovery_callbacks); data = discovery_callbacks->data; - discovery_callbacks = g_slist_remove(discovery_callbacks, data); + discovery_callbacks = g_slist_delete_link(discovery_callbacks, discovery_callbacks); cb(success, data); } } diff -r 0e9b252f1769 -r c7f0decf419b libpurple/xmlnode.c diff -r 0e9b252f1769 -r c7f0decf419b pidgin.spec.in --- a/pidgin.spec.in Tue Nov 23 07:50:25 2010 +0000 +++ b/pidgin.spec.in Tue Nov 30 07:07:42 2010 +0000 @@ -46,14 +46,14 @@ %if "%{_vendor}" == "suse" # For SuSE: BuildRequires: gnutls-devel -%define sslopts "--enable-gnutls=yes --enable-nss=no" +%define sslopts --enable-gnutls=yes --enable-nss=no %{?_with_dbus:BuildRequires: dbus-1-devel >= 0.35} %{!?_without_gstreamer:BuildRequires: gstreamer010-devel >= 0.10} Requires(pre): gconf2 Requires(post): gconf2 Requires(preun): gconf2 %else -%define sslopts "--enable-gnutls=no --enable-nss=yes" +%define sslopts --enable-gnutls=no --enable-nss=yes %{?_with_dbus:BuildRequires: dbus-devel >= 0.35} %{!?_without_gstreamer:BuildRequires: gstreamer-devel >= 0.10} Requires(pre): GConf2 diff -r 0e9b252f1769 -r c7f0decf419b pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Tue Nov 23 07:50:25 2010 +0000 +++ b/pidgin/gtkdialogs.c Tue Nov 30 07:07:42 2010 +0000 @@ -168,7 +168,6 @@ {N_("Greek"), "el", "Bouklis Panos", "panos@echidna-band.com"}, {N_("Australian English"), "en_AU", "Peter Lawler", "trans@six-by-nine.com.au"}, {N_("Canadian English"), "en_CA", "Adam Weinberger", "adamw@gnome.org"}, - {N_("British English"), "en_GB", "Luke Ross", "lukeross@sys3175.co.uk"}, {N_("Esperanto"), "eo", "Stéphane Fillod", "fillods@users.sourceforge.net"}, {N_("Spanish"), "es", "Javier Fernández-Sanguino Peña", "jfs@debian.org"}, {N_("Estonian"), "et", "Ivar Smolin", "okul@linux.ee"}, @@ -260,6 +259,7 @@ {N_("Czech"), "cs", "Honza Král", NULL}, {N_("Czech"), "cs", "Miloslav Trmac", "mitr@volny.cz"}, {N_("German"), "de", "Daniel Seifert, Karsten Weiss", NULL}, + {N_("British English"), "en_GB", "Luke Ross", "luke@lukeross.name"}, {N_("Spanish"), "es", "JM Pérez Cáncer", NULL}, {N_("Spanish"), "es", "Nicolás Lichtmaier", NULL}, {N_("Spanish"), "es", "Amaya Rodrigo", NULL}, diff -r 0e9b252f1769 -r c7f0decf419b pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Tue Nov 23 07:50:25 2010 +0000 +++ b/pidgin/gtkimhtml.c Tue Nov 30 07:07:42 2010 +0000 @@ -4905,18 +4905,20 @@ * are apparently pretty inefficient. Hopefully we can remove this * restriction when we're using a better HTML widget. */ + unescaped = purple_unescape_html(smiley); numsmileys_thismsg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg")); if (numsmileys_thismsg >= 30) { - gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); + gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1); + g_free(unescaped); return; } numsmileys_total = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total")); if (numsmileys_total >= 300) { - gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); + gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1); + g_free(unescaped); return; } - unescaped = purple_unescape_html(smiley); imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped); if (imhtml->format_functions & GTK_IMHTML_SMILEY) { @@ -4991,7 +4993,7 @@ g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1)); g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1)); } else { - gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); + gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1); } if (ebox) { diff -r 0e9b252f1769 -r c7f0decf419b pidgin/gtkscrollbook.c --- a/pidgin/gtkscrollbook.c Tue Nov 23 07:50:25 2010 +0000 +++ b/pidgin/gtkscrollbook.c Tue Nov 30 07:07:42 2010 +0000 @@ -65,9 +65,13 @@ } static gboolean -scroll_left_cb(PidginScrollBook *scroll_book) +scroll_left_cb(PidginScrollBook *scroll_book, GdkEventButton *event) { int index; + + if (event->type != GDK_BUTTON_PRESS) + return FALSE; + index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)); if (index > 0) @@ -76,9 +80,13 @@ } static gboolean -scroll_right_cb(PidginScrollBook *scroll_book) +scroll_right_cb(PidginScrollBook *scroll_book, GdkEventButton *event) { int index, count; + + if (event->type != GDK_BUTTON_PRESS) + return FALSE; + index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)); count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook)); @@ -131,9 +139,10 @@ } static gboolean -scroll_close_cb(PidginScrollBook *scroll_book) +scroll_close_cb(PidginScrollBook *scroll_book, GdkEventButton *event) { - gtk_widget_destroy(gtk_notebook_get_nth_page(GTK_NOTEBOOK(scroll_book->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)))); + if (event->type == GDK_BUTTON_PRESS) + gtk_widget_destroy(gtk_notebook_get_nth_page(GTK_NOTEBOOK(scroll_book->notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)))); return FALSE; }