--- a/libpurple/protocols/gg/gg.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/gg/gg.c Fri Dec 23 08:21:58 2011 +0000
@@ -39,14 +39,16 @@
+# include "win32-resolver.h" static PurplePlugin *my_protocol = NULL;
@@ -97,7 +99,7 @@
static void ggp_async_token_handler(gpointer _gc, gint fd, PurpleInputCondition cond)
PurpleConnection *gc = _gc;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GGPToken *token = info->token;
@@ -170,7 +172,7 @@
if (ggp_setup_proxy(account) == -1)
+ info = purple_connection_get_protocol_data(gc); if ((req = gg_token(1)) == NULL) {
purple_notify_error(account,
@@ -199,7 +201,7 @@
static void ggp_action_buddylist_get(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); purple_debug_info("gg", "Downloading...\n");
@@ -214,7 +216,7 @@
static void ggp_action_buddylist_put(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); char *buddylist = ggp_buddylist_dump(purple_connection_get_account(gc));
@@ -235,7 +237,7 @@
static void ggp_action_buddylist_delete(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); purple_debug_info("gg", "Deleting...\n");
@@ -334,7 +336,7 @@
PurpleRequestFields *fields)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); struct gg_http *h = NULL;
@@ -389,8 +391,8 @@
purple_notify_info(NULL, _("New Gadu-Gadu Account Registered"),
_("Registration completed successfully!"), NULL);
- if(account->registration_cb)
- (account->registration_cb)(account, TRUE, account->registration_cb_user_data);
+ purple_account_register_completed(account, TRUE); /* TODO: the currently open Accounts Window will not be updated withthe
* new username and etc, we need to somehow have it refresh at this
@@ -400,8 +402,7 @@
purple_account_disconnect(account);
- if(account->registration_cb)
- (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
+ purple_account_register_completed(account, FALSE); @@ -415,10 +416,10 @@
static void ggp_callback_register_account_cancel(PurpleConnection *gc,
PurpleRequestFields *fields)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GGPToken *token = info->token;
- purple_account_disconnect(gc->account);
+ purple_account_disconnect(purple_connection_get_account(gc)); @@ -433,7 +434,7 @@
PurpleRequestFieldGroup *group;
PurpleRequestField *field;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GGPToken *token = info->token;
@@ -483,7 +484,7 @@
static void ggp_callback_show_next(PurpleConnection *gc, GList *row, gpointer user_data)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GGPSearchForm *form = user_data;
@@ -520,7 +521,7 @@
static void ggp_callback_find_buddies(PurpleConnection *gc, PurpleRequestFields *fields)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -616,75 +617,137 @@
-/* ----- CHANGE PASSWORD ------------------------------------------------ */
-static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields)
+/* ----- CHANGE PASSWORD ---------------------------------------------------- */ + struct gg_http *http_req; + PurpleAccount *account; +} ggp_change_passwd_request; +static void ggp_callback_change_passwd_handler(gpointer _req, gint fd, + PurpleInputCondition cond) + ggp_change_passwd_request *req = _req; + const char *messagesTitle = + _("Change password for the Gadu-Gadu account"); + purple_input_remove(req->inpa); + if (gg_change_passwd_watch_fd(req->http_req) == -1 || + req->http_req->state == GG_STATE_ERROR) + if (req->http_req->state != GG_STATE_DONE) + req->inpa = ggp_http_input_add(req->http_req, + ggp_callback_change_passwd_handler, req); + if (req->http_req->data != NULL && + ((struct gg_pubdir*)req->http_req->data)->success == 1) + purple_account_set_password(req->account, req->new_password); + purple_notify_info(req->account, messagesTitle, + _("Password was changed successfully!"), NULL); + purple_notify_error(req->account, messagesTitle, + _("Unable to change password. Error occurred.\n"), NULL); + gg_change_passwd_free(req->http_req); + g_free(req->new_password); +static void ggp_callback_change_passwd_ok(PurpleConnection *gc, + PurpleRequestFields *fields) - GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); - gchar *cur, *p1, *p2, *t;
- purple_request_fields_get_string(fields, "password_cur"),
- purple_request_fields_get_string(fields, "password1"),
- purple_request_fields_get_string(fields, "password2"),
- purple_request_fields_get_string(fields, "token"),
+ gchar *cur, *p1, *p2, *t, *mail; + const char *messagesTitle = + _("Change password for the Gadu-Gadu account"); + cur = g_strdup(purple_request_fields_get_string(fields, + p1 = g_strdup(purple_request_fields_get_string(fields, "password1")); + p2 = g_strdup(purple_request_fields_get_string(fields, "password2")); + t = g_strdup(purple_request_fields_get_string(fields, "token")); + mail = g_strdup(purple_request_fields_get_string(fields, "email")); account = purple_connection_get_account(gc);
if (cur == NULL || p1 == NULL || p2 == NULL || t == NULL ||
- *cur == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') {
- purple_notify_error(account, NULL, _("Fill in the fields."), NULL);
+ mail == NULL || *cur == '\0' || *p1 == '\0' || *p2 == '\0' || + *t == '\0' || *mail == '\0') { + purple_notify_error(account, messagesTitle, + _("Fill in the fields."), NULL); if (g_utf8_collate(p1, p2) != 0) {
- purple_notify_error(account, NULL,
- _("New passwords do not match."), NULL);
+ purple_notify_error(account, messagesTitle, + _("New passwords do not match."), NULL); + purple_notify_error(account, messagesTitle, + _("New password should be at most 15 characters long."), if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) {
- purple_notify_error(account, NULL,
- _("Your current password is different from the one that you specified."),
+ purple_notify_error(account, messagesTitle, + _("Your current password is different from the one that" + " you specified."), NULL); + if (!purple_email_is_valid(mail)) { + purple_notify_error(account, messagesTitle, + _("Invalid email address"), NULL); - purple_debug_info("gg", "Changing password\n");
- /* XXX: this email should be a pref... */
- h = gg_change_passwd4(ggp_get_uin(account),
- "user@example.net", purple_account_get_password(account),
- p1, info->token->id, t, 0);
- purple_notify_error(account, NULL,
+ purple_debug_info("gg", "Changing password with email \"%s\"...\n", + h = gg_change_passwd4(ggp_get_uin(account), mail, + purple_account_get_password(account), p1, info->token->id, t, + purple_notify_error(account, messagesTitle, _("Unable to change password. Error occurred.\n"),
+ ggp_change_passwd_request *req = + g_new(ggp_change_passwd_request, 1); + req->new_password = g_strdup(p1); + req->account = account; + req->inpa = ggp_http_input_add(h, + ggp_callback_change_passwd_handler, req);
- purple_account_set_password(account, p1);
- gg_change_passwd_free(h);
- purple_notify_info(account, _("Change password for the Gadu-Gadu account"),
- _("Password was changed successfully!"), NULL);
g_free(info->token->data);
@@ -696,12 +759,11 @@
PurpleRequestFieldGroup *group;
PurpleRequestField *field;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GGPToken *token = info->token;
fields = purple_request_fields_new();
group = purple_request_field_group_new(NULL);
purple_request_fields_add_group(fields, group);
@@ -721,6 +783,11 @@
purple_request_field_string_set_masked(field, TRUE);
purple_request_field_group_add_field(group, field);
+ field = purple_request_field_string_new("email", + _("Email Address"), "", FALSE); + purple_request_field_string_set_masked(field, FALSE); + purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("token",
_("Enter current token"), "", FALSE);
purple_request_field_string_set_masked(field, FALSE);
@@ -732,8 +799,8 @@
purple_request_field_group_add_field(group, field);
msg = g_strdup_printf("%s %d",
- _("Please, enter your current password and your new password for UIN: "),
- ggp_get_uin(purple_connection_get_account(gc)));
+ _("Please, enter your current password and your new password " + "for UIN: "), ggp_get_uin(purple_connection_get_account(gc))); purple_request_fields(gc,
_("Change Gadu-Gadu Password"),
@@ -758,7 +825,7 @@
static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, PurpleRequestFields *fields)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc);
@@ -778,7 +845,7 @@
static void ggp_action_change_status_broadcasting(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleRequestFields *fields;
PurpleRequestFieldGroup *group;
@@ -848,7 +915,7 @@
buddy = (PurpleBuddy *)node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+ info = purple_connection_get_protocol_data(gc); fields = purple_request_fields_new();
group = purple_request_field_group_new(NULL);
@@ -857,7 +924,7 @@
field = purple_request_field_list_new("name", "Chat name");
for (l = info->chats; l != NULL; l = l->next) {
- purple_request_field_list_add(field, chat->name, chat->name);
+ purple_request_field_list_add_icon(field, chat->name, NULL, chat->name); purple_request_field_group_add_field(group, field);
@@ -879,7 +946,7 @@
static void ggp_add_deny(PurpleConnection *gc, const char *who)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); uin_t uin = ggp_str_to_uin(who);
purple_debug_info("gg", "ggp_add_deny: %u\n", uin);
@@ -890,7 +957,7 @@
static void ggp_rem_deny(PurpleConnection *gc, const char *who)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); uin_t uin = ggp_str_to_uin(who);
purple_debug_info("gg", "ggp_rem_deny: %u\n", uin);
@@ -1024,7 +1091,8 @@
purple_debug_info("gg", "gg_get_avatar_url_cb: "
"requesting avatar for %s\n", uin);
- url_data = purple_util_fetch_url_request_len(account,
+ /* FIXME: This should be cancelled somewhere if not needed. */ + url_data = purple_util_fetch_url_request(account, bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
@@ -1052,7 +1120,8 @@
avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin);
- url_data = purple_util_fetch_url_request_len(
+ /* FIXME: This should be cancelled somewhere if not needed. */ + url_data = purple_util_fetch_url_request( purple_connection_get_account(gc), avatarurl, TRUE,
"Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
gg_get_avatar_url_cb, gc);
@@ -1086,7 +1155,7 @@
case GG_STATUS_FFC_DESCR:
- st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE);
case GG_STATUS_AVAIL_DESCR:
@@ -1096,6 +1165,10 @@
case GG_STATUS_BUSY_DESCR:
st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY);
+ case GG_STATUS_INVISIBLE: + case GG_STATUS_INVISIBLE_DESCR: + st = purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE); case GG_STATUS_DND_DESCR:
st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE);
@@ -1349,7 +1422,7 @@
static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -1391,7 +1464,7 @@
static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); GList *entry = g_list_first(info->pending_richtext_messages);
gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32);
@@ -1439,11 +1512,12 @@
static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleConversation *conv;
if (ev->event.msg.message == NULL)
@@ -1572,8 +1646,13 @@
from, msg, ev->event.msg.msgclass,
ev->event.msg.recipients_count);
+ if (ev->event.msg.msgclass & GG_CLASS_QUEUED) + mtime = ev->event.msg.time; if (ev->event.msg.recipients_count == 0) {
- serv_got_im(gc, from, msg, 0, ev->event.msg.time);
+ serv_got_im(gc, from, msg, 0, mtime); @@ -1599,7 +1678,7 @@
buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender);
serv_got_chat_in(gc, chat_id, buddy_name,
- PURPLE_MESSAGE_RECV, msg, ev->event.msg.time);
+ PURPLE_MESSAGE_RECV, msg, mtime); @@ -1608,7 +1687,7 @@
static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleStoredImage *image;
gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
@@ -1714,7 +1793,7 @@
static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond)
PurpleConnection *gc = _gc;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -1849,7 +1928,7 @@
g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
+ info = purple_connection_get_protocol_data(gc); purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
info->session->check, info->session->state);
@@ -1896,11 +1975,12 @@
purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
info->session->check, info->session->state);
- purple_input_remove(gc->inpa);
+ purple_input_remove(info->inpa); /** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */
if (info->session->fd >= 0)
- gc->inpa = purple_input_add(info->session->fd,
+ info->inpa = purple_input_add(info->session->fd, (info->session->check == 1) ? PURPLE_INPUT_WRITE :
ggp_async_login_handler, gc);
@@ -1913,8 +1993,8 @@
case GG_EVENT_CONN_SUCCESS:
purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n");
- purple_input_remove(gc->inpa);
- gc->inpa = purple_input_add(info->session->fd,
+ purple_input_remove(info->inpa); + info->inpa = purple_input_add(info->session->fd, @@ -1924,17 +2004,69 @@
case GG_EVENT_CONN_FAILED:
- purple_input_remove(gc->inpa);
- purple_connection_error (gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Connection failed"));
+ purple_input_remove(info->inpa); + purple_debug_info("gg", "Connection failure: %d\n", + switch (ev->event.failure) { + case GG_FAILURE_RESOLVING: + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + case GG_FAILURE_PASSWORD: + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, + _("Incorrect password")); + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, + _("SSL Connection Failed")); + case GG_FAILURE_INTRUDER: + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, + _("Your account has been " + "disabled because too many " + "incorrect passwords were " + case GG_FAILURE_UNAVAILABLE: + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Service temporarily " + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Error connecting to proxy " + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Error connecting to master " + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Connection failed")); if (ev->event.msg.sender == 0)
+ if (ev->event.msg.message == NULL) /* system messages are mostly ads */
purple_debug_info("gg", "System message:\n%s\n",
purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u "
"unexpected while connecting:\n%s\n",
@@ -1958,6 +2090,19 @@
+static const char *ggp_normalize(const PurpleAccount *account, const char *who) + static char normalized[21]; /* maximum unsigned long long int size */ + uin_t uin = ggp_str_to_uin(who); + g_snprintf(normalized, sizeof(normalized), "%u", uin); static char *ggp_status_text(PurpleBuddy *b)
@@ -2013,50 +2158,60 @@
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + NULL, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
- * Without this selecting Invisible as own status doesn't
- * work. It's not used and not needed to show status of buddies.
+ * New status for GG 8.0: PoGGadaj ze mna (chatty). + * NOTE: at this time, this is used only to set our own status. - type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_INVISIBLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + "freeforchat", _("Chatty"), TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, + NULL, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
- * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because
- * libpurple can't support Chatty status) and Nie przeszkadzac
+ * New status for GG 8.0: Nie przeszkadzac (do not disturb). - type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_UNAVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, + NULL, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), + types = g_list_append(types, type); + * It's used on buddy list if and only if it's showing our own + type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, + NULL, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
* This status is necessary to display guys who are blocking *us*.
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_INVISIBLE, "blocked", _("Blocked"), TRUE, FALSE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL);
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, + "blocked", _("Blocked"), TRUE, FALSE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(
- PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE, + NULL, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), types = g_list_append(types, type);
@@ -2067,13 +2222,15 @@
if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
account = purple_buddy_get_account((PurpleBuddy *) node);
- info = purple_account_get_connection(account)->proto_data;
+ gc = purple_account_get_connection(account); + info = purple_connection_get_protocol_data(gc); act = purple_menu_action_new(_("Add to chat"),
PURPLE_CALLBACK(ggp_bmenu_add_to_chat),
@@ -2125,11 +2282,25 @@
info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal);
info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE);
+ purple_connection_set_protocol_data(gc, info); glp->uin = ggp_get_uin(account);
- glp->password = (char *)purple_account_get_password(account);
+ glp->password = charset_convert(purple_account_get_password(account), + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_INVALID_USERNAME, + _("The username specified is invalid.")); + glp->status_flags = GG_STATUS_FLAG_UNKNOWN; + if (purple_account_get_bool(account, "show_links_from_strangers", 1)) + glp->status_flags |= GG_STATUS_FLAG_SPAM; presence = purple_account_get_presence(account);
status = purple_presence_get_active_status(presence);
@@ -2141,13 +2312,26 @@
glp->status = ggp_to_gg_status(status, &glp->status_descr);
- encryption_type = purple_account_get_string(account, "encryption", "none");
- purple_debug_info("gg", "Requested encryption type: %s\n", encryption_type);
+ encryption_type = purple_account_get_string(account, "encryption", + purple_debug_info("gg", "Requested encryption type: %s\n", if (strcmp(encryption_type, "opportunistic_tls") == 0)
- purple_debug_info("gg", "TLS enabled: %d\n", glp->tls);
+ glp->tls = GG_SSL_ENABLED; + else if (strcmp(encryption_type, "require_tls") == 0) { + if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL)) + glp->tls = GG_SSL_REQUIRED; + purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, + _("SSL support unavailable")); + else /* encryption_type == "none" */ + glp->tls = GG_SSL_DISABLED; + purple_debug_info("gg", "TLS mode: %d\n", glp->tls); if (!info->status_broadcasting)
glp->status = glp->status|GG_STATUS_FRIENDS_MASK;
@@ -2183,24 +2367,25 @@
- gc->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ,
+ info->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ, ggp_async_login_handler, gc);
static void ggp_close(PurpleConnection *gc)
+ PurpleAccount *account; purple_debug_info("gg", "gc == NULL\n");
- PurpleAccount *account = purple_connection_get_account(gc);
- GGPInfo *info = gc->proto_data;
- status = purple_account_get_active_status(account);
+ account = purple_connection_get_account(gc); + info = purple_connection_get_protocol_data(gc); + PurpleStatus *status = purple_account_get_active_status(account); if (info->session != NULL) {
ggp_set_status(account, status);
@@ -2218,20 +2403,21 @@
ggp_search_destroy(info->searches);
g_list_free(info->pending_richtext_messages);
g_hash_table_destroy(info->pending_images);
+ purple_input_remove(info->inpa); + purple_connection_set_protocol_data(gc, NULL);
- purple_input_remove(gc->inpa);
purple_debug_info("gg", "Connection closed.\n");
static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
PurpleMessageFlags flags)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); unsigned char format[1024];
@@ -2349,6 +2535,7 @@
static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
+ GGPInfo *info = purple_connection_get_protocol_data(gc); int dummy_length; // we don't send real length of typed message
if (state == PURPLE_TYPED) // not supported
@@ -2360,7 +2547,7 @@
- ((GGPInfo*)gc->proto_data)->session,
@@ -2369,7 +2556,7 @@
static void ggp_get_info(PurpleConnection *gc, const char *name)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -2397,6 +2584,9 @@
if (strcmp(status_id, "available") == 0) {
new_status = GG_STATUS_AVAIL;
new_status_descr = GG_STATUS_AVAIL_DESCR;
+ } else if (strcmp(status_id, "freeforchat") == 0) { + new_status = GG_STATUS_FFC; + new_status_descr = GG_STATUS_FFC_DESCR; } else if (strcmp(status_id, "away") == 0) {
new_status = GG_STATUS_BUSY;
new_status_descr = GG_STATUS_BUSY_DESCR;
@@ -2445,7 +2635,7 @@
gc = purple_account_get_connection(account);
+ info = purple_connection_get_protocol_data(gc); new_status = ggp_to_gg_status(status, &new_msg);
@@ -2463,10 +2653,10 @@
-static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
+static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message) - GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); const gchar *name = purple_buddy_get_name(buddy);
gg_add_notify(info->session, ggp_str_to_uin(name));
@@ -2480,14 +2670,14 @@
static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -2525,7 +2715,7 @@
static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
PurpleConversation *conv;
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); @@ -2539,7 +2729,7 @@
for (l = info->chats; l != NULL; l = l->next) {
- if (g_utf8_collate(chat->name, conv->name) == 0) {
+ if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) { @@ -2580,7 +2770,7 @@
static void ggp_keepalive(PurpleConnection *gc)
- GGPInfo *info = gc->proto_data;
+ GGPInfo *info = purple_connection_get_protocol_data(gc); /* purple_debug_info("gg", "Keeping connection alive....\n"); */
@@ -2605,14 +2795,16 @@
+ act = purple_plugin_action_new(_("Change password..."), + m = g_list_append(m, act); act = purple_plugin_action_new(_("Find buddies..."),
m = g_list_append(m, act);
- m = g_list_append(m, NULL);
- act = purple_plugin_action_new(_("Change password..."),
+ act = purple_plugin_action_new(_("Change status broadcasting"), + ggp_action_change_status_broadcasting); m = g_list_append(m, act);
m = g_list_append(m, NULL);
@@ -2637,10 +2829,6 @@
ggp_action_buddylist_load);
m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Change status broadcasting"),
- ggp_action_change_status_broadcasting);
- m = g_list_append(m, act);
@@ -2651,6 +2839,7 @@
static PurplePluginProtocolInfo prpl_info =
+ sizeof(PurplePluginProtocolInfo), /* struct_size */ OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_IM_IMAGE,
NULL, /* protocol_options */
@@ -2691,13 +2880,12 @@
ggp_keepalive, /* keepalive */
ggp_register_user, /* register_user */
- NULL, /* get_cb_away */
+ ggp_normalize, /* normalize */ NULL, /* set_buddy_icon */
NULL, /* get_cb_real_name */
@@ -2716,15 +2904,12 @@
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */ static PurplePluginInfo info = {
@@ -2790,11 +2975,6 @@
PurpleAccountOption *option;
GList *encryption_options = NULL;
- option = purple_account_option_string_new(_("Nickname"),
- "nick", _("Gadu-Gadu User"));
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
option = purple_account_option_string_new(_("GG server"),
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
@@ -2807,22 +2987,29 @@
list = g_list_append(list, kvp); \
- ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
ADD_VALUE(encryption_options, _("Use encryption if available"),
ADD_VALUE(encryption_options, _("Require encryption"), "require_tls");
+ ADD_VALUE(encryption_options, _("Don't use encryption"), "none"); option = purple_account_option_list_new(_("Connection security"),
"encryption", encryption_options);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+ option = purple_account_option_bool_new(_("Show links from strangers"), + "show_links_from_strangers", 1); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, gg_debug_handler = purple_gg_debug_handler;
+ gg_global_set_custom_resolver(ggp_resolver_win32thread_start, + ggp_resolver_win32thread_cleanup); PURPLE_INIT_PLUGIN(gg, init_plugin, info);
--- a/libpurple/protocols/jabber/si.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/jabber/si.c Fri Dec 23 08:21:58 2011 +0000
@@ -87,9 +87,9 @@
for(xfers = js->file_transfers; xfers; xfers = xfers->next) {
PurpleXfer *xfer = xfers->data;
- JabberSIXfer *jsx = xfer->data;
- if(jsx->stream_id && xfer->who &&
- !strcmp(jsx->stream_id, sid) && !strcmp(xfer->who, from))
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); + if(jsx->stream_id && purple_xfer_get_remote_user(xfer) && + !strcmp(jsx->stream_id, sid) && !strcmp(purple_xfer_get_remote_user(xfer), from)) @@ -118,7 +118,7 @@
jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); JabberBytestreamsStreamhost *streamhost = jsx->streamhosts->data;
@@ -143,7 +143,7 @@
/* unknown file transfer type is assumed to be RECEIVE */
- if(xfer->type == PURPLE_XFER_SEND)
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
@@ -151,14 +151,14 @@
query = xmlnode_get_child(iq->node, "query");
xmlnode_set_attrib(query, "sid", jsx->stream_id);
activate = xmlnode_new_child(query, "activate");
- xmlnode_insert_data(activate, xfer->who, -1);
+ xmlnode_insert_data(activate, purple_xfer_get_remote_user(xfer), -1); /* TODO: We need to wait for an activation result before starting */
iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, NS_BYTESTREAMS);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); jabber_iq_set_id(iq, jsx->iq_id);
query = xmlnode_get_child(iq->node, "query");
su = xmlnode_new_child(query, "streamhost-used");
@@ -174,7 +174,7 @@
connect_timeout_cb(gpointer data)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); purple_debug_info("jabber", "Streamhost connection timeout of %d seconds exceeded.\n", STREAMHOST_CONNECT_TIMEOUT);
@@ -203,7 +203,7 @@
jabber_si_bytestreams_ibb_timeout_cb(gpointer data)
PurpleXfer *xfer = (PurpleXfer *) data;
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); if (jsx && !jsx->ibb_session) {
purple_debug_info("jabber",
@@ -218,7 +218,7 @@
static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); JabberBytestreamsStreamhost *streamhost;
@@ -229,7 +229,7 @@
jabber_iq_set_id(iq, jsx->iq_id);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); error = xmlnode_new_child(iq->node, "error");
xmlnode_set_attrib(error, "code", "404");
xmlnode_set_attrib(error, "type", "cancel");
@@ -271,7 +271,7 @@
purple_proxy_info_destroy(jsx->gpi);
- dstjid = jabber_id_new(xfer->who);
+ dstjid = jabber_id_new(purple_xfer_get_remote_user(xfer)); /* TODO: Deal with zeroconf */
@@ -284,7 +284,7 @@
purple_proxy_info_set_port(jsx->gpi, streamhost->port);
/* unknown file transfer type is assumed to be RECEIVE */
- if(xfer->type == PURPLE_XFER_SEND)
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, jsx->js->user->node, jsx->js->user->domain,
jsx->js->user->resource, dstjid->node, dstjid->domain, dstjid->resource);
@@ -302,7 +302,7 @@
/* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */
- if (xfer->type != PURPLE_XFER_SEND && jsx->connect_data != NULL)
+ if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND && jsx->connect_data != NULL) jsx->connect_timeout = purple_timeout_add_seconds(
STREAMHOST_CONNECT_TIMEOUT, connect_timeout_cb, xfer);
@@ -337,7 +337,7 @@
if(!(xfer = jabber_si_xfer_find(js, sid, from)))
+ jsx = purple_xfer_get_protocol_data(xfer); @@ -375,15 +375,13 @@
PurpleInputCondition cond)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
if (len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
@@ -395,8 +393,8 @@
if (jsx->rxlen < jsx->rxmaxlen)
- purple_input_remove(xfer->watcher);
+ purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, 0); @@ -412,7 +410,7 @@
PurpleInputCondition cond)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/
@@ -426,8 +424,6 @@
if(len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
purple_xfer_cancel_remote(xfer);
@@ -441,8 +437,6 @@
purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n",
jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2],
jsx->rxqueue[3], jsx->rxqueue[4]);
- purple_input_remove(xfer->watcher);
purple_xfer_cancel_remote(xfer);
@@ -455,8 +449,6 @@
if(len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
purple_xfer_cancel_remote(xfer);
@@ -470,12 +462,12 @@
if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2)
- purple_input_remove(xfer->watcher);
+ purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, 0); dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id,
jsx->js->user->node, jsx->js->user->domain,
- jsx->js->user->resource, xfer->who);
+ jsx->js->user->resource, purple_xfer_get_remote_user(xfer)); /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
@@ -516,8 +508,8 @@
jsx->rxqueue[5+strlen(host)] = 0x00;
jsx->rxqueue[6+strlen(host)] = 0x00;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, + jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer)); jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source,
@@ -527,15 +519,13 @@
PurpleInputCondition cond)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
if (len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
@@ -547,13 +537,11 @@
if (jsx->rxlen < jsx->rxmaxlen)
- purple_input_remove(xfer->watcher);
/* If we sent a "Success", wait for a response, otherwise give up and cancel */
if (jsx->rxqueue[1] == 0x00) {
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_again_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_READ, + jabber_si_xfer_bytestreams_send_read_again_cb, xfer)); @@ -568,14 +556,14 @@
PurpleInputCondition cond)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n");
+ purple_xfer_set_fd(xfer, source); /** Try to read the SOCKS5 header */
@@ -584,9 +572,6 @@
if(len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
purple_xfer_cancel_remote(xfer);
@@ -603,9 +588,6 @@
if(len < 0 && errno == EAGAIN)
- purple_input_remove(xfer->watcher);
purple_xfer_cancel_remote(xfer);
@@ -618,13 +600,9 @@
if(jsx->rxlen -2 < jsx->rxqueue[1])
- purple_input_remove(xfer->watcher);
purple_debug_info("jabber", "checking to make sure we're socks FIVE\n");
if(jsx->rxqueue[0] != 0x05) {
purple_xfer_cancel_remote(xfer);
@@ -641,9 +619,10 @@
jsx->rxqueue = g_malloc(jsx->rxmaxlen);
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
+ purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, jabber_si_xfer_bytestreams_send_read_response_cb,
jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
source, PURPLE_INPUT_WRITE);
@@ -658,8 +637,9 @@
jsx->rxqueue = g_malloc(jsx->rxmaxlen);
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_response_cb, xfer);
+ purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, + jabber_si_xfer_bytestreams_send_read_response_cb, xfer)); jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
source, PURPLE_INPUT_WRITE);
@@ -680,7 +660,7 @@
PurpleInputCondition cond)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");
@@ -694,7 +674,7 @@
- purple_input_remove(xfer->watcher);
+ purple_input_remove(purple_xfer_get_watcher(xfer)); jsx->local_streamhost_fd = -1;
@@ -704,8 +684,8 @@
fcntl(acceptfd, F_SETFD, FD_CLOEXEC);
- xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ, + jabber_si_xfer_bytestreams_send_read_cb, xfer)); @@ -727,12 +707,12 @@
+ jsx = purple_xfer_get_protocol_data(xfer); /* In the case of a direct file transfer, this is expected to return */
if(type != JABBER_IQ_RESULT) {
purple_debug_info("jabber",
"jabber_si_xfer_connect_proxy_cb: type = error\n");
@@ -781,7 +761,7 @@
jsx->js->user->domain, jsx->js->user->resource);
if (!strcmp(jid, my_jid)) {
purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n");
- purple_xfer_start(xfer, xfer->fd, NULL, -1);
+ purple_xfer_start(xfer, purple_xfer_get_fd(xfer), NULL, -1); /* if available, try to revert to IBB... */
if (jsx->stream_method & STREAM_METHOD_IBB) {
@@ -805,9 +785,9 @@
/* Clean up the local streamhost - it isn't going to be used.*/
- if (xfer->watcher > 0) {
- purple_input_remove(xfer->watcher);
+ if (purple_xfer_get_watcher(xfer) > 0) { + purple_input_remove(purple_xfer_get_watcher(xfer)); + purple_xfer_set_watcher(xfer, 0); if (jsx->local_streamhost_fd >= 0) {
close(jsx->local_streamhost_fd);
@@ -835,7 +815,7 @@
JabberBytestreamsStreamhost *sh, *sh2;
int streamhost_count = 0;
+ jsx = purple_xfer_get_protocol_data(xfer); /* I'm not sure under which conditions this can happen
@@ -848,7 +828,7 @@
iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); query = xmlnode_get_child(iq->node, "query");
xmlnode_set_attrib(query, "sid", jsx->stream_id);
@@ -865,8 +845,8 @@
jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
jsx->js->user->domain, jsx->js->user->resource);
- xfer->local_port = purple_network_get_port_from_fd(sock);
- g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
+ purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock)); + g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer)); public_ip = purple_network_get_my_ip(jsx->js->fd);
@@ -896,8 +876,8 @@
/* The listener for the local proxy */
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_connected_cb, xfer);
+ purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ, + jabber_si_xfer_bytestreams_send_connected_cb, xfer)); for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) {
@@ -969,7 +949,7 @@
+ jsx = purple_xfer_get_protocol_data(xfer); /* TODO: This should probably be done with an account option instead of
* piggy-backing on the TOR proxy type. */
@@ -979,7 +959,7 @@
purple_debug_info("jabber", "Skipping attempting local streamhost.\n");
- jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
+ jsx->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, jabber_si_xfer_bytestreams_listen_cb, xfer);
if (jsx->listen_data == NULL) {
@@ -1017,7 +997,7 @@
PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); if (size <= purple_xfer_get_bytes_remaining(xfer)) {
purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
@@ -1037,7 +1017,7 @@
jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); @@ -1060,7 +1040,7 @@
const gchar *sid = xmlnode_get_attrib(open, "sid");
PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who);
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer);
@@ -1105,7 +1085,7 @@
jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer)
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); JabberIBBSession *sess = jsx->ibb_session;
gsize packet_size = len < jabber_ibb_session_get_max_data_size(sess) ?
len : jabber_ibb_session_get_max_data_size(sess);
@@ -1119,7 +1099,7 @@
jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess)
PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
- gsize remaining = purple_xfer_get_bytes_remaining(xfer);
+ goffset remaining = purple_xfer_get_bytes_remaining(xfer); @@ -1149,7 +1129,7 @@
jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer)
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id,
purple_xfer_get_remote_user(xfer), xfer);
@@ -1206,7 +1186,7 @@
for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) {
const char *var = xmlnode_get_attrib(field, "var");
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); if(var && !strcmp(var, "stream-method")) {
if((value = xmlnode_get_child(field, "value"))) {
@@ -1237,7 +1217,7 @@
static void jabber_si_xfer_send_request(PurpleXfer *xfer)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); xmlnode *si, *file, *feature, *x, *field, *option, *value;
@@ -1247,10 +1227,10 @@
purple_xfer_prepare_thumbnail(xfer, "jpeg,png");
- xfer->filename = g_path_get_basename(xfer->local_filename);
+ purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer))); iq = jabber_iq_new(jsx->js, JABBER_IQ_SET);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); si = xmlnode_new_child(iq->node, "si");
xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
jsx->stream_id = jabber_get_next_id(jsx->js);
@@ -1259,8 +1239,8 @@
file = xmlnode_new_child(si, "file");
xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
- xmlnode_set_attrib(file, "name", xfer->filename);
- g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
+ xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer)); + g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer)); xmlnode_set_attrib(file, "size", buf);
/* maybe later we'll do hash and date attribs */
@@ -1309,7 +1289,7 @@
static void jabber_si_xfer_free(PurpleXfer *xfer)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); JabberStream *js = jsx->js;
@@ -1324,10 +1304,9 @@
jabber_iq_remove_callback_by_id(js, jsx->iq_id);
if (jsx->local_streamhost_fd >= 0)
close(jsx->local_streamhost_fd);
- if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND &&
+ if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && purple_xfer_get_fd(xfer) >= 0) { purple_debug_info("jabber", "remove port mapping\n");
- purple_network_remove_port_mapping(xfer->fd);
+ purple_network_remove_port_mapping(purple_xfer_get_fd(xfer)); if (jsx->connect_timeout > 0)
purple_timeout_remove(jsx->connect_timeout);
@@ -1356,7 +1335,7 @@
/* XXX: free other stuff */
+ purple_xfer_set_protocol_data(xfer, NULL); @@ -1367,7 +1346,7 @@
static void jabber_si_xfer_cancel_send(PurpleXfer *xfer)
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); /* if there is an IBB session active, send close on that */
@@ -1380,7 +1359,7 @@
static void jabber_si_xfer_request_denied(PurpleXfer *xfer)
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); JabberStream *js = jsx->js;
@@ -1391,7 +1370,7 @@
iq = jabber_iq_new(js, JABBER_IQ_ERROR);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); jabber_iq_set_id(iq, jsx->iq_id);
error = xmlnode_new_child(iq->node, "error");
@@ -1412,7 +1391,7 @@
static void jabber_si_xfer_cancel_recv(PurpleXfer *xfer)
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); /* if there is an IBB session active, send close */
jabber_ibb_session_close(jsx->ibb_session);
@@ -1432,7 +1411,7 @@
JabberCapabilities capabilities, gpointer data)
PurpleXfer *xfer = (PurpleXfer *) data;
- JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); if (capabilities & JABBER_CAP_IBB) {
purple_debug_info("jabber",
@@ -1458,8 +1437,8 @@
static void do_transfer_send(PurpleXfer *xfer, const char *resource)
- JabberSIXfer *jsx = xfer->data;
- char **who_v = g_strsplit(xfer->who, "/", 2);
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); + char **who_v = g_strsplit(purple_xfer_get_remote_user(xfer), "/", 2); JabberBuddyResource *jbr = NULL;
@@ -1508,7 +1487,7 @@
static void jabber_si_xfer_init(PurpleXfer *xfer)
- JabberSIXfer *jsx = xfer->data;
+ JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -1516,7 +1495,7 @@
- if(NULL != (resource = jabber_get_resource(xfer->who))) {
+ if(NULL != (resource = jabber_get_resource(purple_xfer_get_remote_user(xfer)))) { /* they've specified a resource, no need to ask or
* default or anything, just do it */
@@ -1525,7 +1504,7 @@
- jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
+ jb = jabber_buddy_find(jsx->js, purple_xfer_get_remote_user(xfer), TRUE); @@ -1549,11 +1528,11 @@
- msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), purple_xfer_get_remote_user(xfer)); } else if(jb->subscription & JABBER_SUB_TO) {
- msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), purple_xfer_get_remote_user(xfer)); - msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), xfer->who);
+ msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), purple_xfer_get_remote_user(xfer)); purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
@@ -1566,7 +1545,7 @@
/* we've got multiple resources, we need to pick one to send to */
- char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), xfer->who);
+ char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), purple_xfer_get_remote_user(xfer)); PurpleRequestFields *fields = purple_request_fields_new();
PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
@@ -1582,7 +1561,7 @@
purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
- jsx->js->gc->account, xfer->who, NULL, xfer);
+ purple_connection_get_account(jsx->js->gc), purple_xfer_get_remote_user(xfer), NULL, xfer); @@ -1592,7 +1571,7 @@
xmlnode *si, *feature, *x, *field, *value;
iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT);
- xmlnode_set_attrib(iq->node, "to", xfer->who);
+ xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); jabber_iq_set_id(iq, jsx->iq_id);
@@ -1636,12 +1615,13 @@
+ js = purple_connection_get_protocol_data(gc); - xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who); - xfer->data = jsx = g_new0(JabberSIXfer, 1);
+ jsx = g_new0(JabberSIXfer, 1); + purple_xfer_set_protocol_data(xfer, jsx); jsx->local_streamhost_fd = -1;
@@ -1696,8 +1676,7 @@
const char *stream_id, *filename, *filesize_c, *profile;
- guint64 filesize_64 = 0;
if(!(profile = xmlnode_get_attrib(si, "profile")) ||
strcmp(profile, NS_SI_FILE_TRANSFER))
@@ -1713,17 +1692,7 @@
if((filesize_c = xmlnode_get_attrib(file, "size")))
- filesize_64 = g_ascii_strtoull(filesize_c, NULL, 10);
- /* TODO 3.0.0: When the core uses a guint64, this is redundant.
- if (filesize_64 > G_MAXSIZE) {
- /* Should this pop up a warning? */
- purple_debug_warning("jabber", "Unable to transfer file (too large)"
- " -- see #8477 for more details.");
- filesize = filesize_64;
+ filesize = g_ascii_strtoull(filesize_c, NULL, 10); if(!(feature = xmlnode_get_child(si, "feature")))
@@ -1774,10 +1743,10 @@
jsx->stream_id = g_strdup(stream_id);
jsx->iq_id = g_strdup(id);
- xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(js->gc), PURPLE_XFER_RECEIVE, from); g_return_if_fail(xfer != NULL);
+ purple_xfer_set_protocol_data(xfer, jsx); purple_xfer_set_filename(xfer, filename);
--- a/libpurple/protocols/null/nullprpl.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/null/nullprpl.c Fri Dec 23 08:21:58 2011 +0000
@@ -113,7 +113,7 @@
PurpleConnection *gc = (PurpleConnection *)(data);
GcFuncData *gcfdata = (GcFuncData *)userdata;
- if (!strcmp(gc->account->protocol_id, NULLPRPL_ID))
+ if (!strcmp(purple_account_get_protocol_id(purple_connection_get_account(gc)), NULLPRPL_ID)) gcfdata->fn(gcfdata->from, gc, gcfdata->userdata);
@@ -138,11 +138,11 @@
PurpleConnection *to = (PurpleConnection *)data;
ChatFuncData *cfdata = (ChatFuncData *)userdata;
- int id = cfdata->from_chat->id;
+ int id = purple_conv_chat_get_id(cfdata->from_chat); PurpleConversation *conv = purple_find_chat(to, id);
PurpleConvChat *chat = purple_conversation_get_chat_data(conv);
- cfdata->fn(cfdata->from_chat, chat, id, conv->name, cfdata->userdata);
+ cfdata->fn(cfdata->from_chat, chat, id, purple_conversation_get_name(conv), cfdata->userdata); @@ -160,11 +160,11 @@
static void discover_status(PurpleConnection *from, PurpleConnection *to,
- const char *from_username = from->account->username;
- const char *to_username = to->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(from)); + const char *to_username = purple_account_get_username(purple_connection_get_account(to)); - if (purple_find_buddy(from->account, to_username)) {
- PurpleStatus *status = purple_account_get_active_status(to->account);
+ if (purple_find_buddy(purple_connection_get_account(from), to_username)) { + PurpleStatus *status = purple_account_get_active_status(purple_connection_get_account(to)); const char *status_id = purple_status_get_id(status);
const char *message = purple_status_get_attr_string(status, "message");
@@ -173,7 +173,7 @@
!strcmp(status_id, NULL_STATUS_OFFLINE)) {
purple_debug_info("nullprpl", "%s sees that %s is %s: %s\n",
from_username, to_username, status_id, message);
- purple_prpl_got_user_status(from->account, to_username, status_id,
+ purple_prpl_got_user_status(purple_connection_get_account(from), to_username, status_id, (message) ? "message" : NULL, message, NULL);
purple_debug_error("nullprpl",
@@ -186,7 +186,7 @@
static void report_status_change(PurpleConnection *from, PurpleConnection *to,
purple_debug_info("nullprpl", "notifying %s that %s changed status\n",
- to->account->username, from->account->username);
+ purple_account_get_username(purple_connection_get_account(to)), purple_account_get_username(purple_connection_get_account(from))); discover_status(to, from, NULL);
@@ -199,7 +199,7 @@
PurpleConnection *gc = (PurpleConnection *)action->context;
PurpleAccount *acct = purple_connection_get_account(gc);
purple_debug_info("nullprpl", "showing 'Set User Info' dialog for %s\n",
+ purple_account_get_username(acct)); purple_account_request_change_user_info(acct);
@@ -225,7 +225,7 @@
static char *nullprpl_status_text(PurpleBuddy *buddy) {
purple_debug_info("nullprpl", "getting %s's status text for %s\n",
- buddy->name, buddy->account->username);
+ buddy->name, purple_account_get_username(buddy->account)); if (purple_find_buddy(buddy->account, buddy->name)) {
PurplePresence *presence = purple_buddy_get_presence(buddy);
@@ -260,16 +260,16 @@
char *msg = nullprpl_status_text(buddy);
/* TODO: Check whether it's correct to call add_pair_html,
or if we should be using add_pair_plaintext */
- purple_notify_user_info_add_pair(info, purple_status_get_name(status),
+ purple_notify_user_info_add_pair_html(info, purple_status_get_name(status), - const char *user_info = purple_account_get_user_info(gc->account);
+ const char *user_info = purple_account_get_user_info(purple_connection_get_account(gc)); /* TODO: Check whether it's correct to call add_pair_html,
or if we should be using add_pair_plaintext */
- purple_notify_user_info_add_pair(info, _("User info"), user_info);
+ purple_notify_user_info_add_pair_html(info, _("User info"), user_info); @@ -287,7 +287,7 @@
purple_debug_info("nullprpl", "returning status types for %s: %s, %s, %s\n",
+ purple_account_get_username(acct), NULL_STATUS_ONLINE, NULL_STATUS_AWAY, NULL_STATUS_OFFLINE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
@@ -366,7 +366,7 @@
PurpleConnection *gc = purple_account_get_connection(acct);
- purple_debug_info("nullprpl", "logging in %s\n", acct->username);
+ purple_debug_info("nullprpl", "logging in %s\n", purple_account_get_username(acct)); purple_connection_update_progress(gc, _("Connecting"),
0, /* which connection step this is */
@@ -385,12 +385,12 @@
/* fetch stored offline messages */
purple_debug_info("nullprpl", "checking for offline messages for %s\n",
- offline_messages = g_hash_table_lookup(goffline_messages, acct->username);
+ purple_account_get_username(acct)); + offline_messages = g_hash_table_lookup(goffline_messages, purple_account_get_username(acct)); while (offline_messages) {
GOfflineMessage *message = (GOfflineMessage *)offline_messages->data;
purple_debug_info("nullprpl", "delivering offline message to %s: %s\n",
- acct->username, message->message);
+ purple_account_get_username(acct), message->message); serv_got_im(gc, message->from, message->message, message->flags,
offline_messages = g_list_next(offline_messages);
@@ -401,7 +401,7 @@
g_list_free(offline_messages);
- g_hash_table_remove(goffline_messages, &acct->username);
+ g_hash_table_remove(goffline_messages, purple_account_get_username(acct)); static void nullprpl_close(PurpleConnection *gc)
@@ -413,7 +413,7 @@
static int nullprpl_send_im(PurpleConnection *gc, const char *who,
const char *message, PurpleMessageFlags flags)
- const char *from_username = gc->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(gc)); PurpleMessageFlags receive_flags = ((flags & ~PURPLE_MESSAGE_SEND)
PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID);
@@ -423,13 +423,13 @@
from_username, who, message);
/* is the sender blocked by the recipient's privacy settings? */
- if (to_acct && !purple_privacy_check(to_acct, gc->account->username)) {
+ if (to_acct && !purple_privacy_check(to_acct, purple_account_get_username(purple_connection_get_account(gc)))) { char *msg = g_strdup_printf(
_("Your message was blocked by %s's privacy settings."), who);
purple_debug_info("nullprpl",
"discarding; %s is blocked by %s's privacy settings\n",
- purple_conv_present_error(who, gc->account, msg);
+ purple_conv_present_error(who, purple_connection_get_account(gc), msg); @@ -461,7 +461,7 @@
static void nullprpl_set_info(PurpleConnection *gc, const char *info) {
purple_debug_info("nullprpl", "setting %s's user info to %s\n",
- gc->account->username, info);
+ purple_account_get_username(purple_connection_get_account(gc)), info); static const char *typing_state_to_string(PurpleTypingState typing) {
@@ -475,10 +475,10 @@
static void notify_typing(PurpleConnection *from, PurpleConnection *to,
- const char *from_username = from->account->username;
+ const char *from_username = purple_account_get_username(purple_connection_get_account(from)); const char *action = typing_state_to_string((PurpleTypingState)typing);
purple_debug_info("nullprpl", "notifying %s that %s %s\n",
- to->account->username, from_username, action);
+ purple_account_get_username(purple_connection_get_account(to)), from_username, action); @@ -489,7 +489,7 @@
static unsigned int nullprpl_send_typing(PurpleConnection *gc, const char *name,
PurpleTypingState typing) {
- purple_debug_info("nullprpl", "%s %s\n", gc->account->username,
+ purple_debug_info("nullprpl", "%s %s\n", purple_account_get_username(purple_connection_get_account(gc)), typing_state_to_string(typing));
foreach_nullprpl_gc(notify_typing, gc, (gpointer)typing);
@@ -501,7 +501,7 @@
purple_debug_info("nullprpl", "Fetching %s's user info for %s\n", username,
- gc->account->username);
+ purple_account_get_username(purple_connection_get_account(gc))); if (!get_nullprpl_gc(username)) {
char *msg = g_strdup_printf(_("%s is not logged in."), username);
@@ -516,7 +516,7 @@
body = _("No user info.");
/* TODO: Check whether it's correct to call add_pair_html,
or if we should be using add_pair_plaintext */
- purple_notify_user_info_add_pair(info, "Info", body);
+ purple_notify_user_info_add_pair_html(info, "Info", body); /* show a buddy's user info in a nice dialog box */
purple_notify_userinfo(gc, /* connection the buddy info came through */
@@ -529,35 +529,35 @@
static void nullprpl_set_status(PurpleAccount *acct, PurpleStatus *status) {
const char *msg = purple_status_get_attr_string(status, "message");
purple_debug_info("nullprpl", "setting %s's status to %s: %s\n",
- acct->username, purple_status_get_name(status), msg);
+ purple_account_get_username(acct), purple_status_get_name(status), msg); - foreach_nullprpl_gc(report_status_change, get_nullprpl_gc(acct->username),
+ foreach_nullprpl_gc(report_status_change, get_nullprpl_gc(purple_account_get_username(acct)), static void nullprpl_set_idle(PurpleConnection *gc, int idletime) {
purple_debug_info("nullprpl",
"purple reports that %s has been idle for %d seconds\n",
- gc->account->username, idletime);
+ purple_account_get_username(purple_connection_get_account(gc)), idletime); static void nullprpl_change_passwd(PurpleConnection *gc, const char *old_pass,
purple_debug_info("nullprpl", "%s wants to change their password\n",
- gc->account->username);
+ purple_account_get_username(purple_connection_get_account(gc))); static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
+ PurpleGroup *group, const char *message) - const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name);
purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name,
- PurpleAccount *buddy_acct = buddy_gc->account;
+ PurpleAccount *buddy_acct = purple_connection_get_account(buddy_gc); discover_status(gc, buddy_gc, NULL);
@@ -571,20 +571,20 @@
NULL, /* local account id (rarely used) */
+ message); /* message */ static void nullprpl_add_buddies(PurpleConnection *gc, GList *buddies,
+ GList *groups, const char *message) { purple_debug_info("nullprpl", "adding multiple buddies\n");
- nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data);
+ nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data, message); buddy = g_list_next(buddy);
group = g_list_next(group);
@@ -594,7 +594,7 @@
purple_debug_info("nullprpl", "removing %s from %s's buddy list\n",
- buddy->name, gc->account->username);
+ buddy->name, purple_account_get_username(purple_connection_get_account(gc))); static void nullprpl_remove_buddies(PurpleConnection *gc, GList *buddies,
@@ -620,22 +620,22 @@
static void nullprpl_add_permit(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s adds %s to their allowed list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name); static void nullprpl_add_deny(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s adds %s to their blocked list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name); static void nullprpl_rem_permit(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s removes %s from their allowed list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name); static void nullprpl_rem_deny(PurpleConnection *gc, const char *name) {
purple_debug_info("nullprpl", "%s removes %s from their blocked list\n",
- gc->account->username, name);
+ purple_account_get_username(purple_connection_get_account(gc)), name); static void nullprpl_set_permit_deny(PurpleConnection *gc) {
@@ -648,9 +648,9 @@
int id, const char *room, gpointer userdata) {
/* tell their chat window that we joined */
purple_debug_info("nullprpl", "%s sees that %s joined chat room %s\n",
- to->nick, from->nick, room);
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room); purple_conv_chat_add_user(to,
+ purple_conv_chat_get_nick(from), NULL, /* user-provided join message, IRC style */
TRUE); /* show a join message */
@@ -658,9 +658,9 @@
/* add them to our chat window */
purple_debug_info("nullprpl", "%s sees that %s is in chat room %s\n",
- from->nick, to->nick, room);
+ purple_conv_chat_get_nick(from), purple_conv_chat_get_nick(to), room); purple_conv_chat_add_user(from,
+ purple_conv_chat_get_nick(to), NULL, /* user-provided join message, IRC style */
FALSE); /* show a join message */
@@ -668,7 +668,7 @@
static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); const char *room = g_hash_table_lookup(components, "room");
int chat_id = g_str_hash(room);
purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room);
@@ -692,7 +692,7 @@
static void nullprpl_reject_chat(PurpleConnection *gc, GHashTable *components) {
const char *invited_by = g_hash_table_lookup(components, "invited_by");
const char *room = g_hash_table_lookup(components, "room");
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); PurpleConnection *invited_by_gc = get_nullprpl_gc(invited_by);
char *message = g_strdup_printf(
@@ -719,9 +719,9 @@
static void nullprpl_chat_invite(PurpleConnection *gc, int id,
const char *message, const char *who) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); PurpleConversation *conv = purple_find_chat(gc, id);
- const char *room = conv->name;
+ const char *room = purple_conversation_get_name(conv); PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID);
purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n",
@@ -752,9 +752,9 @@
/* tell their chat window that we left */
purple_debug_info("nullprpl", "%s sees that %s left chat room %s\n",
- to->nick, from->nick, room);
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room); purple_conv_chat_remove_user(to,
+ purple_conv_chat_get_nick(from), NULL); /* user-provided message, IRC style */
@@ -762,7 +762,7 @@
static void nullprpl_chat_leave(PurpleConnection *gc, int id) {
PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl", "%s is leaving chat room %s\n",
- gc->account->username, conv->name);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv)); /* tell everyone that we left */
foreach_gc_in_chat(left_chat_room, gc, id, NULL);
@@ -789,9 +789,9 @@
return PURPLE_CMD_RET_FAILED;
- from_username = conv->account->username;
+ from_username = purple_account_get_username(purple_conversation_get_account(conv)); purple_debug_info("nullprpl", "%s whispers to %s in chat room %s: %s\n",
- from_username, to_username, conv->name, message);
+ from_username, to_username, purple_conversation_get_name(conv), message); chat = purple_conversation_get_chat_data(conv);
chat_buddy = purple_conv_chat_cb_find(chat, to_username);
@@ -813,7 +813,7 @@
- serv_chat_whisper(to, chat->id, from_username, message);
+ serv_chat_whisper(to, purple_conv_chat_get_id(chat), from_username, message); return PURPLE_CMD_RET_OK;
@@ -821,11 +821,11 @@
static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who,
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl",
"%s receives whisper from %s in chat room %s: %s\n",
- username, who, conv->name, message);
+ username, who, purple_conversation_get_name(conv), message); /* receive whisper on recipient's account */
serv_got_chat_in(gc, id, who, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_WHISPER,
@@ -835,24 +835,24 @@
static void receive_chat_message(PurpleConvChat *from, PurpleConvChat *to,
int id, const char *room, gpointer userdata) {
const char *message = (const char *)userdata;
- PurpleConnection *to_gc = get_nullprpl_gc(to->nick);
+ PurpleConnection *to_gc = get_nullprpl_gc(purple_conv_chat_get_nick(to)); purple_debug_info("nullprpl",
"%s receives message from %s in chat room %s: %s\n",
- to->nick, from->nick, room, message);
- serv_got_chat_in(to_gc, id, from->nick, PURPLE_MESSAGE_RECV, message,
+ purple_conv_chat_get_nick(to), purple_conv_chat_get_nick(from), room, message); + serv_got_chat_in(to_gc, id, purple_conv_chat_get_nick(from), PURPLE_MESSAGE_RECV, message, static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message,
PurpleMessageFlags flags) {
- const char *username = gc->account->username;
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl",
"%s is sending message to chat room %s: %s\n", username,
+ purple_conversation_get_name(conv), message); /* send message to everyone in the chat room */
foreach_gc_in_chat(receive_chat_message, gc, id, (gpointer)message);
@@ -868,14 +868,14 @@
static void nullprpl_register_user(PurpleAccount *acct) {
purple_debug_info("nullprpl", "registering account for %s\n",
+ purple_account_get_username(acct)); static void nullprpl_get_cb_info(PurpleConnection *gc, int id, const char *who) {
PurpleConversation *conv = purple_find_chat(gc, id);
purple_debug_info("nullprpl",
"retrieving %s's info for %s in chat room %s\n", who,
- gc->account->username, conv->name);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv)); nullprpl_get_info(gc, who);
@@ -883,25 +883,25 @@
static void nullprpl_alias_buddy(PurpleConnection *gc, const char *who,
purple_debug_info("nullprpl", "%s sets %s's alias to %s\n",
- gc->account->username, who, alias);
+ purple_account_get_username(purple_connection_get_account(gc)), who, alias); static void nullprpl_group_buddy(PurpleConnection *gc, const char *who,
purple_debug_info("nullprpl", "%s has moved %s from group %s to group %s\n",
- gc->account->username, who, old_group, new_group);
+ purple_account_get_username(purple_connection_get_account(gc)), who, old_group, new_group); static void nullprpl_rename_group(PurpleConnection *gc, const char *old_name,
PurpleGroup *group, GList *moved_buddies) {
purple_debug_info("nullprpl", "%s has renamed group %s to %s\n",
- gc->account->username, old_name, group->name);
+ purple_account_get_username(purple_connection_get_account(gc)), old_name, group->name); static void nullprpl_convo_closed(PurpleConnection *gc, const char *who) {
purple_debug_info("nullprpl", "%s's conversation with %s was closed\n",
- gc->account->username, who);
+ purple_account_get_username(purple_connection_get_account(gc)), who); /* normalize a username (e.g. remove whitespace, add default domain, etc.)
@@ -915,20 +915,20 @@
static void nullprpl_set_buddy_icon(PurpleConnection *gc,
PurpleStoredImage *img) {
purple_debug_info("nullprpl", "setting %s's buddy icon to %s\n",
+ purple_account_get_username(purple_connection_get_account(gc)), img ? purple_imgstore_get_filename(img) : "(null)");
static void nullprpl_remove_group(PurpleConnection *gc, PurpleGroup *group) {
purple_debug_info("nullprpl", "%s has removed group %s\n",
- gc->account->username, group->name);
+ purple_account_get_username(purple_connection_get_account(gc)), group->name); static void set_chat_topic_fn(PurpleConvChat *from, PurpleConvChat *to,
int id, const char *room, gpointer userdata) {
const char *topic = (const char *)userdata;
- const char *username = from->conv->account->username;
+ const char *username = purple_account_get_username(purple_conversation_get_account(purple_conv_chat_get_conversation(from))); purple_conv_chat_set_topic(to, username, topic);
@@ -954,7 +954,7 @@
purple_debug_info("nullprpl", "%s sets topic of chat room '%s' to '%s'\n",
- gc->account->username, conv->name, topic);
+ purple_account_get_username(purple_connection_get_account(gc)), purple_conversation_get_name(conv), topic); last_topic = purple_conv_chat_get_topic(chat);
if ((!topic && !last_topic) ||
@@ -970,8 +970,8 @@
static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) {
- const char *username = gc->account->username;
- PurpleRoomlist *roomlist = purple_roomlist_new(gc->account);
+ const char *username = purple_account_get_username(purple_connection_get_account(gc)); + PurpleRoomlist *roomlist = purple_roomlist_new(purple_connection_get_account(gc)); PurpleRoomlistField *field;
@@ -994,8 +994,8 @@
for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) {
PurpleConversation *conv = (PurpleConversation *)chats->data;
PurpleRoomlistRoom *room;
- const char *name = conv->name;
- int id = purple_conversation_get_chat_data(conv)->id;
+ const char *name = purple_conversation_get_name(conv); + int id = purple_conv_chat_get_id(purple_conversation_get_chat_data(conv)); /* have we already added this room? */
if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp))
@@ -1019,14 +1019,17 @@
static void nullprpl_roomlist_cancel(PurpleRoomlist *list) {
+ PurpleAccount *account = purple_roomlist_get_account(list); purple_debug_info("nullprpl", "%s asked to cancel room list request\n",
- list->account->username);
+ purple_account_get_username(account)); static void nullprpl_roomlist_expand_category(PurpleRoomlist *list,
PurpleRoomlistRoom *category) {
+ PurpleAccount *account = purple_roomlist_get_account(list); purple_debug_info("nullprpl", "%s asked to expand room list category %s\n",
- list->account->username, category->name);
+ purple_account_get_username(account), + purple_roomlist_room_get_name(category)); /* nullprpl doesn't support file transfer...yet... */
@@ -1049,6 +1052,7 @@
static PurplePluginProtocolInfo prpl_info =
+ sizeof(PurplePluginProtocolInfo), /* struct_size */ OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC, /* options */
NULL, /* user_splits, initialized in nullprpl_init() */
NULL, /* protocol_options, initialized in nullprpl_init() */
@@ -1097,7 +1101,6 @@
nullprpl_register_user, /* register_user */
nullprpl_get_cb_info, /* get_cb_info */
- NULL, /* get_cb_away */
nullprpl_alias_buddy, /* alias_buddy */
nullprpl_group_buddy, /* group_buddy */
nullprpl_rename_group, /* rename_group */
@@ -1122,15 +1125,12 @@
NULL, /* unregister_user */
NULL, /* send_attention */
NULL, /* get_attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */ static void nullprpl_init(PurplePlugin *plugin)
--- a/libpurple/protocols/sametime/sametime.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/sametime/sametime.c Fri Dec 23 08:21:58 2011 +0000
@@ -171,10 +171,10 @@
-#define DEBUG_ERROR(a...) purple_debug_error(G_LOG_DOMAIN, a)
-#define DEBUG_INFO(a...) purple_debug_info(G_LOG_DOMAIN, a)
-#define DEBUG_MISC(a...) purple_debug_misc(G_LOG_DOMAIN, a)
-#define DEBUG_WARN(a...) purple_debug_warning(G_LOG_DOMAIN, a)
+#define DEBUG_ERROR(...) purple_debug_error(G_LOG_DOMAIN, __VA_ARGS__) +#define DEBUG_INFO(...) purple_debug_info(G_LOG_DOMAIN, __VA_ARGS__) +#define DEBUG_MISC(...) purple_debug_misc(G_LOG_DOMAIN, __VA_ARGS__) +#define DEBUG_WARN(...) purple_debug_warning(G_LOG_DOMAIN, __VA_ARGS__) /** ensure non-null strings */
@@ -197,7 +197,7 @@
/** the purple plugin data.
- available as gc->proto_data and mwSession_getClientData */
+ available as purple_connection_get_protocol_data(gc) and mwSession_getClientData */ struct mwPurplePluginData {
struct mwSession *session;
@@ -217,6 +217,7 @@
+ guint inpa; /* input watcher */ gint outpa; /* like inpa, but the other way */
/** circular buffer for outgoing data */
@@ -320,7 +321,7 @@
g_return_val_if_fail(gc != NULL, NULL);
+ pd = purple_connection_get_protocol_data(gc); g_return_val_if_fail(pd != NULL, NULL);
@@ -449,9 +450,9 @@
- purple_input_remove(gc->inpa);
+ purple_input_remove(pd->inpa); @@ -499,7 +500,7 @@
gc = mwAwareList_getClientData(list);
acct = purple_connection_get_account(gc);
+ pd = purple_connection_get_protocol_data(gc); idle = aware->status.time;
stat = aware->status.status;
@@ -851,7 +852,7 @@
static PurpleBuddy *buddy_ensure(PurpleConnection *gc, PurpleGroup *group,
struct mwSametimeUser *stuser) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); PurpleAccount *acct = purple_connection_get_account(gc);
@@ -927,6 +928,11 @@
+ DEBUG_WARN("Can't ensure a null group\n"); DEBUG_INFO("attempting to ensure group %s, called %s\n",
NSTR(name), NSTR(alias));
@@ -968,7 +974,7 @@
if(type == mwSametimeGroup_DYNAMIC) {
purple_blist_node_set_string(gn, GROUP_KEY_OWNER, owner);
- group_add(gc->proto_data, group);
+ group_add(purple_connection_get_protocol_data(gc), group); @@ -1274,7 +1280,7 @@
struct mwIdBlock who = { 0, 0 };
struct mwConversation *conv;
- gc = purple_conversation_get_gc(g_conv);
+ gc = purple_conversation_get_connection(g_conv); @@ -1398,7 +1404,7 @@
- purple_account_add_buddies(acct, add_buds);
+ purple_account_add_buddies(acct, add_buds, NULL); @@ -1755,9 +1761,9 @@
- purple_input_remove(pd->gc->inpa);
+ purple_input_remove(pd->inpa); @@ -1786,7 +1792,6 @@
static void connect_cb(gpointer data, gint source, const gchar *error_message) {
struct mwPurplePluginData *pd = data;
- PurpleConnection *gc = pd->gc;
@@ -1814,7 +1819,7 @@
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ,
+ pd->inpa = purple_input_add(source, PURPLE_INPUT_READ, mwSession_start(pd->session);
@@ -2139,7 +2144,7 @@
static void ft_incoming_cancel(PurpleXfer *xfer) {
/* incoming transfer rejected or cancelled in-progress */
- struct mwFileTransfer *ft = xfer->data;
+ struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer); if(ft) mwFileTransfer_reject(ft);
@@ -2155,9 +2160,9 @@
struct mwFileTransfer *ft;
- fp = g_fopen(xfer->local_filename, "wb");
+ ft = purple_xfer_get_protocol_data(xfer); + fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb"); mwFileTransfer_cancel(ft);
@@ -2202,7 +2207,7 @@
mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
+ purple_xfer_set_protocol_data(xfer, ft); purple_xfer_set_init_fnc(xfer, ft_incoming_init);
purple_xfer_set_cancel_recv_fnc(xfer, ft_incoming_cancel);
@@ -2219,7 +2224,7 @@
static void ft_send(struct mwFileTransfer *ft, FILE *fp) {
- struct mwOpaque o = { .data = buf, .len = MW_FT_LEN };
+ struct mwOpaque o = { MW_FT_LEN, buf }; @@ -2231,8 +2236,7 @@
if(fread(buf, (size_t) o.len, 1, fp)) {
/* calculate progress and display it */
- xfer->bytes_sent += o.len;
- xfer->bytes_remaining -= o.len;
+ purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + o.len); purple_xfer_update_progress(xfer);
mwFileTransfer_send(ft, &o);
@@ -2264,7 +2268,7 @@
if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
- xfer->dest_fp = g_fopen(xfer->local_filename, "rb");
+ xfer->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb"); ft_send(ft, xfer->dest_fp);
@@ -2281,7 +2285,7 @@
xfer = mwFileTransfer_getClientData(ft);
+ purple_xfer_set_protocol_data(xfer, NULL); if(! mwFileTransfer_getRemaining(ft)) {
purple_xfer_set_completed(xfer, TRUE);
@@ -2334,8 +2338,7 @@
/* update the progress */
- xfer->bytes_sent += data->len;
- xfer->bytes_remaining -= data->len;
+ purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + data->len); purple_xfer_update_progress(xfer);
/* let the other side know we got it, and to send some more */
@@ -2348,7 +2351,7 @@
xfer = mwFileTransfer_getClientData(ft);
g_return_if_fail(xfer != NULL);
- g_return_if_fail(xfer->watcher == 0);
+ g_return_if_fail(purple_xfer_get_watcher(xfer) == 0); if(! mwFileTransfer_getRemaining(ft)) {
purple_xfer_set_completed(xfer, TRUE);
@@ -2482,12 +2485,12 @@
text = g_strconcat(_("Unable to send message: "), tmp, NULL);
gconv = convo_get_gconv(conv);
- if(gconv && !purple_conv_present_error(idb->user, gconv->account, text)) {
+ if(gconv && !purple_conv_present_error(idb->user, purple_conversation_get_account(gconv), text)) { text = g_strdup_printf(_("Unable to send message to %s:"),
(idb->user)? idb->user: "(unknown)");
- purple_notify_error(purple_account_get_connection(gconv->account),
+ purple_notify_error(purple_account_get_connection(purple_conversation_get_account(gconv)), @@ -2525,10 +2528,10 @@
gconv = convo_get_gconv(conv);
- gc = purple_conversation_get_gc(gconv);
+ gc = purple_conversation_get_connection(gconv); - purple_conversation_set_features(gconv, gc->flags);
+ purple_conversation_set_features(gconv, purple_connection_get_flags(gc)); @@ -3194,7 +3197,7 @@
mwSession_addCipher(pd->session, mwCipher_new_RC2_128(pd->session));
mwSession_setClientData(pd->session, pd, NULL);
+ purple_connection_set_protocol_data(gc, pd); @@ -3203,7 +3206,7 @@
static void mwPurplePluginData_free(struct mwPurplePluginData *pd) {
g_return_if_fail(pd != NULL);
- pd->gc->proto_data = NULL;
+ purple_connection_set_protocol_data(pd->gc, NULL); mwSession_removeService(pd->session, mwService_AWARE);
mwSession_removeService(pd->session, mwService_CONFERENCE);
@@ -3265,7 +3268,7 @@
if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
- && (pd = gc->proto_data))
+ && (pd = purple_connection_get_protocol_data(gc))) ret = mwServiceAware_getText(pd->srvc_aware, &t);
return (ret && g_utf8_validate(ret, -1, NULL)) ? g_markup_escape_text(ret, -1): NULL;
@@ -3328,7 +3331,7 @@
if ((gc = purple_account_get_connection(purple_buddy_get_account(b)))
- && (pd = gc->proto_data))
+ && (pd = purple_connection_get_protocol_data(gc))) message = mwServiceAware_getText(pd->srvc_aware, &idb);
@@ -3405,7 +3408,7 @@
acct = purple_buddy_get_account(buddy);
gc = purple_account_get_connection(acct);
+ pd = purple_connection_get_protocol_data(gc); f = purple_request_fields_get_field(fields, CHAT_KEY_TOPIC);
@@ -3571,7 +3574,7 @@
gc = purple_account_get_connection(acct);
g_return_if_fail(gc != NULL);
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
@@ -3610,7 +3613,7 @@
gc = purple_account_get_connection(acct);
g_return_if_fail(gc != NULL);
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
rcpt_name = g_strdup_printf("@U %s", buddy->name);
@@ -3687,49 +3690,6 @@
static void mw_prpl_login(PurpleAccount *acct);
-static void prompt_host_cancel_cb(PurpleConnection *gc) {
- const char *msg = _("No Sametime Community Server specified");
- purple_connection_error(gc,
- PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
-static void prompt_host_ok_cb(PurpleConnection *gc, const char *host) {
- PurpleAccount *acct = purple_connection_get_account(gc);
- purple_account_set_string(acct, MW_KEY_HOST, host);
- prompt_host_cancel_cb(gc);
-static void prompt_host(PurpleConnection *gc) {
- acct = purple_connection_get_account(gc);
- msgA = _("No host or IP address has been configured for the"
- " Meanwhile account %s. Please enter one below to"
- " continue logging in.");
- msg = g_strdup_printf(msgA, NSTR(purple_account_get_username(acct)));
- purple_request_input(gc, _("Meanwhile Connection Setup"),
- _("No Sametime Community Server Specified"), msg,
- MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL,
- _("Connect"), G_CALLBACK(prompt_host_ok_cb),
- _("Cancel"), G_CALLBACK(prompt_host_cancel_cb),
static void mw_prpl_login(PurpleAccount *account) {
struct mwPurplePluginData *pd;
@@ -3741,7 +3701,7 @@
pd = mwPurplePluginData_new(gc);
/* while we do support images, the default is to not offer it */
- gc->flags |= PURPLE_CONNECTION_NO_IMAGES;
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_NO_IMAGES); user = g_strdup(purple_account_get_username(account));
@@ -3761,7 +3721,9 @@
/* somehow, we don't have a host to connect to. Well, we need one
to actually continue, so let's ask the user directly. */
+ purple_connection_error(gc, + PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, + _("A server is required to connect this account")); @@ -3815,7 +3777,7 @@
g_return_if_fail(gc != NULL);
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
/* get rid of the blist save timeout */
@@ -3829,12 +3791,12 @@
mwSession_stop(pd->session, 0x00);
/* no longer necessary */
+ purple_connection_set_protocol_data(gc, NULL); /* stop watching the socket */
- purple_input_remove(gc->inpa);
+ purple_input_remove(pd->inpa); @@ -4020,7 +3982,7 @@
struct mwConversation *conv;
g_return_val_if_fail(gc != NULL, 0);
+ pd = purple_connection_get_protocol_data(gc); g_return_val_if_fail(pd != NULL, 0);
@@ -4095,7 +4057,7 @@
gpointer t = GINT_TO_POINTER(!! state);
g_return_val_if_fail(gc != NULL, 0);
+ pd = purple_connection_get_protocol_data(gc); g_return_val_if_fail(pd != NULL, 0);
@@ -4191,7 +4153,7 @@
g_return_if_fail(who != NULL);
g_return_if_fail(*who != '\0');
+ pd = purple_connection_get_protocol_data(gc); acct = purple_connection_get_account(gc);
b = purple_find_buddy(acct, who);
@@ -4436,7 +4398,7 @@
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+ pd = purple_connection_get_protocol_data(gc); @@ -4515,9 +4477,10 @@
static void mw_prpl_add_buddy(PurpleConnection *gc,
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); struct mwServiceResolve *srvc;
enum mwResolveFlag flags;
@@ -4562,13 +4525,14 @@
static void mw_prpl_add_buddies(PurpleConnection *gc,
struct mwPurplePluginData *pd;
struct mwAwareIdBlock *idbs, *idb;
+ pd = purple_connection_get_protocol_data(gc); /* map PurpleGroup:GList of mwAwareIdBlock */
group_sets = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -4619,7 +4583,7 @@
GList *rem = g_list_prepend(NULL, &idb);
+ pd = purple_connection_get_protocol_data(gc); group = purple_buddy_get_group(buddy);
list = list_ensure(pd, group);
@@ -4666,13 +4630,13 @@
acct = purple_connection_get_account(gc);
g_return_if_fail(acct != NULL);
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
g_return_if_fail(session != NULL);
- switch(acct->perm_deny) {
+ switch(purple_account_get_privacy_type(acct)) { case PURPLE_PRIVACY_DENY_USERS:
DEBUG_INFO("PURPLE_PRIVACY_DENY_USERS\n");
privacy_fill(&privacy, acct->deny);
@@ -4696,7 +4660,7 @@
- DEBUG_INFO("acct->perm_deny is 0x%x\n", acct->perm_deny);
+ DEBUG_INFO("acct->perm_deny is 0x%x\n", purple_account_get_privacy_type(acct)); @@ -4750,7 +4714,7 @@
struct mwPurplePluginData *pd;
+ pd = purple_connection_get_protocol_data(gc); c = g_hash_table_lookup(components, CHAT_KEY_NAME);
t = g_hash_table_lookup(components, CHAT_KEY_TOPIC);
@@ -4792,7 +4756,7 @@
struct mwServiceConference *srvc;
+ pd = purple_connection_get_protocol_data(gc); if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) {
@@ -4824,7 +4788,7 @@
struct mwIdBlock idb = { (char *) who, NULL };
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
conf = ID_TO_CONF(pd, id);
@@ -4848,7 +4812,7 @@
struct mwPurplePluginData *pd;
struct mwConference *conf;
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
conf = ID_TO_CONF(pd, id);
@@ -4884,7 +4848,7 @@
+ pd = purple_connection_get_protocol_data(gc); g_return_val_if_fail(pd != NULL, 0);
conf = ID_TO_CONF(pd, id);
@@ -4922,7 +4886,7 @@
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
/* it's a change to the buddy list, so we've gotta reflect that in
@@ -4940,7 +4904,7 @@
struct mwAwareIdBlock idb = { mwAware_USER, (char *) who, NULL };
GList *gl = g_list_prepend(NULL, &idb);
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); struct mwAwareList *list;
@@ -4966,7 +4930,7 @@
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
/* it's a change in the buddy list, so we've gotta reflect that in
@@ -4986,7 +4950,7 @@
static void mw_prpl_convo_closed(PurpleConnection *gc, const char *who) {
- struct mwPurplePluginData *pd = gc->proto_data;
+ struct mwPurplePluginData *pd = purple_connection_get_protocol_data(gc); struct mwServiceIm *srvc;
struct mwConversation *conv;
struct mwIdBlock idb = { (char *) who, NULL };
@@ -5021,7 +4985,7 @@
struct mwPurplePluginData *pd;
struct mwAwareList *list;
+ pd = purple_connection_get_protocol_data(gc); g_return_if_fail(pd != NULL);
g_return_if_fail(pd->group_list_map != NULL);
@@ -5045,7 +5009,7 @@
g_return_val_if_fail(gc != NULL, FALSE);
+ pd = purple_connection_get_protocol_data(gc); g_return_val_if_fail(pd != NULL, FALSE);
@@ -5077,12 +5041,12 @@
acct = purple_xfer_get_account(xfer);
gc = purple_account_get_connection(acct);
+ pd = purple_connection_get_protocol_data(gc); filename = purple_xfer_get_local_filename(xfer);
filesize = purple_xfer_get_size(xfer);
+ idb.user = purple_xfer_get_remote_user(xfer); purple_xfer_update_progress(xfer);
@@ -5091,7 +5055,7 @@
char *msg = g_strdup_printf(_("Error reading file %s: \n%s\n"),
filename, g_strerror(errno));
- purple_xfer_error(purple_xfer_get_type(xfer), acct, xfer->who, msg);
+ purple_xfer_error(purple_xfer_get_type(xfer), acct, purple_xfer_get_remote_user(xfer), msg); @@ -5106,14 +5070,14 @@
mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
+ purple_xfer_set_protocol_data(xfer, ft); mwFileTransfer_offer(ft);
static void ft_outgoing_cancel(PurpleXfer *xfer) {
- struct mwFileTransfer *ft = xfer->data;
+ struct mwFileTransfer *ft = purple_xfer_get_protocol_data(xfer); DEBUG_INFO("ft_outgoing_cancel called\n");
@@ -5154,67 +5118,77 @@
static PurplePluginProtocolInfo mw_prpl_info = {
- .options = OPT_PROTO_IM_IMAGE,
- .user_splits = NULL, /*< set in mw_plugin_init */
- .protocol_options = NULL, /*< set in mw_plugin_init */
- .icon_spec = NO_BUDDY_ICONS,
- .list_icon = mw_prpl_list_icon,
- .list_emblem = mw_prpl_list_emblem,
- .status_text = mw_prpl_status_text,
- .tooltip_text = mw_prpl_tooltip_text,
- .status_types = mw_prpl_status_types,
- .blist_node_menu = mw_prpl_blist_node_menu,
- .chat_info = mw_prpl_chat_info,
- .chat_info_defaults = mw_prpl_chat_info_defaults,
- .login = mw_prpl_login,
- .close = mw_prpl_close,
- .send_im = mw_prpl_send_im,
- .send_typing = mw_prpl_send_typing,
- .get_info = mw_prpl_get_info,
- .set_status = mw_prpl_set_status,
- .set_idle = mw_prpl_set_idle,
- .add_buddy = mw_prpl_add_buddy,
- .add_buddies = mw_prpl_add_buddies,
- .remove_buddy = mw_prpl_remove_buddy,
- .remove_buddies = NULL,
- .add_permit = mw_prpl_add_permit,
- .add_deny = mw_prpl_add_deny,
- .rem_permit = mw_prpl_rem_permit,
- .rem_deny = mw_prpl_rem_deny,
- .set_permit_deny = mw_prpl_set_permit_deny,
- .join_chat = mw_prpl_join_chat,
- .reject_chat = mw_prpl_reject_chat,
- .get_chat_name = mw_prpl_get_chat_name,
- .chat_invite = mw_prpl_chat_invite,
- .chat_leave = mw_prpl_chat_leave,
- .chat_whisper = mw_prpl_chat_whisper,
- .chat_send = mw_prpl_chat_send,
- .keepalive = mw_prpl_keepalive,
- .alias_buddy = mw_prpl_alias_buddy,
- .group_buddy = mw_prpl_group_buddy,
- .rename_group = mw_prpl_rename_group,
- .buddy_free = mw_prpl_buddy_free,
- .convo_closed = mw_prpl_convo_closed,
- .normalize = mw_prpl_normalize,
- .set_buddy_icon = NULL,
- .remove_group = mw_prpl_remove_group,
- .get_cb_real_name = NULL,
- .set_chat_topic = NULL,
- .find_blist_chat = NULL,
- .roomlist_get_list = NULL,
- .roomlist_expand_category = NULL,
- .can_receive_file = mw_prpl_can_receive_file,
- .send_file = mw_prpl_send_file,
- .new_xfer = mw_prpl_new_xfer,
- .offline_message = NULL,
- .whiteboard_prpl_ops = NULL,
- .struct_size = sizeof(PurplePluginProtocolInfo)
+ sizeof(PurplePluginProtocolInfo), + NULL, /*< set in mw_plugin_init */ + NULL, /*< set in mw_plugin_init */ + mw_prpl_blist_node_menu, + mw_prpl_chat_info_defaults, + mw_prpl_set_permit_deny, + mw_prpl_can_receive_file, @@ -5536,7 +5510,7 @@
enum mwResolveFlag flags;
+ pd = purple_connection_get_protocol_data(gc); query = g_list_prepend(NULL, (char *) name);
@@ -5661,7 +5635,7 @@
enum mwResolveFlag flags;
+ pd = purple_connection_get_protocol_data(gc); query = g_list_prepend(NULL, (char *) name);
@@ -5791,6 +5765,7 @@
static void mw_plugin_init(PurplePlugin *plugin) {
+ PurpleAccountUserSplit *split; PurpleAccountOption *opt;
@@ -5801,15 +5776,15 @@
purple_prefs_add_none(MW_PRPL_OPT_BASE);
purple_prefs_add_int(MW_PRPL_OPT_BLIST_ACTION, BLIST_CHOICE_DEFAULT);
+ /* set up account ID as user:server */ + split = purple_account_user_split_new(_("Server"), + MW_PLUGIN_DEFAULT_HOST, ':'); + mw_prpl_info.user_splits = g_list_append(mw_prpl_info.user_splits, split); /* remove dead preferences */
purple_prefs_remove(MW_PRPL_OPT_PSYCHIC);
purple_prefs_remove(MW_PRPL_OPT_SAVE_DYNAMIC);
- /* host to connect to */
- opt = purple_account_option_string_new(_("Server"), MW_KEY_HOST,
- MW_PLUGIN_DEFAULT_HOST);
- l = g_list_append(l, opt);
opt = purple_account_option_int_new(_("Port"), MW_KEY_PORT,
--- a/libpurple/protocols/yahoo/libymsg.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c Fri Dec 23 08:21:58 2011 +0000
@@ -337,12 +337,12 @@
- b = purple_find_buddy(gc->account, name);
+ b = purple_find_buddy(purple_connection_get_account(gc), name); if (!cksum || (cksum == -1)) {
yahoo_friend_set_buddy_icon_need_request(f, TRUE);
- purple_buddy_icons_set_for_user(gc->account, name, NULL, 0, NULL);
+ purple_buddy_icons_set_for_user(purple_connection_get_account(gc), name, NULL, 0, NULL); @@ -496,7 +496,7 @@
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -573,7 +573,7 @@
yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT);
/* This buddy is on the ignore list (and therefore in no group) */
- purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n",account->username, norm_bud);
+ purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n", purple_account_get_username(account), norm_bud); purple_privacy_deny_add(account, norm_bud, 1);
@@ -634,11 +634,10 @@
static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
- gboolean export = FALSE;
gboolean got_serv_list = FALSE;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -712,7 +711,6 @@
b = purple_buddy_new(account, norm_bud, NULL);
purple_blist_add_buddy(b, NULL, g, NULL);
yahoo_do_group_check(account, ht, norm_bud, grp);
@@ -748,13 +746,13 @@
- ((account->perm_deny != PURPLE_PRIVACY_ALLOW_BUDDYLIST) &&
- (account->perm_deny != PURPLE_PRIVACY_DENY_ALL) &&
- (account->perm_deny != PURPLE_PRIVACY_ALLOW_USERS)))
+ ((purple_account_get_privacy_type(account) != PURPLE_PRIVACY_ALLOW_BUDDYLIST) && + (purple_account_get_privacy_type(account) != PURPLE_PRIVACY_DENY_ALL) && + (purple_account_get_privacy_type(account) != PURPLE_PRIVACY_ALLOW_USERS))) - account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
+ purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS); purple_debug_info("yahoo", "%s privacy defaulting to PURPLE_PRIVACY_DENY_USERS.\n",
+ purple_account_get_username(account)); if (yd->tmp_serv_plist) {
@@ -763,7 +761,7 @@
f = yahoo_friend_find(gc, *bud);
purple_debug_info("yahoo", "%s setting presence for %s to PERM_OFFLINE\n",
- account->username, *bud);
+ purple_account_get_username(account), *bud); f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
@@ -787,7 +785,7 @@
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); YahooFederation fed = YAHOO_FEDERATION_NONE;
account = purple_connection_get_account(gc);
@@ -899,7 +897,7 @@
+ yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
@@ -960,7 +958,7 @@
static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct _yahoo_im *im = NULL;
@@ -1061,7 +1059,7 @@
wb = purple_whiteboard_create(account, im->from,
+ ds = purple_whiteboard_get_protocol_data(wb); ds->imv_key = g_strdup(pair->value);
yahoo_doodle_command_send_request(gc, im->from, pair->value);
@@ -1202,7 +1200,7 @@
struct yahoo_add_request *add_req = data;
struct yahoo_packet *pkt;
- YahooData *yd = add_req->gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(add_req->gc); const char *who = add_req->who;
pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -1233,7 +1231,7 @@
yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg)
- YahooData *yd = add_req->gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(add_req->gc); struct yahoo_packet *pkt;
char *encoded_msg = NULL;
const char *who = add_req->who;
@@ -1295,7 +1293,7 @@
static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -1625,7 +1623,7 @@
static void yahoo_process_mail(PurpleConnection *gc, struct yahoo_packet *pkt)
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); const char *email = NULL;
@@ -1709,7 +1707,7 @@
static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc);
const char *name = purple_normalize(account, purple_account_get_username(account));
PurpleCipher *md5_cipher;
@@ -2014,7 +2012,7 @@
gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
url = g_strdup_printf(yahoojp ? YAHOOJP_LOGIN_URL : YAHOO_LOGIN_URL, token);
- url_data = purple_util_fetch_url_request_len(
+ url_data = purple_util_fetch_url_request( proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT,
TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data);
@@ -2055,7 +2053,7 @@
g_free(encoded_password);
g_free(encoded_username);
- url_data = purple_util_fetch_url_request_len(
+ url_data = purple_util_fetch_url_request( proxy_ssl ? account : NULL, url, TRUE,
YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
yahoo_auth16_stage1_cb, auth_data);
@@ -2180,12 +2178,12 @@
who, (ignore ? "ignoring" : "unignoring"));
- b = purple_find_buddy(gc->account, who);
+ b = purple_find_buddy(purple_connection_get_account(gc), who); g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the "
"user is on your buddy list. Clicking \"Yes\" "
"will remove and ignore the buddy."), who);
purple_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0,
- gc->account, who, NULL,
+ purple_connection_get_account(gc), who, NULL, G_CALLBACK(ignore_buddy),
@@ -2207,14 +2205,14 @@
static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pkt)
#ifdef TRY_WEBMESSENGER_LOGIN
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); #endif /* TRY_WEBMESSENGER_LOGIN */
- PurpleAccount *account = gc->account;
+ PurpleAccount *account = purple_connection_get_account(gc); PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
@@ -2244,10 +2242,12 @@
- purple_input_remove(gc->inpa);
+ purple_input_remove(yd->inpa); url_data = purple_util_fetch_url(WEBMESSENGER_URL, TRUE,
- "Purple/" VERSION, FALSE, yahoo_login_page_cb, gc);
+ "Purple/" VERSION, FALSE, -1, yahoo_login_page_cb, gc); yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
@@ -2300,7 +2300,7 @@
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -2394,7 +2394,7 @@
PurpleConnection *gc = user_data;
struct yahoo_packet *pkt_to_send;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
@@ -2413,7 +2413,7 @@
static gboolean yahoo_p2p_keepalive(gpointer data)
PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); g_hash_table_foreach(yd->peers, yahoo_p2p_keepalive_cb, gc);
@@ -2460,7 +2460,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); /* lets see whats in the packet */
@@ -2545,7 +2545,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); len = read(source, buf, sizeof(buf));
if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
@@ -2617,7 +2617,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); acceptfd = accept(source, NULL, 0);
if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
@@ -2657,7 +2657,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); purple_debug_warning("yahoo","yahoo p2p server timeout, peer failed to connect\n");
yahoo_p2p_disconnect_destroy_data(data);
@@ -2678,7 +2678,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); @@ -2706,7 +2706,7 @@
struct yahoo_packet *pkt;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_p2p_data *p2p_data;
const char *norm_username;
@@ -2770,7 +2770,7 @@
purple_debug_warning("yahoo","p2p: Failed to create p2p server - server already exists\n");
- yd->listen_data = purple_network_listen(YAHOO_PAGER_PORT_P2P, SOCK_STREAM, yahoo_p2p_server_listen_cb, p2p_data);
+ yd->listen_data = purple_network_listen(YAHOO_PAGER_PORT_P2P, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_server_listen_cb, p2p_data); if (yd->listen_data == NULL)
purple_debug_warning("yahoo","p2p: Failed to created p2p server\n");
@@ -2787,7 +2787,7 @@
- yd = p2p_data->gc->proto_data;
+ yd = purple_connection_get_protocol_data(p2p_data->gc); if(error_message != NULL) {
purple_debug_warning("yahoo","p2p: %s\n",error_message);
@@ -3132,7 +3132,7 @@
static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond)
PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -3155,7 +3155,7 @@
_("Server closed the connection"));
- gc->last_received = time(NULL);
+ purple_connection_update_last_received(gc); yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen);
memcpy(yd->rxqueue + yd->rxlen, buf, len);
@@ -3240,15 +3240,15 @@
+ yd = purple_connection_get_protocol_data(gc); pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, yd->current_status, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))));
+ yahoo_packet_hash_str(pkt, 1, purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc)))); yahoo_packet_send_and_free(pkt, yd);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
+ yd->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc); #ifdef TRY_WEBMESSENGER_LOGIN
@@ -3266,26 +3266,26 @@
+ yd = purple_connection_get_protocol_data(gc); pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, yd->session_id);
yahoo_packet_hash(pkt, "sss", 0,
- purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
- 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
+ purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc))), + 1, purple_normalize(purple_connection_get_account(gc), purple_account_get_username(purple_connection_get_account(gc))), yahoo_packet_send_and_free(pkt, yd);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
+ yd->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc); static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition cond)
PurpleConnection *gc = data;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); char bufread[2048], *i = bufread, *buf = bufread;
@@ -3342,7 +3342,8 @@
yd->auth = g_string_free(s, FALSE);
- purple_input_remove(gc->inpa);
+ purple_input_remove(yd->inpa); @@ -3359,13 +3360,10 @@
static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCondition cond)
+ PurpleConnection *gc = data; + YahooData *yd = purple_connection_get_protocol_data(gc);
remaining = strlen(yd->auth) - yd->auth_written;
written = write(source, yd->auth + yd->auth_written, remaining);
@@ -3375,9 +3373,10 @@
- purple_input_remove(gc->inpa);
+ purple_input_remove(yd->inpa); tmp = g_strdup_printf(_("Lost connection with %s: %s"),
"login.yahoo.com:80", g_strerror(errno));
purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
@@ -3393,13 +3392,14 @@
- purple_input_remove(gc->inpa);
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ, yahoo_web_pending, gc);
+ purple_input_remove(yd->inpa); + yd->inpa = purple_input_add(source, PURPLE_INPUT_READ, yahoo_web_pending, gc); static void yahoo_got_cookies(gpointer data, gint source, const gchar *error_message)
PurpleConnection *gc = data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -3410,9 +3410,9 @@
- gc->inpa = purple_input_add(source, PURPLE_INPUT_WRITE,
+ yd->inpa = purple_input_add(source, PURPLE_INPUT_WRITE, yahoo_got_cookies_send_cb, gc);
yahoo_got_cookies_send_cb(gc, source, PURPLE_INPUT_WRITE);
@@ -3474,7 +3474,7 @@
PurpleConnection *gc = (PurpleConnection *)user_data;
PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); const char *sn = purple_account_get_username(account);
const char *pass = purple_connection_get_password(gc);
GHashTable *hash = yahoo_login_page_hash(url_text, len);
@@ -3671,13 +3671,14 @@
void yahoo_login(PurpleAccount *account) {
PurpleConnection *gc = purple_account_get_connection(account);
- YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
+ YahooData *yd = g_new0(YahooData, 1); PurpleStatus *status = purple_account_get_active_status(account);
gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
PurpleUtilFetchUrlData *url_data;
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
+ purple_connection_set_protocol_data(gc, yd); + purple_connection_set_flags(gc, PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC); purple_connection_update_progress(gc, _("Connecting"), 1, 2);
@@ -3708,7 +3709,7 @@
/* Get the pager server. Actually start connecting in the callback since we
* must have the contents of the HTTP response to proceed. */
- url_data = purple_util_fetch_url_request_len(
+ url_data = purple_util_fetch_url_request( proxy_ssl ? purple_connection_get_account(gc) : NULL,
yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
use_whole_url ? TRUE : FALSE,
@@ -3721,11 +3722,13 @@
void yahoo_close(PurpleConnection *gc) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc);
- purple_input_remove(gc->inpa);
+ purple_input_remove(yd->inpa); purple_util_fetch_url_cancel(yd->url_datas->data);
@@ -3810,7 +3813,7 @@
g_free(yd->current_list15_grp);
+ purple_connection_set_protocol_data(gc, NULL); const char *yahoo_list_icon(PurpleAccount *a, PurpleBuddy *b)
@@ -3827,7 +3830,7 @@
if (!b || !(account = purple_buddy_get_account(b)) ||
!(gc = purple_account_get_connection(account)) ||
+ !purple_connection_get_protocol_data(gc)) f = yahoo_friend_find(gc, purple_buddy_get_name(b));
@@ -3892,7 +3895,7 @@
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+ yd = purple_connection_get_protocol_data(gc); components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -4055,7 +4058,7 @@
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yahoo_add_buddy(gc, buddy, NULL);
+ yahoo_add_buddy(gc, buddy, NULL, NULL); @@ -4075,7 +4078,7 @@
static GList *build_presence_submenu(YahooFriend *f, PurpleConnection *gc) {
- YahooData *yd = (YahooData *) gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
if (f->presence != YAHOO_PRESENCE_ONLINE) {
@@ -4135,7 +4138,7 @@
PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); @@ -4218,7 +4221,7 @@
static void yahoo_act_id(PurpleConnection *gc, PurpleRequestFields *fields)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); const char *name = yd->profiles[purple_request_fields_get_choice(fields, "id")];
struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -4235,7 +4238,7 @@
PurpleConnection *gc = user_data;
gboolean set_cookie = FALSE;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
@@ -4271,7 +4274,7 @@
/* XXX I have no idea how this will work with Yahoo! Japan. */
PurpleConnection *gc = action->context;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); PurpleUtilFetchUrlData *url_data;
const char* base_url = "http://login.yahoo.com";
@@ -4286,7 +4289,7 @@
use_whole_url ? base_url : "",
yd->cookie_t, yd->cookie_y);
- url_data = purple_util_fetch_url_request_len(
+ url_data = purple_util_fetch_url_request( purple_connection_get_account(gc), base_url, use_whole_url,
YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
yahoo_get_inbox_token_cb, gc);
@@ -4385,7 +4388,7 @@
struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data;
PurpleConnection *gc = sms_cb_data->gc;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc);
@@ -4440,7 +4443,7 @@
static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); PurpleUtilFetchUrlData *url_data;
struct yahoo_sms_carrier_cb_data *sms_cb_data;
char *validate_request_str = NULL;
@@ -4475,10 +4478,10 @@
YAHOO_CLIENT_VERSION, yd->cookie_t, yd->cookie_y, strlen(validate_request_str), validate_request_str);
/* use whole URL if using HTTP Proxy */
- if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
+ if ((purple_account_get_proxy_info(purple_connection_get_account(gc))) && (purple_proxy_info_get_type(purple_account_get_proxy_info(purple_connection_get_account(gc))) == PURPLE_PROXY_HTTP)) - url_data = purple_util_fetch_url_request_len(
+ url_data = purple_util_fetch_url_request( purple_connection_get_account(gc), YAHOO_SMS_CARRIER_URL, use_whole_url,
YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
yahoo_get_sms_carrier_cb, data);
@@ -4500,7 +4503,7 @@
int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt = NULL;
char *msg = yahoo_html_to_codes(what);
@@ -4611,7 +4614,7 @@
* If they have not set an IMVironment, then use the default.
- wb = purple_whiteboard_get_session(gc->account, who);
+ wb = purple_whiteboard_get_session(purple_connection_get_account(gc), who); yahoo_packet_hash_str(pkt, 63, DOODLE_IMV_KEY);
@@ -4657,7 +4660,7 @@
unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_p2p_data *p2p_data;
YahooFederation fed = YAHOO_FEDERATION_NONE;
struct yahoo_packet *pkt = NULL;
@@ -4728,7 +4731,7 @@
gc = purple_account_get_connection(account);
presence = purple_status_get_presence(status);
- yd = (YahooData *)gc->proto_data;
+ yd = purple_connection_get_protocol_data(gc); old_status = yd->current_status;
yd->current_status = get_yahoo_status_from_purple_status(status);
@@ -4794,7 +4797,7 @@
void yahoo_set_idle(PurpleConnection *gc, int idle)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt = NULL;
char *msg = NULL, *msg2 = NULL;
PurpleStatus *status = NULL;
@@ -4913,7 +4916,7 @@
void yahoo_keepalive(PurpleConnection *gc)
struct yahoo_packet *pkt;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); /* We're only allowed to send a ping once an hour or the servers will boot us */
@@ -4944,9 +4947,9 @@
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
+void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g, const char *message) - YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
const char *group = NULL;
@@ -5009,7 +5012,7 @@
void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
@@ -5065,7 +5068,7 @@
void yahoo_add_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -5088,7 +5091,7 @@
void yahoo_rem_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -5116,7 +5119,7 @@
account = purple_connection_get_account(gc);
- switch (account->perm_deny)
+ switch (purple_account_get_privacy_type(account)) case PURPLE_PRIVACY_ALLOW_ALL:
for (deny = account->deny; deny; deny = deny->next)
@@ -5136,7 +5139,7 @@
void yahoo_change_buddys_group(PurpleConnection *gc, const char *who,
const char *old_group, const char *new_group)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
YahooFriend *f = yahoo_friend_find(gc, who);
@@ -5183,7 +5186,7 @@
void yahoo_rename_group(PurpleConnection *gc, const char *old_name,
PurpleGroup *group, GList *moved_buddies)
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); struct yahoo_packet *pkt;
@@ -5212,7 +5215,7 @@
return PURPLE_CMD_RET_FAILED;
- purple_prpl_send_attention(account->gc, c->name, YAHOO_BUZZ);
+ purple_prpl_send_attention(purple_account_get_connection(account), purple_conversation_get_name(c), YAHOO_BUZZ); return PURPLE_CMD_RET_OK;
@@ -5227,7 +5230,7 @@
return PURPLE_CMD_RET_FAILED;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv); purple_debug_info("yahoo", "Trying to join %s \n", args[0]);
comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -5261,12 +5264,12 @@
c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- username, gc->account);
+ username, purple_connection_get_account(gc)); g_return_val_if_fail(c != NULL, FALSE);
purple_debug_info("yahoo", "Sending <ding> on account %s to buddy %s.\n",
+ username, purple_conversation_get_name(c)); purple_conv_im_send_with_flags(PURPLE_CONV_IM(c), "<ding>", PURPLE_MESSAGE_INVISIBLE);
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Fri Dec 23 08:21:58 2011 +0000
@@ -43,7 +43,7 @@
@@ -85,7 +85,7 @@
+ yd = purple_connection_get_protocol_data(gc); /* remove entry from map */
if(xd->xfer_peer_idstring) {
@@ -120,13 +120,13 @@
struct yahoo_xfer_data *xd;
- int remaining, written;
+ gssize remaining, written;
+ xd = purple_xfer_get_protocol_data(xfer); remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+ written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining); if (written < 0 && errno == EAGAIN)
@@ -160,22 +160,23 @@
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect.")); purple_xfer_cancel_remote(xfer);
+ purple_xfer_set_fd(xfer, source); /* The first time we get here, assemble the tx buffer */
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
+ gchar *header = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", - xd->txbuflen = strlen(xd->txbuf);
+ xd->txbuf = (guchar*) header; + xd->txbuflen = strlen(header); @@ -191,13 +192,13 @@
struct yahoo_xfer_data *xd;
- int written, remaining;
+ gssize written, remaining;
+ xd = purple_xfer_get_protocol_data(xfer); remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
+ written = purple_xfer_write(xfer, xd->txbuf + xd->txbuf_written, remaining); if (written < 0 && errno == EAGAIN)
@@ -239,32 +240,32 @@
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect.")); purple_xfer_cancel_remote(xfer);
+ purple_xfer_set_fd(xfer, source); /* Assemble the tx buffer */
account = purple_connection_get_account(gc);
+ yd = purple_connection_get_protocol_data(gc); pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER,
YAHOO_STATUS_AVAILABLE, yd->session_id);
- size = g_strdup_printf("%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));
+ size = g_strdup_printf("%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer)); filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
encoded_filename = yahoo_string_encode(gc, filename, NULL);
yahoo_packet_hash(pkt, "sssss", 0, purple_connection_get_display_name(gc),
- 5, xfer->who, 14, "", 27, encoded_filename, 28, size);
+ 5, purple_xfer_get_remote_user(xfer), 14, "", 27, encoded_filename, 28, size); g_free(encoded_filename);
@@ -278,7 +279,7 @@
port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);
header = g_strdup_printf(
"POST http://%s:%d/notifyft HTTP/1.0\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n"
+ "Content-length: %" G_GOFFSET_FORMAT "\r\n" @@ -313,9 +314,9 @@
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
+ yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -339,7 +340,7 @@
+ purple_xfer_set_fd(xfer, -1); if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
yahoo_receivefile_connected, xfer) == NULL) {
purple_notify_error(gc, NULL, _("File Transfer Failed"),
@@ -357,9 +358,9 @@
struct yahoo_packet *pkt;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer);
+ yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
@@ -370,14 +371,14 @@
yahoo_packet_hash(pkt, "sssiiiisiii",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
+ 28, (int)purple_xfer_get_size(xfer), @@ -388,7 +389,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -397,7 +398,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -410,14 +411,14 @@
/* We don't need to do anything here, do we? */
-static guint calculate_length(const gchar *l, size_t len)
+static goffset calculate_length(const gchar *l, size_t len) for (i = 0; i < len; i++) {
if (!g_ascii_isdigit(l[i]))
- return strtol(l + i, NULL, 10);
+ return g_ascii_strtoll(l + i, NULL, 10); @@ -429,14 +430,14 @@
- struct yahoo_xfer_data *xd = xfer->data;
+ struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer); if (purple_xfer_get_type(xfer) != PURPLE_XFER_RECEIVE) {
- len = read(xfer->fd, buf, sizeof(buf));
+ len = read(purple_xfer_get_fd(xfer), buf, sizeof(buf)); if ((purple_xfer_get_size(xfer) > 0) &&
@@ -490,7 +491,7 @@
static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
- struct yahoo_xfer_data *xd = xfer->data;
+ struct yahoo_xfer_data *xd = purple_xfer_get_protocol_data(xfer); @@ -499,7 +500,7 @@
- len = write(xfer->fd, buffer, size);
+ len = write(purple_xfer_get_fd(xfer), buffer, size); if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))
@@ -516,7 +517,7 @@
struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer); if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
@@ -526,7 +527,7 @@
struct yahoo_packet *pkt;
+ yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
if(xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
@@ -535,7 +536,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -546,7 +547,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -556,14 +557,14 @@
yahoo_xfer_data_free(xfer_data);
+ purple_xfer_set_protocol_data(xfer, NULL); static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer); if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
@@ -574,7 +575,7 @@
struct yahoo_packet *pkt;
+ yd = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc);
if(!xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
@@ -583,7 +584,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -594,7 +595,7 @@
yahoo_packet_hash(pkt, "sssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
@@ -603,7 +604,7 @@
yahoo_xfer_data_free(xfer_data);
+ purple_xfer_set_protocol_data(xfer, NULL); /* Send HTTP OK after receiving file */
@@ -611,9 +612,10 @@
+ int fd = purple_xfer_get_fd(xfer); - tx = g_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n");
- written = write(xfer->fd, tx, strlen(tx));
+ tx = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n"; + written = write(fd, tx, strlen(tx)); if (written < 0 && errno == EAGAIN)
@@ -621,9 +623,8 @@
purple_debug_info("yahoo", "p2p filetransfer: Unable to write HTTP OK");
+ purple_xfer_set_fd(xfer, -1); static void yahoo_xfer_end(PurpleXfer *xfer_old)
@@ -633,13 +634,13 @@
- xfer_data = xfer_old->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer_old); if(xfer_data && xfer_data->version == 15
&& purple_xfer_get_type(xfer_old) == PURPLE_XFER_RECEIVE
&& xfer_data->filename_list) {
/* Send HTTP OK in case of p2p transfer, when we act as server */
- if((xfer_data->xfer_url != NULL) && (xfer_old->fd >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE))
+ if((xfer_data->xfer_url != NULL) && (purple_xfer_get_fd(xfer_old) >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE)) yahoo_p2p_ft_server_send_OK(xfer_old);
/* removing top of filename & size list completely */
@@ -656,13 +657,13 @@
if(xfer_data->filename_list)
filename = xfer_data->filename_list->data;
- filesize = atol( xfer_data->size_list->data );
+ filesize = g_ascii_strtoll( xfer_data->size_list->data, NULL, 10 );
+ yd = purple_connection_get_protocol_data(gc); /* setting up xfer_data for next file's tranfer */
@@ -689,10 +690,10 @@
xfer_data->firstoflist = FALSE;
/* Dereference xfer_data from old xfer */
+ purple_xfer_set_protocol_data(xfer_old, NULL); /* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, xfer_old->who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, purple_xfer_get_remote_user(xfer_old)); @@ -702,7 +703,7 @@
purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data); /* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
@@ -726,8 +727,7 @@
yahoo_xfer_data_free(xfer_data);
+ purple_xfer_set_protocol_data(xfer_old, NULL); void yahoo_process_p2pfilexfer(PurpleConnection *gc, struct yahoo_packet *pkt)
@@ -803,10 +803,10 @@
struct yahoo_xfer_data *xfer_data;
- unsigned long filesize = 0L;
+ goffset filesize = G_GOFFSET_CONSTANT(0);
+ yd = purple_connection_get_protocol_data(gc); for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -831,7 +831,7 @@
- filesize = atol(pair->value);
+ filesize = g_ascii_strtoll(pair->value, NULL, 10); @@ -880,13 +880,13 @@
xfer_data->host, xfer_data->port, xfer_data->path, url);
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, from); - xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data); /* Set the info about the incoming file. */
@@ -936,14 +936,14 @@
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who); g_return_val_if_reached(NULL);
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data); /* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init);
@@ -993,11 +993,11 @@
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) account = purple_connection_get_account(gc);
+ yd = purple_connection_get_protocol_data(gc); @@ -1057,7 +1057,7 @@
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xd->xfer_peer_idstring,
@@ -1077,7 +1077,7 @@
void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
struct yahoo_xfer_data *xfer_data;
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); PurpleXfer *xfer = yahoo_new_xfer(gc, who);
g_return_if_fail(xfer != NULL);
@@ -1086,7 +1086,7 @@
if( !g_hash_table_lookup(yd->peers, who) )
yahoo_send_p2p_pkt(gc, who, 0);
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer); xfer_data->status_15 = STARTED;
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
@@ -1108,26 +1108,22 @@
struct yahoo_xfer_data *xd;
+ xd = purple_xfer_get_protocol_data(xfer); account = purple_connection_get_account(xd->gc);
- buf=g_strnfill(1000, 0);
- while((did = read(source, buf, 998)) > 0)
+ while((did = read(source, buf, sizeof(buf))) > 0) + /* TODO: Convert to circ buffer, this all is pretty horrible */ + xd->txbuf = g_realloc(xd->txbuf, xd->txbuflen + did); + g_memmove(xd->txbuf + xd->txbuflen, buf, did);
- xd->txbuf = g_strconcat(t,buf,NULL);
if (did < 0 && errno == EAGAIN)
@@ -1167,7 +1163,7 @@
+ xd = purple_xfer_get_protocol_data(xfer); remaining = xd->txbuflen - xd->txbuf_written;
written = write(source, xd->txbuf + xd->txbuf_written, remaining);
@@ -1200,13 +1196,13 @@
else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == HEAD_REPLY_RECEIVED)
xd->status_15 = TRANSFER_PHASE;
+ purple_xfer_set_fd(xfer, source); purple_xfer_start(xfer, source, NULL, 0);
else if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && (xd->status_15 == ACCEPTED || xd->status_15 == P2P_GET_REQUESTED) )
xd->status_15 = TRANSFER_PHASE;
+ purple_xfer_set_fd(xfer, source); purple_input_remove(xd->input_event);
@@ -1219,9 +1215,9 @@
purple_input_remove(xd->input_event);
+ purple_xfer_set_fd(xfer, -1); /* start local server, listen for connections */
- purple_network_listen(xd->yahoo_local_p2p_ft_server_port, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer);
+ purple_network_listen(xd->yahoo_local_p2p_ft_server_port, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer); @@ -1239,13 +1235,13 @@
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) account = purple_connection_get_account(gc);
if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
+ purple_xfer_get_remote_user(xfer), _("Unable to connect.")); purple_xfer_cancel_remote(xfer);
@@ -1253,7 +1249,8 @@
- YahooData *yd = gc->proto_data;
+ YahooData *yd = purple_connection_get_protocol_data(gc); /* cookies = yahoo_get_cookies(gc);
* This doesn't seem to be working. The function is returning NULL, which yahoo servers don't like
@@ -1266,30 +1263,30 @@
if(xd->info_val_249 == 2)
/* sending file via p2p, we are connected as client */
- xd->txbuf = g_strdup_printf("POST /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("POST /%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: %ld\r\n"
+ "Content-Length: %" G_GOFFSET_FORMAT "\r\n" "Cache-Control: no-cache\r\n\r\n",
- (long int)xfer->size); /* to do, add Referer */
+ purple_xfer_get_size(xfer)); /* to do, add Referer */ /* sending file via relaying */
- xd->txbuf = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: %ld\r\n"
+ "Content-Length: %" G_GOFFSET_FORMAT "\r\n" "Cache-Control: no-cache\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
+ purple_xfer_get_remote_user(xfer),
+ purple_xfer_get_size(xfer)); /* to do, add Referer */ else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
@@ -1297,7 +1294,7 @@
if(xd->info_val_249 == 1)
/* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("HEAD /%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
@@ -1308,7 +1305,7 @@
/* receiving file via relaying */
- xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
@@ -1317,7 +1314,7 @@
"Cache-Control: no-cache\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
+ purple_xfer_get_remote_user(xfer), @@ -1327,7 +1324,7 @@
if(xd->info_val_249 == 1)
/* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("GET /%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Connection: Keep-Alive\r\n\r\n",
@@ -1336,14 +1333,14 @@
/* receiving file via relaying */
- xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
+ initial_buffer = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n" "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
"Connection: Keep-Alive\r\n\r\n",
purple_url_encode(xd->xfer_idstring_for_relay),
purple_normalize(account, purple_account_get_username(account)),
+ purple_xfer_get_remote_user(xfer), @@ -1354,7 +1351,8 @@
- xd->txbuflen = strlen(xd->txbuf);
+ xd->txbuf = (guchar*) initial_buffer; + xd->txbuflen = strlen(initial_buffer); @@ -1373,14 +1371,14 @@
struct yahoo_xfer_data *xd;
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) { purple_xfer_cancel_remote(xfer);
purple_input_remove(xd->input_event);
xd->status_15 = TRANSFER_PHASE;
+ purple_xfer_set_fd(xfer, source); purple_xfer_start(xfer, source, NULL, 0);
@@ -1396,7 +1394,7 @@
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) { purple_xfer_cancel_remote(xfer);
@@ -1431,14 +1429,15 @@
time_str[strlen(time_str) - 1] = '\0';
- xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
+ gchar *initial_buffer = g_strdup_printf("HTTP/1.0 200 OK\r\n" "Last-modified: %s GMT\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n\r\n",
- time_str, time_str, xfer->size);
- xd->txbuflen = strlen(xd->txbuf);
+ "Content-length: %" G_GOFFSET_FORMAT "\r\n\r\n", + time_str, time_str, purple_xfer_get_size(xfer)); + xd->txbuf = (guchar *)initial_buffer; + xd->txbuflen = strlen(initial_buffer); @@ -1458,7 +1457,7 @@
struct yahoo_xfer_data *xd;
- if (!(xd = xfer->data)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) { purple_xfer_cancel_remote(xfer);
@@ -1480,8 +1479,8 @@
close(xd->yahoo_local_p2p_ft_server_fd);
/* Add an Input Read event to the file descriptor */
- if(xfer->type == PURPLE_XFER_RECEIVE)
+ purple_xfer_set_fd(xfer, acceptfd); + if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_POST_cb, data);
xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_HEAD_GET_cb, data);
@@ -1500,14 +1499,14 @@
char *filename_without_spaces = NULL;
- if (!(xd = xfer->data) || (listenfd == -1)) {
+ if (!(xd = purple_xfer_get_protocol_data(xfer)) || (listenfd == -1)) { purple_debug_warning("yahoo","p2p: error starting server for p2p file transfer\n");
purple_xfer_cancel_remote(xfer);
- if( (xfer->type == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) ) {
- yd = xd->gc->proto_data;
+ if( (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) ) { + yd = purple_connection_get_protocol_data(xd->gc); account = purple_connection_get_account(xd->gc);
local_ip = purple_network_get_my_ip(listenfd);
xd->yahoo_local_p2p_ft_server_port = purple_network_get_port_from_fd(listenfd);
@@ -1515,18 +1514,18 @@
filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
filename_without_spaces = g_strdup(filename);
purple_util_chrreplace(filename_without_spaces, ' ', '+');
- xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", xfer->who, (int)time(NULL), filename_without_spaces, xfer->who);
+ xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", purple_xfer_get_remote_user(xfer), (int)time(NULL), filename_without_spaces, purple_xfer_get_remote_user(xfer)); url_to_send = g_strdup_printf("http://%s:%d%s", local_ip, xd->yahoo_local_p2p_ft_server_port, xd->xfer_url);
- if(xfer->type == PURPLE_XFER_RECEIVE) {
+ if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { xd->info_val_249 = 2; /* 249=2: we are p2p server, and receiving file */
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xd->xfer_peer_idstring,
+ 27, purple_xfer_get_filename(xfer), @@ -1535,7 +1534,7 @@
pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xd->xfer_peer_idstring,
@@ -1564,15 +1563,15 @@
struct yahoo_p2p_data *p2p_data;
- if (!(xd = xfer->data))
+ if (!(xd = purple_xfer_get_protocol_data(xfer))) account = purple_connection_get_account(gc);
+ yd = purple_connection_get_protocol_data(gc); - p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+ p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer)); if( p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER )
- if(purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer))
+ if(purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer)) pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
@@ -1580,7 +1579,7 @@
yahoo_packet_hash(pkt, "ssssi",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xd->xfer_peer_idstring,
249, 2); /* 249=2: we are p2p client */
@@ -1603,13 +1602,13 @@
char *xfer_peer_idstring = NULL;
- unsigned long filesize = 0L;
+ goffset filesize = G_GOFFSET_CONSTANT(0); GSList *filename_list = NULL;
GSList *size_list = NULL;
+ yd = purple_connection_get_protocol_data(gc); for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1683,13 +1682,13 @@
account = purple_connection_get_account(gc);
- purple_dnsquery_a_account(account, YAHOOJP_XFER_RELAY_HOST,
+ purple_dnsquery_a(account, YAHOOJP_XFER_RELAY_HOST, yahoo_xfer_dns_connected_15, xfer);
- purple_dnsquery_a_account(account, YAHOO_XFER_RELAY_HOST,
+ purple_dnsquery_a(account, YAHOO_XFER_RELAY_HOST, yahoo_xfer_dns_connected_15, xfer);
@@ -1720,7 +1719,7 @@
filename_list = g_slist_reverse(filename_list);
size_list = g_slist_reverse(size_list);
filename = filename_list->data;
- filesize = atol(size_list->data);
+ filesize = g_ascii_strtoll(size_list->data, NULL, 10); xfer_data = g_new0(struct yahoo_xfer_data, 1);
@@ -1732,22 +1731,20 @@
xfer_data->size_list = size_list;
/* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
+ xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, from);
/* Set the info about the incoming file. */
utf8_filename = yahoo_string_decode(gc, filename, TRUE);
purple_xfer_set_filename(xfer, utf8_filename);
purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
+ purple_xfer_set_protocol_data(xfer, xfer_data); /* Setup our I/O op functions */
purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
@@ -1765,7 +1762,7 @@
- message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), xfer->who, nooffiles);
+ message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), purple_xfer_get_remote_user(xfer), nooffiles); purple_xfer_conversation_write(xfer, message, FALSE);
@@ -1790,7 +1787,7 @@
struct yahoo_packet *pkt_to_send;
struct yahoo_p2p_data *p2p_data;
+ yd = purple_connection_get_protocol_data(gc); for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1837,7 +1834,7 @@
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer); xfer_data->info_val_249 = val_249;
xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
@@ -1854,9 +1851,9 @@
YAHOO_STATUS_AVAILABLE, yd->session_id);
yahoo_packet_hash(pkt_to_send, "ssssis",
1, purple_normalize(account, purple_account_get_username(account)),
+ 5, purple_xfer_get_remote_user(xfer), 265, xfer_data->xfer_peer_idstring,
+ 27, purple_xfer_get_filename(xfer), 249, xfer_data->info_val_249,
251, xfer_data->xfer_idstring_for_relay);
@@ -1870,12 +1867,12 @@
- p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
+ p2p_data = g_hash_table_lookup(yd->peers, purple_xfer_get_remote_user(xfer)); if( !( p2p_data && (p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) ) ) {
purple_xfer_cancel_remote(xfer);
- if(!purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer)) {
+ if(!purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, yahoo_p2p_ft_server_listen_cb, xfer)) { purple_xfer_cancel_remote(xfer);
@@ -1896,7 +1893,7 @@
+ yd = purple_connection_get_protocol_data(gc); for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -1934,7 +1931,7 @@
- xfer_data = xfer->data;
+ xfer_data = purple_xfer_get_protocol_data(xfer); purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL);
--- a/libpurple/protocols/zephyr/zephyr.c Mon Aug 22 22:46:08 2011 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c Fri Dec 23 08:21:58 2011 +0000
@@ -347,7 +347,7 @@
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if (g_utf8_validate(string, -1, NULL)) {
@@ -762,7 +762,7 @@
static void handle_message(PurpleConnection *gc,ZNotice_t notice)
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc); if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) {
/* well, we'll be updating in 20 seconds anyway, might as well ignore this. */
@@ -777,9 +777,9 @@
if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE)
- if ((b = purple_find_buddy(gc->account, user)) == NULL) {
+ if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) { char* stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(gc->account,stripped_user);
+ b = purple_find_buddy(purple_connection_get_account(gc),stripped_user); @@ -815,9 +815,9 @@
purple_notify_user_info_destroy(user_info);
- purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "available", NULL); - purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "offline", NULL); @@ -872,7 +872,7 @@
zephyr_triple *zt1, *zt2;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); zt1 = new_triple(zephyr,notice.z_class, notice.z_class_inst, notice.z_recipient);
zt2 = find_sub_by_triple(zephyr,zt1);
@@ -900,7 +900,7 @@
gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
- zt2->name, gc->account);
+ zt2->name, purple_connection_get_account(gc)); gcc = purple_conversation_get_chat_data(gconv1);
#define INET_ADDRSTRLEN 16
@@ -1109,7 +1109,7 @@
static gint check_notify_tzc(gpointer data)
PurpleConnection *gc = (PurpleConnection *)data;
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc); parse_tree *newparsetree = read_from_tzc(zephyr);
if (newparsetree != NULL) {
@@ -1156,9 +1156,9 @@
user = tree_child(find_node(newparsetree,"user"),2)->contents;
- if ((b = purple_find_buddy(gc->account, user)) == NULL) {
+ if ((b = purple_find_buddy(purple_connection_get_account(gc), user)) == NULL) { gchar *stripped_user = zephyr_strip_local_realm(zephyr,user);
- b = purple_find_buddy(gc->account, stripped_user);
+ b = purple_find_buddy(purple_connection_get_account(gc), stripped_user); locations = find_node(newparsetree,"locations");
@@ -1200,9 +1200,9 @@
purple_notify_user_info_destroy(user_info);
- purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "available", NULL); - purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL);
+ purple_prpl_got_user_status(purple_connection_get_account(gc), b ? bname : user, "offline", NULL); else if (!g_ascii_strncasecmp(spewtype,"subscribed",10)) {
@@ -1265,7 +1265,7 @@
PurpleConnection *gc = data;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc);
@@ -1296,7 +1296,7 @@
PurpleConnection *gc = (PurpleConnection *)data;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc);
if (use_zeph02(zephyr)) {
@@ -1521,11 +1521,11 @@
while (fgets(buff, BUFSIZ, fd)) {
- if (!(b = purple_find_buddy(gc->account, buff))) {
+ if (!(b = purple_find_buddy(purple_connection_get_account(gc), buff))) { char *stripped_user = zephyr_strip_local_realm(zephyr,buff);
purple_debug_info("zephyr","stripped_user %s\n",stripped_user);
- if (!(b = purple_find_buddy(gc->account,stripped_user))){
- b = purple_buddy_new(gc->account, stripped_user, NULL);
+ if (!(b = purple_find_buddy(purple_connection_get_account(gc),stripped_user))){ + b = purple_buddy_new(purple_connection_get_account(gc), stripped_user, NULL); purple_blist_add_buddy(b, NULL, g, NULL);
@@ -1564,28 +1564,29 @@
gc = purple_account_get_connection(account);
- read_anyone = purple_account_get_bool(gc->account,"read_anyone",TRUE);
- read_zsubs = purple_account_get_bool(gc->account,"read_zsubs",TRUE);
- exposure = (gchar *)purple_account_get_string(gc->account, "exposure_level", EXPOSE_REALMVIS);
+ read_anyone = purple_account_get_bool(purple_connection_get_account(gc),"read_anyone",TRUE); + read_zsubs = purple_account_get_bool(purple_connection_get_account(gc),"read_zsubs",TRUE); + exposure = (gchar *)purple_account_get_string(purple_connection_get_account(gc), "exposure_level", EXPOSE_REALMVIS); username = purple_account_get_username(account);
- gc->flags |= PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
- gc->proto_data = zephyr=g_new0(zephyr_account,1);
+ purple_connection_set_flags(gc, PURPLE_CONNECTION_AUTO_RESP | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC); + zephyr = g_new0(zephyr_account, 1); + purple_connection_set_protocol_data(gc, zephyr); zephyr->account = account;
/* Make sure that the exposure (visibility) is set to a sane value */
zephyr->exposure=g_strdup(normalize_zephyr_exposure(exposure));
- if (purple_account_get_bool(gc->account,"use_tzc",0)) {
+ if (purple_account_get_bool(purple_connection_get_account(gc),"use_tzc",0)) { zephyr->connection_type = PURPLE_ZEPHYR_TZC;
zephyr->connection_type = PURPLE_ZEPHYR_KRB4;
- zephyr->encoding = (char *)purple_account_get_string(gc->account, "encoding", ZEPHYR_FALLBACK_CHARSET);
+ zephyr->encoding = (char *)purple_account_get_string(purple_connection_get_account(gc), "encoding", ZEPHYR_FALLBACK_CHARSET); purple_connection_update_progress(gc, _("Connecting"), 0, 8);
/* XXX z_call_s should actually try to report the com_err determined error */
@@ -1606,7 +1607,7 @@
gboolean found_ps = FALSE;
- gchar ** tzc_cmd_array = g_strsplit(purple_account_get_string(gc->account,"tzc_command","/usr/bin/tzc -e %s")," ",0);
+ gchar ** tzc_cmd_array = g_strsplit(purple_account_get_string(purple_connection_get_account(gc),"tzc_command","/usr/bin/tzc -e %s")," ",0); @@ -1778,7 +1779,7 @@
if ((realm = strchr(username,'@')))
zephyr->realm = g_strdup_printf("%s",realm+1);
- realm = (gchar *)purple_account_get_string(gc->account,"realm","");
+ realm = (gchar *)purple_account_get_string(purple_connection_get_account(gc),"realm",""); @@ -1815,7 +1816,7 @@
z_call_s(ZOpenPort(&(zephyr->port)), "Couldn't open port");
z_call_s(ZSetLocation((char *)zephyr->exposure), "Couldn't set location");
- realm = (gchar *)purple_account_get_string(gc->account,"realm","");
+ realm = (gchar *)purple_account_get_string(purple_connection_get_account(gc),"realm",""); @@ -1841,7 +1842,7 @@
if (zephyr_subscribe_to(zephyr,"MESSAGE","PERSONAL",zephyr->username,NULL) != ZERR_NONE) {
/* XXX don't translate this yet. It could be written better */
/* XXX error messages could be handled with more detail */
- purple_notify_error(account->gc, NULL,
+ purple_notify_error(purple_account_get_connection(account), NULL, "Unable to subscribe to messages", "Unable to subscribe to initial messages");
@@ -1961,7 +1962,7 @@
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); pid_t tzc_pid = zephyr->tzc_pid;
l = zephyr->pending_zloc_names;
@@ -1971,10 +1972,10 @@
g_list_free(zephyr->pending_zloc_names);
- if (purple_account_get_bool(gc->account, "write_anyone", FALSE))
+ if (purple_account_get_bool(purple_connection_get_account(gc), "write_anyone", FALSE)) - if (purple_account_get_bool(gc->account, "write_zsubs", FALSE))
+ if (purple_account_get_bool(purple_connection_get_account(gc), "write_zsubs", FALSE)) @@ -2036,7 +2037,7 @@
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); zt = find_sub_by_id(zephyr,id);
@@ -2046,7 +2047,7 @@
sig = zephyr_get_signature();
gconv1 = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name,
+ purple_connection_get_account(gc)); gcc = purple_conversation_get_chat_data(gconv1);
if (!(inst = (char *)purple_conv_chat_get_topic(gcc)))
@@ -2065,7 +2066,7 @@
static int zephyr_send_im(PurpleConnection * gc, const char *who, const char *im, PurpleMessageFlags flags)
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if (flags & PURPLE_MESSAGE_AUTO_RESP)
sig = "Automated reply:";
@@ -2234,7 +2235,7 @@
- tmp = local_zephyr_normalize(gc->proto_data, who);
+ tmp = local_zephyr_normalize(purple_connection_get_protocol_data(gc), who); if (strlen(tmp) >= sizeof(buf)) {
@@ -2250,7 +2251,7 @@
static void zephyr_zloc(PurpleConnection *gc, const char *who)
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); gchar* normalized_who = local_zephyr_normalize(zephyr,who);
if (use_zeph02(zephyr)) {
@@ -2277,7 +2278,8 @@
static void zephyr_set_status(PurpleAccount *account, PurpleStatus *status) {
- zephyr_account *zephyr = purple_account_get_connection(account)->proto_data;
+ PurpleConnection *gc = purple_account_get_connection(account); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status));
@@ -2411,7 +2413,7 @@
- zephyr_account *zephyr=gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); classname = g_hash_table_lookup(data, "class");
instname = g_hash_table_lookup(data, "instance");
recip = g_hash_table_lookup(data, "recipient");
@@ -2474,7 +2476,7 @@
static void zephyr_chat_leave(PurpleConnection * gc, int id)
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); zt = find_sub_by_id(zephyr,id);
@@ -2524,7 +2526,7 @@
static unsigned int zephyr_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) {
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); @@ -2566,7 +2568,7 @@
PurpleConversation *gconv;
- zephyr_account* zephyr = gc->proto_data;
+ zephyr_account* zephyr = purple_connection_get_protocol_data(gc); char *sender = (char *)zephyr->username;
zt = find_sub_by_id(zephyr,id);
@@ -2574,7 +2576,7 @@
gconv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, zt->name,
+ purple_connection_get_account(gc)); gcc = purple_conversation_get_chat_data(gconv);
topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic);
@@ -2589,7 +2591,8 @@
const char *cmd, char **args, char **error, void *data)
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc);; if (!g_ascii_strcasecmp(args[0],"*"))
return PURPLE_CMD_RET_FAILED; /* "*" is not a valid argument */
@@ -2607,7 +2610,7 @@
static PurpleCmdRet zephyr_purple_cmd_zlocate(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
- zephyr_zloc(purple_conversation_get_gc(conv),args[0]);
+ zephyr_zloc(purple_conversation_get_connection(conv),args[0]); return PURPLE_CMD_RET_OK;
@@ -2619,9 +2622,8 @@
* one word isn't ideal either. */
PurpleConvChat *gcc = purple_conversation_get_chat_data(conv);
const char* instance = args[0];
- zephyr_chat_set_topic(purple_conversation_get_gc(conv),id,instance);
+ zephyr_chat_set_topic(purple_conversation_get_connection(conv),purple_conv_chat_get_id(gcc),instance); return PURPLE_CMD_RET_OK;
@@ -2633,7 +2635,7 @@
g_hash_table_insert(triple,"class",args[0]);
g_hash_table_insert(triple,"instance",args[1]);
g_hash_table_insert(triple,"recipient",args[2]);
- zephyr_join_chat(purple_conversation_get_gc(conv),triple);
+ zephyr_join_chat(purple_conversation_get_connection(conv),triple); return PURPLE_CMD_RET_OK;
@@ -2641,7 +2643,8 @@
const char *cmd, char **args, char **error, void *data)
/* args = instance, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if ( zephyr_send_message(zephyr,"message",args[0],"",args[1],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
@@ -2652,7 +2655,8 @@
const char *cmd, char **args, char **error, void *data)
/* args = class, instance, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if ( zephyr_send_message(zephyr,args[0],args[1],"",args[2],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
@@ -2663,7 +2667,8 @@
const char *cmd, char **args, char **error, void *data)
/* args = class, instance, recipient, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if ( zephyr_send_message(zephyr,args[0],args[1],args[2],args[3],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
@@ -2674,7 +2679,8 @@
const char *cmd, char **args, char **error, void *data)
/* args = instance, recipient, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if ( zephyr_send_message(zephyr,"message",args[0],args[1],args[2],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
@@ -2685,7 +2691,8 @@
const char *cmd, char **args, char **error, void *data)
/* args = class, message */
- zephyr_account *zephyr = purple_conversation_get_gc(conv)->proto_data;
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); if ( zephyr_send_message(zephyr,args[0],"PERSONAL","",args[1],zephyr_get_signature(),""))
return PURPLE_CMD_RET_OK;
@@ -2766,7 +2773,7 @@
/* Resubscribe to the in-memory list of subscriptions and also
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); GSList *s = zephyr->subscrips;
@@ -2791,7 +2798,7 @@
static void zephyr_action_get_subs_from_server(PurplePluginAction *action)
PurpleConnection *gc = (PurpleConnection *) action->context;
- zephyr_account *zephyr = gc->proto_data;
+ zephyr_account *zephyr = purple_connection_get_protocol_data(gc); int retval, nsubs, one,i;
@@ -2845,6 +2852,7 @@
static PurplePlugin *my_protocol = NULL;
static PurplePluginProtocolInfo prpl_info = {
+ sizeof(PurplePluginProtocolInfo), /* struct_size */ OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD,
NULL, /* ??? user_splits */
NULL, /* ??? protocol_options */
@@ -2885,7 +2893,6 @@
NULL, /* keepalive -- Not necessary*/
NULL, /* register_user -- Not supported*/
NULL, /* XXX get_cb_info */
- NULL, /* get_cb_away */
@@ -2911,15 +2918,12 @@
- sizeof(PurplePluginProtocolInfo), /* struct_size */
NULL, /* get_account_text_table */
NULL, /* initate_media */
NULL, /* get_media_caps */
NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
+ NULL /* get_public_alias */ static PurplePluginInfo info = {
--- a/pidgin/gtkblist.c Mon Aug 22 22:46:08 2011 +0000
+++ b/pidgin/gtkblist.c Fri Dec 23 08:21:58 2011 +0000
@@ -124,6 +124,11 @@
#define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \
((PidginBuddyListPrivate *)((list)->priv))
+#if !GTK_CHECK_VERSION(2,18,0) +#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x) +#define gtk_widget_has_focus(x) GTK_WIDGET_HAS_FOCUS(x) static guint accounts_merge_id;
static GtkActionGroup *accounts_action_group = NULL;
@@ -346,13 +351,13 @@
static void gtk_blist_menu_autojoin_cb(GtkWidget *w, PurpleChat *chat)
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin",
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-autojoin", gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
static void gtk_blist_menu_persistent_cb(GtkWidget *w, PurpleChat *chat)
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent",
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-persistent", gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
@@ -462,9 +467,9 @@
/* First, we find the contact to merge the rest of the buddies into.
- * This will be the contact with the most buddies in it; ties are broken
- * by which contact is higher in the list
+ * This will be the contact with the most buddies in it; ties are broken + * by which contact is higher in the list for (tmp = merges; tmp; tmp = tmp->next) {
PurpleBlistNode *node = tmp->data;
@@ -919,7 +924,7 @@
gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), GTK_RESPONSE_OK, sensitive);
gc = purple_account_get_connection(data->rq_data.account);
- prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
+ prpl_info = (gc != NULL) ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; sensitive = (prpl_info != NULL && prpl_info->roomlist_get_list != NULL);
gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window), 1, sensitive);
@@ -943,7 +948,7 @@
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); return (prpl_info->chat_info != NULL);
@@ -985,23 +990,20 @@
gtkblist = PIDGIN_BLIST(purple_get_blist());
blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
- /* TODO: set no separator in gtk+ 3... */
data->window = gtk_dialog_new_with_buttons(title,
- blist_window, 0, NULL);
+ blist_window, GTK_DIALOG_NO_SEPARATOR, gtk_window_set_transient_for(GTK_WINDOW(data->window), blist_window);
gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK);
gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE);
gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
- gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
- gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
+ gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER); + gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE); gtk_window_set_role(GTK_WINDOW(data->window), window_role);
hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
- gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
@@ -1036,6 +1038,7 @@
rebuild_chat_entries(PidginChatData *data, const char *default_chat_name)
+ PurplePluginProtocolInfo *prpl_info; GList *list = NULL, *tmp;
GHashTable *defaults = NULL;
struct proto_chat_entry *pce;
@@ -1044,17 +1047,18 @@
g_return_if_fail(data->rq_data.account != NULL);
gc = purple_account_get_connection(data->rq_data.account);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); gtk_container_foreach(GTK_CONTAINER(data->rq_data.vbox), (GtkCallback)gtk_widget_destroy, NULL);
g_list_free(data->entries);
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL)
- list = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc);
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
- defaults = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, default_chat_name);
+ if (prpl_info->chat_info != NULL) + list = prpl_info->chat_info(gc); + if (prpl_info->chat_info_defaults != NULL) + defaults = prpl_info->chat_info_defaults(gc, default_chat_name); for (tmp = list; tmp; tmp = tmp->next)
@@ -1064,7 +1068,7 @@
adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
@@ -1417,7 +1421,7 @@
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if(!prpl_info || !prpl_info->blist_node_menu)
@@ -1525,7 +1529,7 @@
if (prpl_info && prpl_info->send_file) {
if (!prpl_info->can_receive_file ||
- prpl_info->can_receive_file(buddy->account->gc, buddy->name))
+ prpl_info->can_receive_file(purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy))) pidgin_new_item_from_stock(menu, _("_Send File..."),
PIDGIN_STOCK_TOOLBAR_SEND_FILE,
@@ -1553,14 +1557,14 @@
NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
- pidgin_append_blist_node_proto_menu(menu, buddy->account->gc, node);
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(purple_buddy_get_account(buddy)), node); pidgin_append_blist_node_extended_menu(menu, node);
if (!contact_expanded && contact != NULL)
- pidgin_append_blist_node_move_to_menu(menu, (PurpleBlistNode *)contact);
+ pidgin_append_blist_node_move_to_menu(menu, PURPLE_BLIST_NODE(contact)); if (node->parent && node->parent->child->next &&
- !sub && !contact_expanded) {
+ !sub && !contact_expanded) { pidgin_append_blist_node_privacy_menu(menu, node);
pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
@@ -1606,14 +1610,14 @@
- pidgin_retrieve_user_info(buddy->account->gc, buddy->name);
+ pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy));
gtk_blist_menu_alias_cb(tv, node);
path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
@@ -1635,7 +1639,7 @@
gtk_tree_path_free(path);
path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
@@ -1759,7 +1763,7 @@
pidgin_new_item_from_stock(menu, _("View _Log"), NULL,
G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL);
- pidgin_append_blist_node_proto_menu(menu, c->account->gc, node);
+ pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(purple_chat_get_account(c)), node); pidgin_append_blist_node_extended_menu(menu, node);
@@ -1809,7 +1813,7 @@
create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b)
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); gboolean show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
@@ -1844,13 +1848,13 @@
- if(!buddy->account->gc)
+ if(!purple_account_get_connection(purple_buddy_get_account(buddy))) if(!show_offline && !PURPLE_BUDDY_IS_ONLINE(buddy))
- menuitem = gtk_image_menu_item_new_with_label(buddy->name);
- buf = pidgin_create_prpl_icon(buddy->account,PIDGIN_PRPL_ICON_SMALL);
+ menuitem = gtk_image_menu_item_new_with_label(purple_buddy_get_name(buddy)); + buf = pidgin_create_prpl_icon(purple_buddy_get_account(buddy), PIDGIN_PRPL_ICON_SMALL); image = gtk_image_new_from_pixbuf(buf);
g_object_unref(G_OBJECT(buf));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
@@ -1877,12 +1881,10 @@
- struct _pidgin_blist_node *gtknode;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); gboolean handled = FALSE;
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
/* Create a menu based on the thing we right-clicked on */
if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
PurpleGroup *g = (PurpleGroup *)node;
@@ -1944,7 +1946,7 @@
gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node); /* Right click draws a context menu */
if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) {
@@ -1968,12 +1970,12 @@
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b))); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
if (prpl && prpl_info->get_info)
- pidgin_retrieve_user_info(b->account->gc, b->name);
+ pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(b)), purple_buddy_get_name(b)); @@ -2123,7 +2125,7 @@
for (l = list; l != NULL; l = l->next)
purple_blist_request_add_buddy(account, l->data,
- (group ? group->name : NULL),
+ (group ? purple_group_get_name(group) : NULL), @@ -2250,9 +2252,9 @@
- GdkAtom target = gtk_selection_data_get_target(data);
- if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) {
+ if (data->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref);
@@ -2268,7 +2270,9 @@
gtk_tree_path_free(sourcerow);
- } else if (target == gdk_atom_intern("application/x-im-contact", FALSE)) {
+ else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE)) GtkTreeRowReference *ref;
@@ -2302,7 +2306,7 @@
buddy = (PurpleBuddy *)node;
- gc = purple_account_get_connection(buddy->account);
+ gc = purple_account_get_connection(purple_buddy_get_account(buddy)); @@ -2311,7 +2315,7 @@
- PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account,
+ PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->list_icon(purple_buddy_get_account(buddy), str = g_string_new(NULL);
@@ -2321,13 +2325,13 @@
- if (buddy->alias != NULL)
+ purple_buddy_get_name(buddy)); + if (purple_buddy_get_local_buddy_alias(buddy) != NULL) g_string_append_printf(str,
+ purple_buddy_get_local_buddy_alias(buddy)); g_string_append(str, "\r\n");
@@ -2346,19 +2350,16 @@
static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
GtkSelectionData *sd, guint info, guint t)
- GdkAtom target = gtk_selection_data_get_target(sd);
- const guchar *data = gtk_selection_data_get_data(sd);
if (gtkblist->drag_timeout) {
g_source_remove(gtkblist->drag_timeout);
gtkblist->drag_timeout = 0;
- if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && data) {
+ if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && sd->data) { PurpleBlistNode *n = NULL;
GtkTreePath *path = NULL;
GtkTreeViewDropPosition position;
- memcpy(&n, data, sizeof(n));
+ memcpy(&n, sd->data, sizeof(n)); if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
/* if we're here, I think it means the drop is ok */
@@ -2369,7 +2370,7 @@
gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel),
&iter, NODE_COLUMN, &node, -1);
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node); if (PURPLE_BLIST_NODE_IS_CONTACT(n)) {
PurpleContact *c = (PurpleContact*)n;
@@ -2494,10 +2495,12 @@
gtk_tree_path_free(path);
- gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
- } else if (target == gdk_atom_intern("application/x-im-contact",
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); + else if (sd->target == gdk_atom_intern("application/x-im-contact", PurpleGroup *group = NULL;
GtkTreePath *path = NULL;
GtkTreeViewDropPosition position;
@@ -2532,7 +2535,7 @@
- if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
+ if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, &protocol, &username, &alias))
@@ -2544,7 +2547,7 @@
purple_blist_request_add_buddy(account, username,
- (group ? group->name : NULL),
+ (group ? purple_group_get_name(group) : NULL), @@ -2556,10 +2559,9 @@
gtk_tree_path_free(path);
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
- else if (target == gdk_atom_intern("text/x-vcard", FALSE) && data)
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); + else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data) PurpleGroup *group = NULL;
@@ -2592,11 +2594,10 @@
- result = parse_vcard((const gchar *) data, group);
- gtk_drag_finish(dc, result,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
- } else if (target == gdk_atom_intern("text/uri-list", FALSE) && data) {
+ result = parse_vcard((const gchar *)sd->data, group); + gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t); + } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) { GtkTreePath *path = NULL;
GtkTreeViewDropPosition position;
@@ -2613,9 +2614,8 @@
if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) {
PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
- pidgin_dnd_file_manage(sd, b->account, b->name);
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+ pidgin_dnd_file_manage(sd, purple_buddy_get_account(b), purple_buddy_get_name(b)); + gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); gtk_drag_finish(dc, FALSE, FALSE, t);
@@ -2687,8 +2687,8 @@
account = purple_buddy_get_account(buddy);
- if(account && account->gc) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
+ if(account && purple_account_get_connection(account)) { + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account))); @@ -2701,7 +2701,7 @@
* a contact then this is a group or some other type of node and we
* want to use that directly. */
- custom_img = purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
+ custom_img = purple_buddy_icons_node_find_custom_icon(PURPLE_BLIST_NODE(contact)); custom_img = purple_buddy_icons_node_find_custom_icon(node);
@@ -2714,7 +2714,7 @@
/* Not sure I like this...*/
- if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name)))
+ if (!(icon = purple_buddy_icons_find(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)))) data = purple_buddy_icon_get_data(icon, &len);
@@ -2884,9 +2884,9 @@
char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL;
if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- account = ((PurpleBuddy*)(node))->account;
+ account = purple_buddy_get_account((PurpleBuddy*)(node)); } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
- account = ((PurpleChat*)(node))->account;
+ account = purple_chat_get_account((PurpleChat*)(node)); td->padding = TOOLTIP_BORDER;
@@ -2940,6 +2940,7 @@
pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
int current_height, max_width;
@@ -2951,7 +2952,7 @@
if(gtkblist->tooltipdata == NULL)
- style = gtk_widget_get_style(gtkblist->tipwindow);
+ style = gtkblist->tipwindow->style; @@ -2973,86 +2974,89 @@
prpl_col = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width - PRPL_SIZE;
+ cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(gtkblist->tipwindow))); for(l = gtkblist->tooltipdata; l; l = l->next)
struct tooltip_data *td = l->data;
- cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(gtkblist->tipwindow));
if (td->avatar && pidgin_gdk_pixbuf_is_opaque(td->avatar))
if (dir == GTK_TEXT_DIR_RTL)
- gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- gtkblist->tipwindow, "tooltip",
- TOOLTIP_BORDER - 1, current_height - 1,
- td->avatar_width + 2, td->avatar_height + 2);
+ gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, + NULL, gtkblist->tipwindow, "tooltip", + TOOLTIP_BORDER -1, current_height -1, td->avatar_width +2, td->avatar_height + 2); - gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- gtkblist->tipwindow, "tooltip",
- max_width - (td->avatar_width + TOOLTIP_BORDER) - 1,
- td->avatar_width + 2, td->avatar_height + 2);
+ gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, + NULL, gtkblist->tipwindow, "tooltip", + max_width - (td->avatar_width+ TOOLTIP_BORDER)-1, + current_height-1,td->avatar_width+2, td->avatar_height+2); if (dir == GTK_TEXT_DIR_RTL) {
gdk_cairo_set_source_pixbuf(cr, td->status_icon,
- max_width - TOOLTIP_BORDER - status_size, current_height);
+ max_width - TOOLTIP_BORDER - status_size, - gdk_cairo_set_source_pixbuf(cr, td->status_icon, TOOLTIP_BORDER, current_height);
+ gdk_cairo_set_source_pixbuf(cr, td->status_icon, + TOOLTIP_BORDER, current_height);
if (dir == GTK_TEXT_DIR_RTL) {
- gdk_cairo_set_source_pixbuf(cr, td->avatar, TOOLTIP_BORDER,
+ gdk_cairo_set_source_pixbuf(cr, td->avatar, + TOOLTIP_BORDER, current_height); gdk_cairo_set_source_pixbuf(cr, td->avatar,
- max_width - (td->avatar_width + TOOLTIP_BORDER), current_height);
+ max_width - (td->avatar_width + TOOLTIP_BORDER), if (!td->avatar_is_prpl_icon && td->prpl_icon) {
gdk_cairo_set_source_pixbuf(cr, td->prpl_icon, prpl_col,
- current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)));
+ (td->name_height - PRPL_SIZE) / 2); if (dir == GTK_TEXT_DIR_RTL) {
- gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
- gtkblist->tipwindow, "tooltip",
- max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
+ gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, + NULL, gtkblist->tipwindow, "tooltip", + max_width -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000), current_height, td->name_layout);
- gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
- gtkblist->tipwindow, "tooltip",
+ gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, + NULL, gtkblist->tipwindow, "tooltip", TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
if (dir != GTK_TEXT_DIR_RTL) {
- gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
- gtkblist->tipwindow, "tooltip",
+ gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, + NULL, gtkblist->tipwindow, "tooltip", TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height + td->name_height, td->layout);
- gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
- gtkblist->tipwindow, "tooltip",
+ gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, + NULL, gtkblist->tipwindow, "tooltip", max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
current_height + td->name_height,
current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
@@ -3193,7 +3197,7 @@
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node); if (!gtknode->contact_expanded) {
@@ -3201,8 +3205,7 @@
pidgin_blist_expand_contact_cb(NULL, node);
gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->contact_rect);
- gtkblist->contact_rect.width =
- gdk_window_get_width(gtk_widget_get_window(tv));
+ gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL); gtkblist->mouseover_contact = node;
gtk_tree_path_down (path);
while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) {
@@ -3223,13 +3226,13 @@
- gtknode = ((PurpleBlistNode*)buddy)->ui_data;
- return (purple_account_is_connected(buddy->account) &&
- (purple_presence_is_online(buddy->presence) ||
+ gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); + return (purple_account_is_connected(purple_buddy_get_account(buddy)) && + (purple_presence_is_online(purple_buddy_get_presence(buddy)) || (gtknode && gtknode->recent_signonoff) ||
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies") ||
- purple_blist_node_get_bool((PurpleBlistNode*)buddy, "show_offline")));
+ purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy), "show_offline"))); void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget)
@@ -3404,7 +3407,7 @@
PurpleAccount *account = purple_connection_get_account(gc);
- if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) {
+ if (purple_connection_get_flags(gc) & 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);
@@ -3420,7 +3423,7 @@
PurpleAccount *account = (PurpleAccount *) accounts->data;
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc && gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS)) { update_status_with_mood(account, mood, NULL);
@@ -3455,9 +3458,9 @@
if (purple_account_is_connected(account)) {
PurpleConnection *gc = purple_account_get_connection(account);
- if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
+ if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOODS) { PurplePluginProtocolInfo *prpl_info =
- PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); /* PURPLE_CONNECTION_SUPPORT_MOODS would not be set if the prpl doesn't
@@ -3515,7 +3518,7 @@
PurpleAccount *account = (PurpleAccount *) accounts->data;
if (purple_account_is_connected(account) &&
- (purple_account_get_connection(account)->flags &
+ (purple_connection_get_flags(purple_account_get_connection(account)) & PURPLE_CONNECTION_SUPPORT_MOODS)) {
PurplePresence *presence = purple_account_get_presence(account);
PurpleStatus *status = purple_presence_get_status(presence, "mood");
@@ -3550,8 +3553,8 @@
PurplePresence *presence = purple_account_get_presence(account);
PurpleStatus *status = purple_presence_get_status(presence, "mood");
gc = purple_account_get_connection(account);
- g_return_if_fail(gc->prpl != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ g_return_if_fail(purple_connection_get_prpl(gc) != NULL); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
current_mood = get_global_mood_status();
@@ -3561,7 +3564,7 @@
g = purple_request_field_group_new(NULL);
f = purple_request_field_list_new("mood", _("Please select your mood from the list"));
- purple_request_field_list_add(f, _("None"), "");
+ purple_request_field_list_add_icon(f, _("None"), NULL, ""); if (current_mood == NULL)
purple_request_field_list_add_selected(f, _("None"));
@@ -3590,7 +3593,7 @@
purple_request_fields_add_group(fields, g);
/* if the connection allows setting a mood message */
- if (gc && (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) {
+ if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) { g = purple_request_field_group_new(NULL);
f = purple_request_field_string_new("text",
_("Message (optional)"), NULL, FALSE);
@@ -3599,11 +3602,11 @@
purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"),
- _("OK"), G_CALLBACK(edit_mood_cb),
- gc ? purple_connection_get_account(gc) : NULL,
+ _("OK"), G_CALLBACK(edit_mood_cb), + gc ? purple_connection_get_account(gc) : NULL, @@ -3617,9 +3620,10 @@
/***************************************************
***************************************************/
/* TODO: fill out tooltips... */
static const GtkActionEntry blist_menu_entries[] = {
+/* NOTE: Do not set any accelerator to Control+O. It is mapped by + gtk_blist_key_press_cb to "Get User Info" on the selected buddy. */ { "BuddiesMenu", NULL, N_("_Buddies"), NULL, NULL, NULL },
{ "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, pidgin_dialogs_im },
@@ -3646,7 +3650,7 @@
{ "Plugins", PIDGIN_STOCK_TOOLBAR_PLUGINS, N_("Plu_gins"), "<control>U", NULL, pidgin_plugin_dialog_show },
{ "Preferences", GTK_STOCK_PREFERENCES, N_("Pr_eferences"), "<control>P", NULL, pidgin_prefs_show },
{ "Privacy", NULL, N_("Pr_ivacy"), NULL, NULL, pidgin_privacy_dialog_show },
- { "SetMood", NULL, N_("Set _Mood"), "<control>O", NULL, set_mood_show },
+ { "SetMood", NULL, N_("Set _Mood"), "<control>D", NULL, set_mood_show }, { "FileTransfers", PIDGIN_STOCK_TOOLBAR_TRANSFER, N_("_File Transfers"), "<control>T", NULL, G_CALLBACK(gtk_blist_show_xfer_dialog_cb) },
{ "RoomList", NULL, N_("R_oom List"), NULL, NULL, pidgin_roomlist_dialog_show },
{ "SystemLog", NULL, N_("System _Log"), NULL, NULL, gtk_blist_show_systemlog_cb },
@@ -3657,6 +3661,7 @@
{ "BuildInformation", NULL, N_("_Build Information"), NULL, NULL, pidgin_dialogs_buildinfo },
{ "DebugWindow", NULL, N_("_Debug Window"), NULL, NULL, toggle_debug },
{ "DeveloperInformation", NULL, N_("De_veloper Information"), NULL, NULL, pidgin_dialogs_developers },
+ { "PluginInformation", NULL, N_("_Plugin Information"), NULL, NULL, pidgin_dialogs_plugins_info }, { "TranslatorInformation", NULL, N_("_Translator Information"), NULL, NULL, pidgin_dialogs_translators },
{ "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, pidgin_dialogs_about },
@@ -3726,6 +3731,7 @@
"<menuitem action='BuildInformation'/>"
"<menuitem action='DebugWindow'/>"
"<menuitem action='DeveloperInformation'/>"
+ "<menuitem action='PluginInformation'/>" "<menuitem action='TranslatorInformation'/>"
"<menuitem action='About'/>"
@@ -3733,66 +3739,6 @@
-static GtkItemFactoryEntry blist_menu[] =
-/* NOTE: Do not set any accelerator to Control+O. It is mapped by
- gtk_blist_key_press_cb to "Get User Info" on the selected buddy. */
- { N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
- { N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<StockItem>", PIDGIN_STOCK_CHAT },
- { N_("/Buddies/Get User _Info..."), "<CTL>I", pidgin_dialogs_info, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
- { N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL },
- { "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/Sh_ow"), NULL, NULL, 0, "<Branch>", NULL},
- { N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/_Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/Show/_Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL },
- { N_("/Buddies/_Sort Buddies"), NULL, NULL, 0, "<Branch>", NULL },
- { "/Buddies/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/_Add Buddy..."), "<CTL>B", pidgin_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
- { N_("/Buddies/Add C_hat..."), NULL, pidgin_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD },
- { N_("/Buddies/Add _Group..."), NULL, purple_blist_request_add_group, 0, "<StockItem>", GTK_STOCK_ADD },
- { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
- { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Accounts/Manage Accounts"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
- { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "<Item>", NULL },
- { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
- { N_("/Tools/Custom Smile_ys"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
- { N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
- { N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
- { N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
- { N_("/Tools/Set _Mood"), "<CTL>D", set_mood_show, 0, "<Item>", NULL },
- { "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
- { N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
- { N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 3, "<Item>", NULL },
- { "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Tools/Mute _Sounds"), NULL, pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL },
- { N_("/_Help"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP },
- { "/Help/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Help/_Build Information"), NULL, pidgin_dialogs_buildinfo, 0, "<Item>", NULL },
- { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
- { N_("/Help/De_veloper Information"), NULL, pidgin_dialogs_developers, 0, "<Item>", NULL },
- { N_("/Help/_Plugin Information"), NULL, pidgin_dialogs_plugins_info, 0, "<Item>", NULL },
- { N_("/Help/_Translator Information"), NULL, pidgin_dialogs_translators, 0, "<Item>", NULL },
- { "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT },
/*********************************************************
* Private Utility functions *
*********************************************************/
@@ -3812,16 +3758,16 @@
struct proto_chat_entry *pce;
PurpleConversation *conv;
- PidginBlistNode *bnode = node->ui_data;
+ PidginBlistNode *bnode = purple_blist_node_get_ui_data(node); chat = (PurpleChat *)node;
- prpl = purple_find_prpl(purple_account_get_protocol_id(chat->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_chat_get_account(chat))); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
connections = purple_connections_get_all();
if (connections && connections->next)
- tmp = g_markup_escape_text(chat->account->username, -1);
+ tmp = g_markup_escape_text(purple_account_get_username(purple_chat_get_account(chat)), -1); g_string_append_printf(str, _("<b>Account:</b> %s"), tmp);
@@ -3831,12 +3777,12 @@
if (prpl_info && prpl_info->get_chat_name)
- chat_name = prpl_info->get_chat_name(chat->components);
+ chat_name = prpl_info->get_chat_name(purple_chat_get_components(chat)); chat_name = g_strdup(purple_chat_get_name(chat));
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chat_name,
+ purple_chat_get_account(chat)); @@ -3853,7 +3799,7 @@
if (prpl_info && prpl_info->chat_info != NULL)
- cur = prpl_info->chat_info(chat->account->gc);
+ cur = prpl_info->chat_info(purple_account_get_connection(purple_chat_get_account(chat))); @@ -3862,13 +3808,13 @@
if (!pce->secret && (!pce->required &&
- g_hash_table_lookup(chat->components, pce->identifier) == NULL))
+ g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier) == NULL)) tmp = purple_text_strip_mnemonic(pce->label);
name = g_markup_escape_text(tmp, -1);
value = g_markup_escape_text(g_hash_table_lookup(
- chat->components, pce->identifier), -1);
+ purple_chat_get_components(chat), pce->identifier), -1); g_string_append_printf(str, "\n<b>%s</b> %s",
@@ -3904,7 +3850,7 @@
c = purple_buddy_get_contact(b);
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b))); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
presence = purple_buddy_get_presence(b);
@@ -3921,12 +3867,12 @@
/* If there's not a contact alias, the node is being displayed with
* this alias, so there's no point in showing it in the tooltip. */
- if (full && c && b->alias != NULL && b->alias[0] != '\0' &&
+ if (full && c && purple_buddy_get_local_buddy_alias(b) != NULL && purple_buddy_get_local_buddy_alias(b)[0] != '\0' && (c->alias != NULL && c->alias[0] != '\0') &&
- strcmp(c->alias, b->alias) != 0)
+ strcmp(c->alias, purple_buddy_get_local_buddy_alias(b)) != 0) purple_notify_user_info_add_pair_plaintext(user_info,
- _("Buddy Alias"), b->alias);
+ _("Buddy Alias"), purple_buddy_get_local_buddy_alias(b)); /* Nickname/Server Alias */
@@ -3934,10 +3880,10 @@
* alias, but many people on MSN set long nicknames, which
* get ellipsized, so the only way to see the whole thing is
* to look at the tooltip. */
- if (full && b->server_alias != NULL && b->server_alias[0] != '\0')
+ if (full && purple_buddy_get_server_alias(b)) purple_notify_user_info_add_pair_plaintext(user_info,
- _("Nickname"), b->server_alias);
+ _("Nickname"), purple_buddy_get_server_alias(b)); @@ -3972,7 +3918,7 @@
if (full && c && !PURPLE_BUDDY_IS_ONLINE(b))
- struct _pidgin_blist_node *gtknode = ((PurpleBlistNode *)c)->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(c)); @@ -4012,7 +3958,7 @@
purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Offline"));
- if (purple_account_is_connected(b->account) &&
+ if (purple_account_is_connected(purple_buddy_get_account(b)) && prpl_info && prpl_info->tooltip_text)
/* Additional text from the PRPL */
@@ -4020,11 +3966,11 @@
/* These are Easter Eggs. Patches to remove them will be rejected. */
- if (!g_ascii_strcasecmp(b->name, "robflynn"))
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "robflynn")) purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), _("Spooky"));
- if (!g_ascii_strcasecmp(b->name, "seanegn"))
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "seanegn")) purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Awesome"));
- if (!g_ascii_strcasecmp(b->name, "chipx86"))
+ if (!g_ascii_strcasecmp(purple_buddy_get_name(b), "chipx86")) purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Rockin'"));
tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
@@ -4101,7 +4047,7 @@
pidgin_blist_get_emblem(PurpleBlistNode *node)
PurpleBuddy *buddy = NULL;
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); PurplePluginProtocolInfo *prpl_info;
@@ -4124,10 +4070,10 @@
return _pidgin_blist_get_cached_emblem(path);
- if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) {
+ if (((struct _pidgin_blist_node*)purple_blist_node_get_ui_data(node->parent))->contact_expanded) { if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"))
- return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL);
+ return pidgin_create_prpl_icon(purple_buddy_get_account((PurpleBuddy*)node), PIDGIN_PRPL_ICON_SMALL); @@ -4135,7 +4081,7 @@
g_return_val_if_fail(buddy != NULL, NULL);
- if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
+ if (!purple_privacy_check(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))) { path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
return _pidgin_blist_get_cached_emblem(path);
@@ -4171,7 +4117,7 @@
return _pidgin_blist_get_cached_emblem(path);
- prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(buddy))); @@ -4208,7 +4154,7 @@
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); struct _pidgin_blist_node *gtkbuddynode = NULL;
PurpleBuddy *buddy = NULL;
@@ -4219,11 +4165,11 @@
if(!gtknode->contact_expanded) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
- gtkbuddynode = ((PurpleBlistNode*)buddy)->ui_data;
+ gtkbuddynode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
- gtkbuddynode = node->ui_data;
+ gtkbuddynode = purple_blist_node_get_ui_data(node); } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
chat = (PurpleChat*)node;
@@ -4235,9 +4181,9 @@
- account = buddy->account;
+ account = purple_buddy_get_account(buddy); - account = chat->account;
+ account = purple_chat_get_account(chat); prpl = purple_find_prpl(purple_account_get_protocol_id(account));
@@ -4252,7 +4198,7 @@
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
if (gtkconv == NULL && size == PIDGIN_STATUS_ICON_SMALL) {
- PidginBlistNode *ui = buddy->node.ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(&(buddy->node)); if (ui == NULL || (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE))
return gtk_widget_render_icon (GTK_WIDGET(gtkblist->treeview),
PIDGIN_STOCK_STATUS_MESSAGE, icon_size, "GtkTreeView");
@@ -4336,7 +4282,7 @@
- PidginBlistNode *ui = b->node.ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(&(b->node)); if (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE)
@@ -4370,12 +4316,12 @@
if (!aliased || biglist) {
- prpl = purple_find_prpl(purple_account_get_protocol_id(b->account));
+ prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(b))); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (prpl_info && prpl_info->status_text && b->account->gc) {
+ if (prpl_info && prpl_info->status_text && purple_account_get_connection(purple_buddy_get_account(b))) { char *tmp = prpl_info->status_text(b);
@@ -4570,7 +4516,7 @@
purple_presence_is_idle(purple_buddy_get_presence(buddy)))
- pidgin_blist_update_contact(list, (PurpleBlistNode*)buddy);
+ pidgin_blist_update_contact(list, PURPLE_BLIST_NODE(buddy)); @@ -4581,7 +4527,7 @@
static void pidgin_blist_hide_node(PurpleBuddyList *list, PurpleBlistNode *node, gboolean update)
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); if (!gtknode || !gtknode->row || !gtkblist)
@@ -4739,6 +4685,7 @@
conversation_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type,
PidginBuddyList *gtkblist)
+ PurpleAccount *account = purple_conversation_get_account(conv); @@ -4746,10 +4693,10 @@
if (type != PURPLE_CONV_UPDATE_UNSEEN)
- if(conv->account != NULL && conv->name != NULL) {
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ if(account != NULL && purple_conversation_get_name(conv) != NULL) { + PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); - pidgin_blist_update_buddy(NULL, (PurpleBlistNode *)buddy, TRUE);
+ pidgin_blist_update_buddy(NULL, PURPLE_BLIST_NODE(buddy), TRUE); if (gtkblist->menutrayicon) {
@@ -4829,7 +4776,7 @@
written_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *message,
PurpleConversation *conv, PurpleMessageFlags flag, PurpleBlistNode *node)
- PidginBlistNode *ui = node->ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(node); if (ui->conv.conv != conv || !pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv)) ||
!(flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)))
@@ -4845,7 +4792,7 @@
displayed_msg_update_ui_cb(PidginConversation *gtkconv, PurpleBlistNode *node)
- PidginBlistNode *ui = node->ui_data;
+ PidginBlistNode *ui = purple_blist_node_get_ui_data(node); if (ui->conv.conv != gtkconv->active_conv)
ui->conv.flags &= ~(PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE |
@@ -4856,13 +4803,15 @@
conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
+ PurpleAccount *account = purple_conversation_get_account(conv); + switch (purple_conversation_get_type(conv)) { case PURPLE_CONV_TYPE_IM:
- GSList *buddies = purple_find_buddies(conv->account, conv->name);
+ GSList *buddies = purple_find_buddies(account, purple_conversation_get_name(conv)); PurpleBlistNode *buddy = buddies->data;
- struct _pidgin_blist_node *ui = buddy->ui_data;
+ struct _pidgin_blist_node *ui = purple_blist_node_get_ui_data(buddy); buddies = g_slist_delete_link(buddies, buddies);
@@ -4880,11 +4829,11 @@
case PURPLE_CONV_TYPE_CHAT:
- PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
+ PurpleChat *chat = purple_blist_find_chat(account, purple_conversation_get_name(conv)); struct _pidgin_blist_node *ui;
- ui = chat->node.ui_data;
+ ui = purple_blist_node_get_ui_data(&(chat->node)); @@ -4912,8 +4861,6 @@
PidginBuddyList *gtkblist;
gtkblist = g_new0(PidginBuddyList, 1);
- gtkblist->connection_errors = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, g_free);
gtkblist->priv = g_new0(PidginBuddyListPrivate, 1);
blist->ui_data = gtkblist;
@@ -4921,7 +4868,7 @@
static void pidgin_blist_new_node(PurpleBlistNode *node)
- node->ui_data = g_new0(struct _pidgin_blist_node, 1);
+ purple_blist_node_set_ui_data(node, g_new0(struct _pidgin_blist_node, 1)); gboolean pidgin_blist_node_is_contact_expanded(PurpleBlistNode *node)
@@ -4934,7 +4881,7 @@
g_return_val_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node), FALSE);
- return ((struct _pidgin_blist_node *)node->ui_data)->contact_expanded;
+ return ((struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node))->contact_expanded; @@ -4984,7 +4931,7 @@
struct _pidgin_blist_node *gtknode;
- gtknode = node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node); if (gtknode && gtknode->row)
path = gtk_tree_row_reference_get_path(gtknode->row);
@@ -5068,7 +5015,7 @@
widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window));
if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) {
- if (gtk_bindings_activate(G_OBJECT(widget), event->keyval, event->state))
+ if (gtk_bindings_activate(GTK_OBJECT(widget), event->keyval, event->state)) @@ -5077,14 +5024,14 @@
headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
- gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->hand_cursor);
+ gdk_window_set_cursor(widget->window, gtkblist->hand_cursor); headline_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
- gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->arrow_cursor);
+ gdk_window_set_cursor(widget->window, gtkblist->arrow_cursor); @@ -5218,10 +5165,9 @@
-generic_error_destroy_cb(GtkWidget *dialog,
+generic_error_destroy_cb(GtkObject *dialog, - g_hash_table_remove(gtkblist->connection_errors, account);
/* If the error dialog is being destroyed in response to the
* account-error-changed signal, we don't want to clear the current
@@ -5479,28 +5425,6 @@
- * Was used by the connection API to tell the blist if an account has a
- * connection error or no longer has a connection error, but the blist now does
- * this itself with the @ref account-error-changed signal.
- * @param account The account that either has a connection error
- * or no longer has a connection error.
- * @param message The connection error message, or NULL if this
- * account is no longer in an error state.
-pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text)
- /* connection_errors isn't actually used anywhere; it's just kept in
- * sync with reality in case a plugin uses it.
- g_hash_table_remove(gtkblist->connection_errors, account);
- g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text));
/* Call appropriate error notification code based on error types */
update_account_error_state(PurpleAccount *account,
@@ -5514,12 +5438,6 @@
if (old == NULL && new == NULL)
- /* For backwards compatibility: */
- pidgin_blist_update_account_error_state(account, new->description);
- pidgin_blist_update_account_error_state(account, NULL);
pidgin_blist_select_notebook_page(gtkblist);
@@ -5590,22 +5508,17 @@
- cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
- gtk_paint_flat_box (gtk_widget_get_style(widget),
- allocation.height - 2);
+ gtk_paint_flat_box (widget->style, + widget->allocation.x + 1, + widget->allocation.y + 1, + widget->allocation.width - 2, + widget->allocation.height - 2); @@ -5944,9 +5857,7 @@
G_CALLBACK(blist_focus_cb), gtkblist);
g_signal_connect(G_OBJECT(gtkblist->window), "focus-out-event",
G_CALLBACK(blist_focus_cb), gtkblist);
- /* TODO: how is this done in gtk+ 3.0? */
- /*GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;*/
+ GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE; gtkblist->main_vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(gtkblist->main_vbox);
@@ -6015,6 +5926,7 @@
pretty = pidgin_make_pretty_arrows(tmp);
label = gtk_label_new(NULL);
+ gtk_widget_set_size_request(label, purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/width") - 12, -1); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.2);
gtk_label_set_markup(GTK_LABEL(label), pretty);
@@ -6031,8 +5943,10 @@
gtk_container_set_border_width(GTK_CONTAINER(gtkblist->headline_hbox), 6);
gtk_container_add(GTK_CONTAINER(ebox), gtkblist->headline_hbox);
gtkblist->headline_image = gtk_image_new_from_pixbuf(NULL);
- gtk_misc_set_alignment(GTK_MISC(gtkblist->headline_image), 0.5, 0.5);
+ gtk_misc_set_alignment(GTK_MISC(gtkblist->headline_image), 0.0, 0); gtkblist->headline_label = gtk_label_new(NULL);
+ gtk_widget_set_size_request(gtkblist->headline_label, + purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/width")-25,-1); gtk_label_set_line_wrap(GTK_LABEL(gtkblist->headline_label), TRUE);
gtk_box_pack_start(GTK_BOX(gtkblist->headline_hbox), gtkblist->headline_image, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(gtkblist->headline_hbox), gtkblist->headline_label, TRUE, TRUE, 0);
@@ -6042,7 +5956,7 @@
G_CALLBACK(headline_style_set),
g_signal_connect (gtkblist->headline_hbox,
G_CALLBACK (paint_headline_hbox),
gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips");
@@ -6339,7 +6253,7 @@
static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter) {
- struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); @@ -6368,7 +6282,7 @@
static void pidgin_blist_remove(PurpleBuddyList *list, PurpleBlistNode *node)
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); purple_request_close_with_handle(node);
@@ -6390,9 +6304,9 @@
if(gtknode->recent_signonoff_timer > 0)
purple_timeout_remove(gtknode->recent_signonoff_timer);
- purple_signals_disconnect_by_handle(node->ui_data);
+ purple_signals_disconnect_by_handle(gtknode); + purple_blist_node_set_ui_data(node, NULL); @@ -6436,8 +6350,8 @@
static gboolean insert_node(PurpleBuddyList *list, PurpleBlistNode *node, GtkTreeIter *iter)
- GtkTreeIter parent_iter, cur, *curptr = NULL;
- struct _pidgin_blist_node *gtknode = node->ui_data;
+ GtkTreeIter parent_iter = {0, NULL, NULL, NULL}, cur, *curptr = NULL; + struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(node); @@ -6459,7 +6373,7 @@
gtk_tree_row_reference_free(gtknode->row);
pidgin_blist_new_node(node);
- gtknode = (struct _pidgin_blist_node *)node->ui_data;
+ gtknode = purple_blist_node_get_ui_data(node); newpath = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel),
@@ -6477,7 +6391,7 @@
GtkTreePath *expand = NULL;
- struct _pidgin_blist_node *gtkparentnode = node->parent->ui_data;
+ struct _pidgin_blist_node *gtkparentnode = purple_blist_node_get_ui_data(node->parent); if(PURPLE_BLIST_NODE_IS_GROUP(node->parent)) {
if(!purple_blist_node_get_bool(node->parent, "collapsed"))
@@ -6499,12 +6413,12 @@
PurpleBlistNode *gnode, *cnode, *bnode;
- gnode = (PurpleBlistNode *)group;
+ gnode = PURPLE_BLIST_NODE(group); for(cnode = gnode->child; cnode; cnode = cnode->next) {
if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
for(bnode = cnode->child; bnode; bnode = bnode->next) {
PurpleBuddy *buddy = (PurpleBuddy *)bnode;
- if (purple_account_is_connected(buddy->account) &&
+ if (purple_account_is_connected(purple_buddy_get_account(buddy)) && purple_blist_node_get_bool(bnode, "show_offline"))
@@ -6644,7 +6558,7 @@
text_color = selected ? NULL : theme_font_get_color_default(pair, NULL);
text_font = theme_font_get_face_default(pair, "");
- esc = g_markup_escape_text(group->name, -1);
+ esc = g_markup_escape_text(purple_group_get_name(group), -1); mark = g_strdup_printf("<span foreground='%s' font_desc='%s'><b>%s</b>%s%s%s</span>",
@@ -6671,7 +6585,7 @@
- gboolean expanded = ((struct _pidgin_blist_node *)(node->parent->ui_data))->contact_expanded;
+ gboolean expanded = ((struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node->parent))->contact_expanded; gboolean selected = (gtkblist->selected_node == node);
gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
@@ -6679,12 +6593,12 @@
- status = pidgin_blist_get_status_icon((PurpleBlistNode*)buddy,
+ status = pidgin_blist_get_status_icon(PURPLE_BLIST_NODE(buddy), biglist ? PIDGIN_STATUS_ICON_LARGE : PIDGIN_STATUS_ICON_SMALL);
/* Speed it up if we don't want buddy icons. */
- avatar = pidgin_blist_get_buddy_icon((PurpleBlistNode *)buddy, TRUE, TRUE);
+ avatar = pidgin_blist_get_buddy_icon(PURPLE_BLIST_NODE(buddy), TRUE, TRUE); @@ -6695,7 +6609,7 @@
do_alphashift(avatar, 77);
- emblem = pidgin_blist_get_emblem((PurpleBlistNode*) buddy);
+ emblem = pidgin_blist_get_emblem(PURPLE_BLIST_NODE(buddy)); mark = pidgin_blist_get_name_markup(buddy, selected, TRUE);
theme = pidgin_blist_get_theme();
@@ -6736,7 +6650,7 @@
- prpl_icon = pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL);
+ prpl_icon = pidgin_create_prpl_icon(purple_buddy_get_account(buddy), PIDGIN_PRPL_ICON_SMALL); color = pidgin_blist_theme_get_contact_color(theme);
@@ -6807,7 +6721,7 @@
if(!insert_node(list, cnode, &iter))
- gtknode = (struct _pidgin_blist_node *)cnode->ui_data;
+ gtknode = purple_blist_node_get_ui_data(cnode); if(gtknode->contact_expanded) {
@@ -6884,7 +6798,7 @@
/* First things first, update the contact */
pidgin_blist_update_contact(list, node);
- gtkparentnode = (struct _pidgin_blist_node *)node->parent->ui_data;
+ gtkparentnode = purple_blist_node_get_ui_data(node->parent); if (gtkparentnode->contact_expanded && buddy_is_displayable(buddy))
@@ -6915,7 +6829,7 @@
chat = (PurpleChat*)node;
- if(purple_account_is_connected(chat->account)) {
+ if(purple_account_is_connected(purple_chat_get_account(chat))) { GdkPixbuf *status, *avatar, *emblem, *prpl_icon;
const gchar *color, *font;
@@ -6934,7 +6848,7 @@
if (!insert_node(list, node, &iter))
+ ui = purple_blist_node_get_ui_data(node); if (conv && pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv))) {
hidden = (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE);
@@ -6979,7 +6893,7 @@
- prpl_icon = pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL);
+ prpl_icon = pidgin_create_prpl_icon(purple_chat_get_account(chat), PIDGIN_PRPL_ICON_SMALL); bgcolor = pidgin_blist_theme_get_contact_color(theme);
@@ -7020,10 +6934,10 @@
if(!gtkblist || !gtkblist->treeview || !node)
- if (node->ui_data == NULL)
+ if (purple_blist_node_get_ui_data(node) == NULL) pidgin_blist_new_node(node);
+ switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_GROUP_NODE:
pidgin_blist_update_group(list, node);
@@ -7067,7 +6981,6 @@
if (gtkblist->drag_timeout)
g_source_remove(gtkblist->drag_timeout);
- g_hash_table_destroy(gtkblist->connection_errors);
gtkblist->refresh_timer = 0;
gtkblist->drag_timeout = 0;
@@ -7098,8 +7011,7 @@
- if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) &&
- !gtk_widget_get_visible(gtkblist->window))
+ if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !gtk_widget_get_visible(gtkblist->window)) purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-unhiding", gtkblist);
pidgin_blist_restore_position();
gtk_window_present(GTK_WINDOW(gtkblist->window));
@@ -7119,7 +7031,6 @@
static GList *list = NULL;
@@ -7139,8 +7050,7 @@
if (PURPLE_BLIST_NODE_IS_GROUP(gnode))
g = (PurpleGroup *)gnode;
- list = g_list_append(list, tmp2);
+ list = g_list_append(list, (char *) purple_group_get_name(g)); @@ -7223,11 +7133,11 @@
purple_blist_add_buddy(b, NULL, g, NULL);
- purple_account_add_buddy_with_invite(account, b, invite);
+ purple_account_add_buddy(account, b, invite); /* Offer to merge people with the same alias. */
if (whoalias != NULL && g != NULL)
- gtk_blist_auto_personize((PurpleBlistNode *)g, whoalias);
+ gtk_blist_auto_personize(PURPLE_BLIST_NODE(g), whoalias); @@ -7375,10 +7285,10 @@
purple_blist_add_chat(chat, group, NULL);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->autojoin)))
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin", TRUE);
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-autojoin", TRUE); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->persistent)))
- purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent", TRUE);
+ purple_blist_node_set_bool(PURPLE_BLIST_NODE(chat), "gtk-persistent", TRUE); gtk_widget_destroy(data->chat_data.rq_data.window);
@@ -7415,11 +7325,13 @@
+ PurplePluginProtocolInfo *prpl_info = NULL; gc = purple_account_get_connection(account);
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat == NULL) {
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); + if (prpl_info->join_chat == NULL) { purple_notify_error(gc, NULL, _("This protocol does not support chat rooms."), NULL);
@@ -7427,8 +7339,9 @@
/* Find an account with chat capabilities */
for (l = purple_connections_get_all(); l != NULL; l = l->next) {
gc = (PurpleConnection *)l->data;
- if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat != NULL) {
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); + if (prpl_info->join_chat != NULL) { account = purple_connection_get_account(gc);
@@ -7472,7 +7385,7 @@
gtk_widget_grab_focus(data->alias_entry);
- data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree());
+ data->group_combo = pidgin_text_combo_box_entry_new(group ? purple_group_get_name(group) : NULL, groups_tree()); pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"),
data->chat_data.rq_data.sg, data->group_combo,
@@ -7578,7 +7491,7 @@
- if (gtkblist->window && !gtk_widget_is_focus(gtkblist->window))
+ if (gtkblist->window && !gtk_widget_has_focus(gtkblist->window)) pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE);
@@ -7629,11 +7542,11 @@
chat = (PurpleChat *)cnode;
- if(chat->account != account)
+ if(purple_chat_get_account(chat) != account) - if (purple_blist_node_get_bool((PurpleBlistNode*)chat, "gtk-autojoin"))
- serv_join_chat(gc, chat->components);
+ if (purple_blist_node_get_bool(PURPLE_BLIST_NODE(chat), "gtk-autojoin")) + serv_join_chat(gc, purple_chat_get_components(chat)); @@ -7650,25 +7563,25 @@
static gboolean buddy_signonoff_timeout_cb(PurpleBuddy *buddy)
- struct _pidgin_blist_node *gtknode = ((PurpleBlistNode*)buddy)->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); gtknode->recent_signonoff = FALSE;
gtknode->recent_signonoff_timer = 0;
- pidgin_blist_update(NULL, (PurpleBlistNode*)buddy);
+ pidgin_blist_update(NULL, PURPLE_BLIST_NODE(buddy)); static void buddy_signonoff_cb(PurpleBuddy *buddy)
- struct _pidgin_blist_node *gtknode;
- if(!((PurpleBlistNode*)buddy)->ui_data) {
- pidgin_blist_new_node((PurpleBlistNode*)buddy);
- gtknode = ((PurpleBlistNode*)buddy)->ui_data;
+ struct _pidgin_blist_node *gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); + pidgin_blist_new_node(PURPLE_BLIST_NODE(buddy)); + gtknode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); gtknode->recent_signonoff = TRUE;
@@ -8035,7 +7948,7 @@
for (n = node->child; n; n = n->next) {
- activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account);
+ activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); buddy_name = purple_contact_get_alias((PurpleContact*)node);
} else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
@@ -8070,8 +7983,8 @@
if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
for (n2 = n->child; n2; n2 = n2->next) {
- buddy = (PurpleBuddy*)n2;
- this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account);
+ buddy = (PurpleBuddy*)n2; + this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); this_buddy_name = purple_contact_get_alias((PurpleContact*)n);
@@ -8106,7 +8019,7 @@
-plugin_act(GtkWidget *obj, PurplePluginAction *pam)
+plugin_act(GtkObject *obj, PurplePluginAction *pam) if (pam && pam->callback)
@@ -8247,7 +8160,7 @@
g_string_append(accounts_ui, "<separator/>");
gc = purple_account_get_connection(account);
- plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+ plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? purple_connection_get_prpl(gc) : NULL; if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
build_plugin_actions(accounts_action_group, accounts_ui, base, plugin, gc);
@@ -8424,3 +8337,4 @@
g_string_free(ui_string, TRUE);
--- a/pidgin/gtkconv.c Mon Aug 22 22:46:08 2011 +0000
+++ b/pidgin/gtkconv.c Fri Dec 23 08:21:58 2011 +0000
@@ -52,6 +52,8 @@
+#include "theme-loader.h" +#include "theme-manager.h" @@ -59,6 +61,8 @@
+#include "gtkconv-theme.h" +#include "gtkconv-theme-loader.h" #include "gtkimhtmltoolbar.h"
@@ -69,11 +73,55 @@
#include "pidgintooltip.h"
+#include "smileyparser.h" #include "gtknickcolors.h"
+#if !GTK_CHECK_VERSION(2,20,0) +#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x) +#if !GTK_CHECK_VERSION(2,18,0) +#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x) +#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x) + * A GTK+ Instant Message pane. + GtkWidget *icon_container; + GdkPixbufAnimation *anim; + GdkPixbufAnimationIter *iter; #define CLOSE_CONV_TIMEOUT_SECS (10 * 60)
#define AUTO_RESPONSE "<AUTO-REPLY> : "
@@ -175,7 +223,7 @@
static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name)
- GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
+ GtkStyle *style = gtk_widget_get_style(gtkconv->webview); col = nick_colors[g_str_hash(name) % nbr_nick_colors];
@@ -195,15 +243,16 @@
get_conversation_blist_node(PurpleConversation *conv)
+ PurpleAccount *account = purple_conversation_get_account(conv); PurpleBlistNode *node = NULL;
switch (purple_conversation_get_type(conv)) {
case PURPLE_CONV_TYPE_IM:
- node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name));
+ node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_conversation_get_name(conv))); node = node ? node->parent : NULL;
case PURPLE_CONV_TYPE_CHAT:
- node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name));
+ node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv))); @@ -275,7 +324,7 @@
default_formatize(PidginConversation *c)
PurpleConversation *conv = c->active_conv;
- gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features);
+ gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), purple_conversation_get_features(conv)); @@ -355,8 +404,32 @@
tmp = g_string_free(str, FALSE);
+ } else if (!g_ascii_strcasecmp(args[0], "unsafe")) { + if (purple_debug_is_unsafe()) { + purple_debug_set_unsafe(FALSE); + purple_conversation_write(conv, NULL, _("Unsafe debugging is now disabled."), + PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); + purple_debug_set_unsafe(TRUE); + purple_conversation_write(conv, NULL, _("Unsafe debugging is now enabled."), + PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); + return PURPLE_CMD_RET_OK; + } else if (!g_ascii_strcasecmp(args[0], "verbose")) { + if (purple_debug_is_verbose()) { + purple_debug_set_verbose(FALSE); + purple_conversation_write(conv, NULL, _("Verbose debugging is now disabled."), + PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); + purple_debug_set_verbose(TRUE); + purple_conversation_write(conv, NULL, _("Verbose debugging is now enabled."), + PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); + return PURPLE_CMD_RET_OK; - purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version"),
+ purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version unsafe verbose"), PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL));
return PURPLE_CMD_RET_OK;
@@ -378,8 +451,9 @@
PidginConversation *gtkconv = NULL;
gtkconv = PIDGIN_CONVERSATION(conv);
- gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml));
+ if (PIDGIN_CONVERSATION(conv)) + webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(gtkconv->webview), "", ""); @@ -497,8 +571,8 @@
PurplePluginProtocolInfo *prpl_info = NULL;
- if ((gc = purple_conversation_get_gc(conv)))
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ if ((gc = purple_conversation_get_connection(conv))) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) {
@@ -590,7 +664,7 @@
flags |= PURPLE_MESSAGE_IMAGES;
gc = purple_account_get_connection(account);
- if (gc && (conv->features & PURPLE_CONNECTION_NO_NEWLINES)) {
+ if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_NO_NEWLINES)) { @@ -656,7 +730,7 @@
PurpleConversation *conv = gtkconv->active_conv;
- if ((gc = purple_conversation_get_gc(conv))) {
+ if ((gc = purple_conversation_get_connection(conv))) { pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
@@ -668,7 +742,7 @@
PurpleConversation *conv = gtkconv->active_conv;
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- pidgin_retrieve_user_info(purple_conversation_get_gc(conv),
+ pidgin_retrieve_user_info(purple_conversation_get_connection(conv), purple_conversation_get_name(conv));
gtk_widget_grab_focus(gtkconv->entry);
} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
@@ -756,7 +830,7 @@
if (!g_ascii_strcasecmp(buddy, ""))
- serv_chat_invite(purple_conversation_get_gc(conv),
+ serv_chat_invite(purple_conversation_get_connection(conv), purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
@@ -774,17 +848,15 @@
InviteBuddyInfo *info = (InviteBuddyInfo *)data;
const char *convprotocol;
- GdkAtom target = gtk_selection_data_get_target(sd);
convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
- if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
+ if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) PurpleBlistNode *node = NULL;
- const guchar *data = gtk_selection_data_get_data(sd);
- memcpy(&node, data, sizeof(node));
+ memcpy(&node, sd->data, sizeof(node)); if (PURPLE_BLIST_NODE_IS_CONTACT(node))
buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
@@ -793,7 +865,7 @@
- if (strcmp(convprotocol, purple_account_get_protocol_id(buddy->account)))
+ if (strcmp(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy)))) purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
_("That buddy is not on the same protocol as this "
@@ -803,16 +875,15 @@
gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
- gtk_drag_finish(dc, success,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
- else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
+ gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); + else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) - if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
+ if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, &protocol, &username, NULL))
@@ -837,8 +908,7 @@
- gtk_drag_finish(dc, success,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+ gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); @@ -880,15 +950,14 @@
gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
- /* TODO: set no separator using GTK+ 3.0 */
+#if !GTK_CHECK_VERSION(2,22,0) gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
info->window = GTK_WIDGET(invite_dialog);
/* Setup the outside spacing. */
- vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
+ vbox = GTK_DIALOG(invite_dialog)->vbox; gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
@@ -986,7 +1055,7 @@
-menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget)
+menu_join_chat_cb(GtkAction *action, gpointer data) pidgin_blist_joinchat_show();
@@ -994,6 +1063,8 @@
savelog_writefile_cb(void *user_data, const char *filename)
+ /* TODO WEBKIT: I don't know how to support this using webkit yet. */ PurpleConversation *conv = (PurpleConversation *)user_data;
@@ -1020,6 +1091,7 @@
fprintf(fp, "\n</body>\n</html>\n");
@@ -1031,7 +1103,8 @@
PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ PurpleAccount *account = purple_conversation_get_account(conv); + PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); @@ -1039,7 +1112,7 @@
name = purple_buddy_get_contact_alias(buddy);
- name = purple_normalize(conv->account, conv->name);
+ name = purple_normalize(account, purple_conversation_get_name(conv)); buf = g_strdup_printf("%s.html", name);
@@ -1081,12 +1154,9 @@
gtkblist = pidgin_blist_get_default_gtk_blist();
cursor = gdk_cursor_new(GDK_WATCH);
- gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor);
- gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor);
+ gdk_window_set_cursor(gtkblist->window->window, cursor); + gdk_window_set_cursor(win->window->window, cursor); gdk_cursor_unref(cursor);
-#if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What?
- gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
name = purple_conversation_get_name(conv);
account = purple_conversation_get_account(conv);
@@ -1099,8 +1169,8 @@
pidgin_log_show_contact((PurpleContact *)node->parent);
- gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
- gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
+ gdk_window_set_cursor(gtkblist->window->window, NULL); + gdk_window_set_cursor(win->window->window, NULL); @@ -1108,8 +1178,8 @@
pidgin_log_show(type, name, account);
- gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
- gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
+ gdk_window_set_cursor(gtkblist->window->window, NULL); + gdk_window_set_cursor(win->window->window, NULL); @@ -1155,20 +1225,25 @@
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- serv_send_file(purple_conversation_get_gc(conv), purple_conversation_get_name(conv), NULL);
-menu_get_attention_cb(GtkAction *ation, gpointer data)
+ serv_send_file(purple_conversation_get_connection(conv), purple_conversation_get_name(conv), NULL); +menu_get_attention_cb(GObject *obj, gpointer data) PidginWindow *win = data;
PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- purple_prpl_send_attention(purple_conversation_get_gc(conv),
- purple_conversation_get_name(conv), 0);
+ if ((GtkAction *)obj == win->menu.get_attention) + index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "index")); + purple_prpl_send_attention(purple_conversation_get_connection(conv), + purple_conversation_get_name(conv), index); @@ -1364,16 +1439,14 @@
purple_conversation_write(conv, NULL,
_("Logging started. Future messages in this conversation will be logged."),
- conv->logs ? (PURPLE_MESSAGE_SYSTEM) :
- (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG),
purple_conversation_write(conv, NULL,
_("Logging stopped. Future messages in this conversation will not be logged."),
- conv->logs ? (PURPLE_MESSAGE_SYSTEM) :
- (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG),
/* Disable the logging second, so that the above message can be logged. */
@@ -1381,7 +1454,7 @@
/* Save the setting IFF it's different than the pref. */
+ switch (purple_conversation_get_type(conv)) case PURPLE_CONV_TYPE_IM:
if (logging == purple_prefs_get_bool("/purple/logging/log_ims"))
@@ -1453,7 +1526,7 @@
gc = purple_account_get_connection(account);
g_return_if_fail(gc != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
@@ -1504,12 +1577,12 @@
PurplePluginProtocolInfo *prpl_info;
PurpleConversation *conv = gtkconv->active_conv;
const char *who = g_object_get_data(G_OBJECT(w), "user_data");
- PurpleConnection *gc = purple_conversation_get_gc(conv);
+ PurpleConnection *gc = purple_conversation_get_connection(conv); g_return_if_fail(gc != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info && prpl_info->get_cb_real_name)
real_who = prpl_info->get_cb_real_name(gc,
@@ -1530,32 +1603,6 @@
-menu_chat_get_away_cb(GtkWidget *w, PidginConversation *gtkconv)
- PurpleConversation *conv = gtkconv->active_conv;
- PurplePluginProtocolInfo *prpl_info = NULL;
- gc = purple_conversation_get_gc(conv);
- who = g_object_get_data(G_OBJECT(w), "user_data");
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
- * May want to expand this to work similarly to menu_info_cb?
- if (prpl_info->get_cb_away != NULL)
- prpl_info->get_cb_away(gc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv)
PurpleConversation *conv = gtkconv->active_conv;
@@ -1578,7 +1625,7 @@
get_mark_for_user(PidginConversation *gtkconv, const char *who)
- GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml));
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->webview)); char *tmp = g_strconcat("user:", who, NULL);
GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp);
@@ -1589,6 +1636,8 @@
menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv)
+/* TODO WEBKIT: This doesn't work yet, of course... */ @@ -1599,6 +1648,7 @@
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0);
@@ -1607,12 +1657,13 @@
static GtkWidget *menu = NULL;
PurplePluginProtocolInfo *prpl_info = NULL;
PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+ PurpleAccount *account = purple_conversation_get_account(conv); PurpleBuddy *buddy = NULL;
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); * If a menu already exists, destroy it before creating a new one,
@@ -1621,7 +1672,7 @@
gtk_widget_destroy(menu);
- if (!strcmp(chat->nick, purple_normalize(conv->account, who)))
+ if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, who))) @@ -1686,18 +1737,8 @@
g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
- if (prpl_info && prpl_info->get_cb_away) {
- button = pidgin_new_item_from_stock(menu, _("Get Away Message"), PIDGIN_STOCK_AWAY,
- G_CALLBACK(menu_chat_get_away_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
- gtk_widget_set_sensitive(button, FALSE);
- g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
- if ((buddy = purple_find_buddy(conv->account, who)) != NULL)
+ if ((buddy = purple_find_buddy(account, who)) != NULL) button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE,
G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
@@ -1718,8 +1759,8 @@
- if (purple_account_is_connected(conv->account))
- pidgin_append_blist_node_proto_menu(menu, conv->account->gc,
+ if (purple_account_is_connected(account)) + pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), (PurpleBlistNode *)buddy);
pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy);
gtk_widget_show_all(menu);
@@ -1745,7 +1786,7 @@
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
account = purple_conversation_get_account(conv);
+ gc = purple_account_get_connection(account); model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -1781,7 +1822,7 @@
gtkchat = gtkconv->u.chat;
account = purple_conversation_get_account(conv);
+ gc = purple_account_get_connection(account); model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -1813,10 +1854,13 @@
chat_do_im(gtkconv, who);
} else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) {
/* Move to user's anchor */
+/* TODO WEBKIT: This isn't implemented yet. */ GtkTextMark *mark = get_mark_for_user(gtkconv, who);
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0);
} else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
GtkWidget *menu = create_chat_menu (conv, who, gc);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
@@ -1893,8 +1937,8 @@
- {gtkconv->entry, gtkconv->imhtml},
- {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry},
+ {gtkconv->entry, gtkconv->webview}, + {gtkconv->webview, chat ? gtkconv->u.chat->list : gtkconv->entry}, {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry},
@@ -1932,8 +1976,8 @@
/* If CTRL was held down... */
if (event->state & GDK_CONTROL_MASK) {
- case GDK_KEY_Page_Down:
- case GDK_KEY_KP_Page_Down:
if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1))
gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
@@ -1942,8 +1986,8 @@
- case GDK_KEY_KP_Page_Up:
if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1))
gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1);
@@ -1952,9 +1996,9 @@
- case GDK_KEY_ISO_Left_Tab:
if (event->state & GDK_SHIFT_MASK) {
move_to_next_unread_tab(gtkconv, FALSE);
@@ -1964,20 +2008,20 @@
gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
(curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)));
if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
@@ -2001,13 +2045,13 @@
if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) {
infopane_entry_activate(gtkconv);
if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
@@ -2031,7 +2075,7 @@
/* If CTRL was held down... */
if (event->state & GDK_CONTROL_MASK) {
if (!gtkconv->send_history)
@@ -2082,7 +2126,7 @@
if (!gtkconv->send_history)
@@ -2135,9 +2179,9 @@
/* If neither CTRL nor ALT were held down... */
- case GDK_KEY_ISO_Left_Tab:
if (gtkconv->entry != entry)
@@ -2149,15 +2193,21 @@
- case GDK_KEY_KP_Page_Up:
+/* TODO WEBKIT: Write this. */ gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml));
- case GDK_KEY_Page_Down:
- case GDK_KEY_KP_Page_Down:
+/* TODO WEBKIT: Write this. */ gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml));
@@ -2200,26 +2250,26 @@
/* If we have a valid key for the conversation display, then exit */
if ((event->state & GDK_CONTROL_MASK) ||
- (event->keyval == GDK_KEY_F6) ||
- (event->keyval == GDK_KEY_F10) ||
- (event->keyval == GDK_KEY_Shift_L) ||
- (event->keyval == GDK_KEY_Shift_R) ||
- (event->keyval == GDK_KEY_Control_L) ||
- (event->keyval == GDK_KEY_Control_R) ||
- (event->keyval == GDK_KEY_Escape) ||
- (event->keyval == GDK_KEY_Up) ||
- (event->keyval == GDK_KEY_Down) ||
- (event->keyval == GDK_KEY_Left) ||
- (event->keyval == GDK_KEY_Right) ||
- (event->keyval == GDK_KEY_Page_Up) ||
- (event->keyval == GDK_KEY_KP_Page_Up) ||
- (event->keyval == GDK_KEY_Page_Down) ||
- (event->keyval == GDK_KEY_KP_Page_Down) ||
- (event->keyval == GDK_KEY_Home) ||
- (event->keyval == GDK_KEY_End) ||
- (event->keyval == GDK_KEY_Tab) ||
- (event->keyval == GDK_KEY_KP_Tab) ||
- (event->keyval == GDK_KEY_ISO_Left_Tab))
+ (event->keyval == GDK_F6) || + (event->keyval == GDK_F10) || + (event->keyval == GDK_Shift_L) || + (event->keyval == GDK_Shift_R) || + (event->keyval == GDK_Control_L) || + (event->keyval == GDK_Control_R) || + (event->keyval == GDK_Escape) || + (event->keyval == GDK_Up) || + (event->keyval == GDK_Down) || + (event->keyval == GDK_Left) || + (event->keyval == GDK_Right) || + (event->keyval == GDK_Page_Up) || + (event->keyval == GDK_KP_Page_Up) || + (event->keyval == GDK_Page_Down) || + (event->keyval == GDK_KP_Page_Down) || + (event->keyval == GDK_Home) || + (event->keyval == GDK_End) || + (event->keyval == GDK_Tab) || + (event->keyval == GDK_KP_Tab) || + (event->keyval == GDK_ISO_Left_Tab)) if (event->type == GDK_KEY_PRESS)
return conv_keypress_common(gtkconv, event);
@@ -2244,6 +2294,7 @@
PurpleConversation *old_conv;
const char *protocol_name;
+ PurpleConnectionFlags features; g_return_if_fail(conv != NULL);
@@ -2265,14 +2316,15 @@
gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
entry = GTK_IMHTML(gtkconv->entry);
- protocol_name = purple_account_get_protocol_name(conv->account);
+ protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); gtk_imhtml_set_protocol_name(entry, protocol_name);
- gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name);
- if (!(conv->features & PURPLE_CONNECTION_HTML))
+ /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ + features = purple_conversation_get_features(conv); + if (!(features & PURPLE_CONNECTION_HTML)) gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry));
- else if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO &&
- !(old_conv->features & PURPLE_CONNECTION_FORMATTING_WBFO))
+ else if (features & PURPLE_CONNECTION_FORMATTING_WBFO && + !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FORMATTING_WBFO)) /* The old conversation allowed formatting on parts of the
* buffer, but the new one only allows it on the whole
@@ -2312,12 +2364,12 @@
gtk_imhtml_toggle_fontface(entry, fontface);
- if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE))
+ if (!(features & PURPLE_CONNECTION_NO_FONTSIZE)) gtk_imhtml_font_set_size(entry, fontsize);
gtk_imhtml_toggle_forecolor(entry, forecolor);
- if (!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR))
+ if (!(features & PURPLE_CONNECTION_NO_BGCOLOR)) gtk_imhtml_toggle_backcolor(entry, backcolor);
gtk_imhtml_toggle_background(entry, background);
@@ -2335,7 +2387,7 @@
* here, we didn't call gtk_imhtml_clear_formatting() (because we want to
* preserve the formatting exactly as it is), so we have to do this now. */
gtk_imhtml_set_whole_buffer_formatting_only(entry,
- (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO));
+ (features & PURPLE_CONNECTION_FORMATTING_WBFO)); purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv);
@@ -2400,7 +2452,7 @@
/* We deleted all the text, so turn off typing. */
purple_conv_im_stop_send_typed_timeout(im);
- serv_send_typing(purple_conversation_get_gc(conv),
+ serv_send_typing(purple_conversation_get_connection(conv), purple_conversation_get_name(conv),
@@ -2450,7 +2502,8 @@
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
PurpleBuddy *b = purple_find_buddy(account, name);
- PurplePresence *p = purple_buddy_get_presence(b);
+ p = purple_buddy_get_presence(b); if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY))
if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE))
@@ -2564,7 +2617,7 @@
status = infopane_status = pidgin_conv_get_icon_stock(conv);
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *b = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *b = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b);
@@ -2585,7 +2638,7 @@
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) {
- emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL);
+ emblem = pidgin_create_prpl_icon(purple_conversation_get_account(gtkconv->active_conv), PIDGIN_PRPL_ICON_SMALL); @@ -2641,7 +2694,7 @@
gtkconv = PIDGIN_CONVERSATION(conv);
account = purple_conversation_get_account(conv);
- if (!(account && account->gc)) {
+ if (!(account && purple_account_get_connection(account))) { gtkconv->u.im->icon_timer = 0;
@@ -2686,7 +2739,7 @@
-start_anim(GtkWidget *widget, PidginConversation *gtkconv)
+start_anim(GtkObject *obj, PidginConversation *gtkconv) @@ -2848,18 +2901,18 @@
ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv)));
- buf = g_strdup_printf("%s.%s", purple_normalize(conv->account, conv->name), ext);
+ buf = g_strdup_printf("%s.%s", purple_normalize(purple_conversation_get_account(conv), purple_conversation_get_name(conv)), ext); purple_request_file(gtkconv, _("Save Icon"), buf, TRUE,
G_CALLBACK(saveicon_writefile_cb), NULL,
- conv->account, NULL, conv,
+ purple_conversation_get_account(conv), NULL, conv, -stop_anim(GtkWidget *widget, PidginConversation *gtkconv)
+stop_anim(GtkObject *obj, PidginConversation *gtkconv) if (gtkconv->u.im->icon_timer != 0)
g_source_remove(gtkconv->u.im->icon_timer);
@@ -2881,7 +2934,7 @@
-icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
+icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv) static GtkWidget *menu = NULL;
PurpleConversation *conv;
@@ -3075,14 +3128,13 @@
static GtkActionEntry menu_entries[] =
/* TODO: fill out tooltips... */
{ "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
{ "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
+ { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), NULL, NULL, G_CALLBACK(menu_join_chat_cb) }, { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
{ "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
{ "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
@@ -3127,6 +3179,7 @@
"<menubar name='Conversation'>"
"<menu action='ConversationMenu'>"
"<menuitem action='NewInstantMessage'/>"
+ "<menuitem action='JoinAChat'/>" "<menuitem action='Find'/>"
"<menuitem action='ViewLog'/>"
@@ -3168,86 +3221,6 @@
-static GtkItemFactoryEntry menu_items[] =
- /* Conversation menu */
- { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb,
- 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
- { N_("/Conversation/Join a _Chat..."), NULL, menu_join_chat_cb,
- 0, "<StockItem>", PIDGIN_STOCK_CHAT },
- { "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
- "<StockItem>", GTK_STOCK_FIND },
- { N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL },
- { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0,
- "<StockItem>", GTK_STOCK_SAVE_AS },
- { N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR },
- { "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Conversation/M_edia"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Conversation/Media/_Audio Call"), NULL, menu_initiate_media_call_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL },
- { N_("/Conversation/Media/_Video Call"), NULL, menu_initiate_media_call_cb, 1,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
- { N_("/Conversation/Media/Audio\\/Video _Call"), NULL, menu_initiate_media_call_cb, 2,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
- { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE },
- { N_("/Conversation/Get _Attention"), NULL, menu_get_attention_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION },
- { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb,
- { N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
- { N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0,
- { N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL },
- { "/Conversation/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Conversation/Al_ias..."), NULL, menu_alias_cb, 0,
- { N_("/Conversation/_Block..."), NULL, menu_block_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_BLOCK },
- { N_("/Conversation/_Unblock..."), NULL, menu_unblock_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_UNBLOCK },
- { N_("/Conversation/_Add..."), NULL, menu_add_remove_cb, 0,
- "<StockItem>", GTK_STOCK_ADD },
- { N_("/Conversation/_Remove..."), NULL, menu_add_remove_cb, 0,
- "<StockItem>", GTK_STOCK_REMOVE },
- { "/Conversation/sep3", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Conversation/Insert Lin_k..."), NULL, menu_insert_link_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_LINK },
- { N_("/Conversation/Insert Imag_e..."), NULL, menu_insert_image_cb, 0,
- "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE },
- { "/Conversation/sep4", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0,
- "<StockItem>", GTK_STOCK_CLOSE },
- { N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL },
- { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL },
- { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
- { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
- { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
- { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
sound_method_pref_changed_cb(const char *name, PurplePrefType type,
gconstpointer value, gpointer data)
@@ -3278,21 +3251,23 @@
PurpleConversation *conv;
+ PurpleAccount *account; PurpleBlistNode *node = NULL;
PurpleBuddy *buddy = NULL;
conv = gtkconv->active_conv;
+ account = purple_conversation_get_account(conv); if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- chat = purple_blist_find_chat(conv->account, conv->name);
- if ((chat == NULL) && (gtkconv->imhtml != NULL)) {
- chat = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat");
- if ((chat == NULL) && (gtkconv->imhtml != NULL)) {
+ chat = purple_blist_find_chat(account, purple_conversation_get_name(conv)); + if ((chat == NULL) && (gtkconv->webview != NULL)) { + chat = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); + if ((chat == NULL) && (gtkconv->webview != NULL)) { PurpleAccount *account = purple_conversation_get_account(conv);
PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account));
@@ -3307,30 +3282,30 @@
g_hash_table_replace(components, g_strdup("channel"),
g_strdup(purple_conversation_get_name(conv)));
- chat = purple_chat_new(conv->account, NULL, components);
+ chat = purple_chat_new(account, NULL, components); purple_blist_node_set_flags((PurpleBlistNode *)chat,
PURPLE_BLIST_NODE_FLAG_NO_SAVE);
- g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_chat",
+ g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_chat", chat, (GDestroyNotify)purple_blist_remove_chat);
- if (!purple_account_is_connected(conv->account))
+ if (!purple_account_is_connected(account)) - buddy = purple_find_buddy(conv->account, conv->name);
+ buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle
* removing "isolated" buddy nodes well */
if (purple_version_check(2, 0, 2) == NULL) {
- if ((buddy == NULL) && (gtkconv->imhtml != NULL)) {
- buddy = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy");
+ if ((buddy == NULL) && (gtkconv->webview != NULL)) { + buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); - if ((buddy == NULL) && (gtkconv->imhtml != NULL)) {
- buddy = purple_buddy_new(conv->account, conv->name, NULL);
+ if ((buddy == NULL) && (gtkconv->webview != NULL)) { + buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL); purple_blist_node_set_flags((PurpleBlistNode *)buddy,
PURPLE_BLIST_NODE_FLAG_NO_SAVE);
- g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy",
+ g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_buddy", buddy, (GDestroyNotify)purple_buddy_destroy);
@@ -3349,8 +3324,8 @@
- if (purple_account_is_connected(conv->account))
- pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node);
+ if (purple_account_is_connected(account)) + pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), node); pidgin_append_blist_node_extended_menu(menu, node);
@@ -3402,7 +3377,7 @@
gtk_action_set_sensitive(win->video_call,
caps & PURPLE_MEDIA_CAPS_VIDEO
- gtk_action_set_sensitive(win->audio_video_call,
+ gtk_action_set_sensitive(win->audio_video_call, caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
} else if (purple_conversation_get_type(conv)
@@ -3420,12 +3395,65 @@
+regenerate_attention_items(PidginWindow *win) + PurpleConversation *conv; + PurplePlugin *prpl = NULL; + PurplePluginProtocolInfo *prpl_info = NULL; + conv = pidgin_conv_window_get_active_conversation(win); + /* Remove the previous entries */ + gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.get_attention), NULL); + pc = purple_conversation_get_connection(conv); + prpl = purple_connection_get_prpl(pc); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_attention_types)) { + list = prpl_info->get_attention_types(purple_connection_get_account(pc)); + /* Multiple attention types */ + if (list && list->next) { + PurpleAttentionType *type; + menuitem = gtk_menu_item_new_with_label(purple_attention_type_get_name(type)); + g_object_set_data(G_OBJECT(menuitem), "index", GINT_TO_POINTER(index)); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(menu_get_attention_cb), + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + list = g_list_delete_link(list, list); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.get_attention), menu); + gtk_widget_show_all(menu); regenerate_options_items(PidginWindow *win)
PidginConversation *gtkconv;
-#if GTK_CHECK_VERSION(2,6,0)
gtkconv = pidgin_conv_window_get_active_gtkconv(win);
@@ -3433,10 +3461,6 @@
"/Conversation/ConversationMenu/MoreMenu");
gtk_widget_show(more_menu);
menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu));
- gtkconv = pidgin_conv_window_get_active_gtkconv(win);
- menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More"));
/* Remove the previous entries */
for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
@@ -3492,12 +3516,8 @@
action_items = g_list_delete_link(action_items, action_items);
-#if GTK_CHECK_VERSION(2,6,0)
item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu");
menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
- menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options"));
list = purple_conversation_get_extended_menu(conv);
@@ -3521,6 +3541,7 @@
regenerate_media_items(win);
regenerate_options_items(win);
regenerate_plugins_items(win);
+ regenerate_attention_items(win); /* The following are to make sure the 'More' submenu is not regenerated every time
* the focus shifts from 'Conversations' to some other menu and back. */
@@ -3606,9 +3627,9 @@
gtk_ui_manager_get_action(win->menu.ui,
"/Conversation/ConversationMenu/SendFile");
- g_object_set_data(G_OBJECT(win->window), "get_attention",
+ win->menu.get_attention = gtk_ui_manager_get_action(win->menu.ui,
- "/Conversation/ConversationMenu/GetAttention"));
+ "/Conversation/ConversationMenu/GetAttention"); gtk_ui_manager_get_action(win->menu.ui,
@@ -3718,7 +3739,7 @@
time(NULL) > purple_conv_im_get_type_again(im)))
- timeout = serv_send_typing(purple_conversation_get_gc(conv),
+ timeout = serv_send_typing(purple_conversation_get_connection(conv), purple_conversation_get_name(conv),
purple_conv_im_set_type_again(im, timeout);
@@ -3754,10 +3775,10 @@
if (gtkwin->menu.typing_icon == NULL) {
- gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
- pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray),
- gtkwin->menu.typing_icon,
- _("User is typing..."));
+ gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); + pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray), + gtkwin->menu.typing_icon, + _("User is typing...")); gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU);
@@ -3769,6 +3790,8 @@
update_typing_message(PidginConversation *gtkconv, const char *message)
+ /* TODO WEBKIT: this is not handled at all */ GtkTextMark *stmark, *enmark;
@@ -3801,6 +3824,7 @@
gtk_text_buffer_get_end_iter(buffer, &iter);
gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE);
@@ -3857,10 +3881,9 @@
if (win->menu.send_to == NULL)
- if (!(b = purple_find_buddy(account, conv->name)))
+ if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
gtk_widget_show(win->menu.send_to);
menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
@@ -3882,7 +3905,6 @@
@@ -3992,7 +4014,6 @@
generate_send_to_items(PidginWindow *win)
GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
@@ -4019,8 +4040,8 @@
- if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM) {
- buds = purple_find_buddies(gtkconv->active_conv->account, gtkconv->active_conv->name);
+ if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM) { + buds = purple_find_buddies(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); @@ -4044,7 +4065,8 @@
account = purple_buddy_get_account(buddy);
- if (purple_account_is_connected(account) || account == gtkconv->active_conv->account)
+ /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */ + if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/) /* Use the PurplePresence to get unique buddies. */
PurplePresence *presence = purple_buddy_get_presence(buddy);
@@ -4077,7 +4099,6 @@
gtk_widget_set_sensitive(win->menu.send_to, FALSE);
update_send_to_selection(win);
@@ -4104,10 +4125,11 @@
deleting_chat_buddy_cb(PurpleConvChatBuddy *cb)
- GtkTreeRowReference *ref = cb->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); gtk_tree_row_reference_free(ref);
+ purple_conv_chat_cb_set_ui_data(cb, NULL); @@ -4126,20 +4148,21 @@
- gchar *tmp, *alias_key, *name, *alias;
+ const gchar *name, *alias; + gchar *tmp, *alias_key; PurpleConvChatBuddyFlags flags;
+ alias = purple_conv_chat_cb_get_alias(cb); + name = purple_conv_chat_cb_get_name(cb); + flags = purple_conv_chat_cb_get_flags(cb); chat = PURPLE_CONV_CHAT(conv);
gtkconv = PIDGIN_CONVERSATION(conv);
gtkchat = gtkconv->u.chat;
- gc = purple_conversation_get_gc(conv);
- if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)))
+ gc = purple_conversation_get_connection(conv); + if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
@@ -4147,20 +4170,23 @@
stock = get_chat_buddy_status_icon(chat, name, flags);
- if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name)))
+ if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name)))
+ is_buddy = purple_conv_chat_cb_is_buddy(cb); tmp = g_utf8_casefold(alias, -1);
alias_key = g_utf8_collate_key(tmp, -1);
+ /* TODO WEBKIT: No tags in webkit stuff, yet. */ GtkTextTag *tag = gtk_text_tag_table_lookup(
- gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->imhtml)->text_buffer),
+ gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->webview)->text_buffer), g_object_get(tag, "foreground-gdk", &color, NULL);
if ((tag = get_buddy_tag(conv, name, 0, FALSE)))
@@ -4188,13 +4214,13 @@
CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
- GtkTreeRowReference *ref = cb->ui_data;
+ if (purple_conv_chat_cb_get_ui_data(cb)) { + GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); gtk_tree_row_reference_free(ref);
newpath = gtk_tree_model_get_path(tm, &iter);
- cb->ui_data = gtk_tree_row_reference_new(tm, newpath);
+ purple_conv_chat_cb_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath)); gtk_tree_path_free(newpath);
@@ -4224,7 +4250,7 @@
tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial,
- GList **matches, char *name)
+ GList **matches, const char *name) memcpy(nick_partial, name, entered_bytes);
if (purple_utf8_strcasecmp(nick_partial, entered))
@@ -4346,7 +4372,7 @@
for (; l != NULL; l = l->next) {
tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial,
- &matches, ((PurpleConvChatBuddy *)l->data)->name);
+ &matches, purple_conv_chat_cb_get_name((PurpleConvChatBuddy *)l->data)); @@ -4444,9 +4470,9 @@
const char *current_topic;
- gc = purple_conversation_get_gc(conv);
- if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)))
+ gc = purple_conversation_get_connection(conv); + if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) if(prpl_info->set_chat_topic == NULL)
@@ -4521,6 +4547,7 @@
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+ PurpleAccount *account = purple_conversation_get_account(conv); @@ -4535,23 +4562,23 @@
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
- normalized_name = g_strdup(purple_normalize(conv->account, buddy->name));
+ normalized_name = g_strdup(purple_normalize(account, purple_buddy_get_name(buddy))); gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
- if (!strcmp(normalized_name, purple_normalize(conv->account, name))) {
+ if (!strcmp(normalized_name, purple_normalize(account, name))) { const char *alias = name;
- if (strcmp(chat->nick, purple_normalize(conv->account, name))) {
+ if (strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, name))) { /* This user is not me, so look into updating the alias. */
- if ((buddy2 = purple_find_buddy(conv->account, name)) != NULL) {
+ if ((buddy2 = purple_find_buddy(account, name)) != NULL) { alias = purple_buddy_get_contact_alias(buddy2);
@@ -4586,10 +4613,10 @@
g_return_if_fail(node != NULL);
g_return_if_fail(conv != NULL);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv); g_return_if_fail(gc != NULL);
- g_return_if_fail(gc->prpl != NULL);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ g_return_if_fail(purple_connection_get_prpl(gc) != NULL); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)
@@ -4609,7 +4636,7 @@
else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
update_chat_alias((PurpleBuddy *)node, conv, gc, prpl_info);
else if (PURPLE_BLIST_NODE_IS_CHAT(node) &&
- purple_conversation_get_account(conv) == ((PurpleChat*)node)->account)
+ purple_conversation_get_account(conv) == purple_chat_get_account((PurpleChat*)node)) if (old_alias == NULL || g_utf8_collate(old_alias, purple_conversation_get_title(conv)) == 0)
pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE);
@@ -4638,14 +4665,14 @@
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
- normalized_name = g_strdup(purple_normalize(conv->account, buddy->name));
+ normalized_name = g_strdup(purple_normalize(purple_conversation_get_account(conv), purple_buddy_get_name(buddy))); gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
- if (!strcmp(normalized_name, purple_normalize(conv->account, name))) {
+ if (!strcmp(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) { gtk_list_store_set(GTK_LIST_STORE(model), &iter,
CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1);
@@ -4724,21 +4751,12 @@
int pad_top, pad_inside, pad_bottom;
+ int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height); + int max_height = total_height / 2; int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
- GtkAllocation imhtml_allocation;
- GtkAllocation entry_allocation;
- GtkAllocation lower_hbox_allocation;
- gtk_widget_get_allocation(gtkconv->imhtml, &imhtml_allocation);
- gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
- gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
- total_height = imhtml_allocation.height + entry_allocation.height;
- max_height = total_height / 2;
pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
@@ -4772,15 +4790,12 @@
height += 2 * focus_width;
- diff = height - entry_allocation.height;
+ diff = height - gtkconv->entry->allocation.height; if (ABS(diff) < oneline.height / 2)
- purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
- diff + lower_hbox_allocation.height, min_lines, diff);
gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
- diff + lower_hbox_allocation.height);
+ diff + gtkconv->lower_hbox->allocation.height); @@ -4808,8 +4823,8 @@
setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox)
PurpleConversation *conv = gtkconv->active_conv;
- PurpleConnection *gc = purple_conversation_get_gc(conv);
- PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ PurpleConnection *gc = purple_conversation_get_connection(conv); + PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info->options & OPT_PROTO_CHAT_TOPIC)
@@ -4827,7 +4842,7 @@
if(prpl_info->set_chat_topic == NULL) {
gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
- g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate",
+ g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate", G_CALLBACK(topic_callback), gtkconv);
@@ -4850,7 +4865,7 @@
PurpleAccount *account = purple_conversation_get_account(conv);
- if (account->gc == NULL)
+ if (purple_account_get_connection(account) == NULL) if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
@@ -4858,8 +4873,8 @@
gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
- node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who));
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account))); + node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), who)); if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME))
pidgin_blist_draw_tooltip(node, gtkconv->infopane);
@@ -4960,7 +4975,7 @@
- gtk_box_pack_start(GTK_BOX(lbox),
+ gtk_box_pack_start(GTK_BOX(lbox), pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1),
@@ -4974,15 +4989,15 @@
conv = gtkconv->active_conv;
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
- node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name));
+ node = (PurpleBlistNode*)(purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); - node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat");
+ node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); - node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name));
+ node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */
- node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy");
+ node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); @@ -4997,8 +5012,8 @@
gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
- gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml));
- gtk_widget_hide(gtkconv->quickfind.container);
+ webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview)); + gtk_widget_hide_all(gtkconv->quickfind.container); gtk_widget_grab_focus(gtkconv->entry);
@@ -5008,9 +5023,9 @@
quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv)
- if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) {
+ if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) { gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
@@ -5020,7 +5035,7 @@
gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col);
pidgin_conv_end_quickfind(gtkconv);
@@ -5064,16 +5079,185 @@
+replace_header_tokens(PurpleConversation *conv, const char *text) + PurpleAccount *account = purple_conversation_get_account(conv); + const char *cur = text; + const char *prev = cur; + if (text == NULL || *text == '\0') + str = g_string_new(NULL); + while ((cur = strchr(cur, '%'))) { + const char *replace = NULL; + const char *fin = NULL; + if (g_str_has_prefix(cur, "%chatName%")) { + replace = purple_conversation_get_name(conv); + } else if (g_str_has_prefix(cur, "%sourceName%")) { + replace = purple_account_get_alias(account); + replace = purple_account_get_username(account); + } else if (g_str_has_prefix(cur, "%destinationName%")) { + PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); + replace = purple_buddy_get_alias(buddy); + replace = purple_conversation_get_name(conv); + } else if (g_str_has_prefix(cur, "%incomingIconPath%")) { + PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); + replace = purple_buddy_icon_get_full_path(icon); + } else if (g_str_has_prefix(cur, "%outgoingIconPath%")) { + replace = purple_account_get_buddy_icon_path(account); + } else if (g_str_has_prefix(cur, "%timeOpened")) { + const char *tmp = cur + strlen("%timeOpened"); + end = strstr(tmp, "}%"); + if (!end) /* Invalid string */ + format = g_strndup(tmp, end - tmp); + replace = purple_utf8_strftime(format ? format : "%X", NULL); + } else if (g_str_has_prefix(cur, "%dateOpened%")) { + replace = purple_date_format_short(NULL); + /* Here we have a replacement to make */ + g_string_append_len(str, prev, cur - prev); + g_string_append(str, replace); + /* And update the pointers */ + prev = cur = strchr(cur + 1, '%') + 1; + g_string_append(str, prev); + return g_string_free(str, FALSE); +replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer) + text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN); + ms = g_strsplit(text, "%@", 6); + if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) { + str = g_string_new(NULL); + g_string_append(str, ms[0]); + g_string_append(str, "file://"); + path = pidgin_conversation_theme_get_template_path(theme); + g_string_append(str, path); + g_string_append(str, ms[1]); + text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS); + g_string_append(str, text); + g_string_append(str, ms[2]); + g_string_append(str, "file://"); + path = pidgin_conversation_theme_get_css_path(theme); + g_string_append(str, path); + g_string_append(str, ms[3]); + g_string_append(str, header); + g_string_append(str, ms[4]); + g_string_append(str, footer); + g_string_append(str, ms[5]); + return g_string_free(str, FALSE); +set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme) + WebKitWebSettings *settings; + g_object_get(G_OBJECT(webview), "settings", &settings, NULL); + val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE); + if (val && G_VALUE_HOLDS_STRING(val)) + g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL); + val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE); + if (val && G_VALUE_HOLDS_INT(val)) + g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL); + val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE); + if (val && G_VALUE_HOLDS_BOOLEAN(val)) + /* this does not work :( */ + webkit_web_view_set_transparent(webview, g_value_get_boolean(val)); +conv_variant_changed_cb(GObject *gobject, GParamSpec *pspec, gpointer user_data) + PidginConversation *gtkconv = user_data; + path = pidgin_conversation_theme_get_css_path(PIDGIN_CONV_THEME(gobject)); + js = g_strdup_printf("setStylesheet(\"mainStyle\", \"file://%s\");", path); + gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), js); setup_common_pane(PidginConversation *gtkconv)
- GtkWidget *vbox, *frame, *imhtml_sw, *event_box;
+ GtkWidget *vbox, *frame, *webview_sw, *event_box; PurpleConversation *conv = gtkconv->active_conv;
- gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
+ gboolean chat = (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT); /* Setup the top part of the pane */
vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -5163,9 +5347,41 @@
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL);
g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
- /* Setup the gtkimhtml widget */
- frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw);
- gtk_widget_set_size_request(gtkconv->imhtml, -1, 0);
+ /* Setup the webkit widget */ + frame = pidgin_create_webview(FALSE, >kconv->webview, NULL, &webview_sw); + gtk_widget_set_size_request(gtkconv->webview, -1, 0); + header = replace_header_tokens(conv, + pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER)); + footer = replace_header_tokens(conv, + pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER)); + template = replace_template_tokens(gtkconv->theme, header, footer); + if (template != NULL) { + purple_debug_info("webkit", "template: %s\n", template); + set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme); + basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme); + baseuri = g_strdup_printf("file://%s", basedir); + webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template, "text/html", "UTF-8", baseuri); + gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), "document.getElementById('Chat').className = 'groupchat'"); + g_signal_connect(G_OBJECT(gtkconv->theme), "notify::variant", + G_CALLBACK(conv_variant_changed_cb), gtkconv); @@ -5183,19 +5399,16 @@
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
- gtk_widget_show(frame);
- gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
- gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE);
- g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv);
- g_object_set(G_OBJECT(imhtml_sw), "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL);
- g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
+ gtk_widget_show_all(frame); + gtk_widget_set_name(gtkconv->webview, "pidgin_conv_webview"); + g_object_set_data(G_OBJECT(gtkconv->webview), "gtkconv", gtkconv); + g_signal_connect_after(G_OBJECT(gtkconv->webview), "button_press_event", G_CALLBACK(entry_stop_rclick_cb), NULL);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "key_press_event", G_CALLBACK(refocus_entry_cb), gtkconv);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "key_release_event", G_CALLBACK(refocus_entry_cb), gtkconv);
pidgin_conv_setup_quickfind(gtkconv, vbox);
@@ -5211,7 +5424,7 @@
gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
- purple_account_get_protocol_name(conv->account));
+ purple_account_get_protocol_name(purple_conversation_get_account(conv))); g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
G_CALLBACK(entry_popup_menu_cb), gtkconv);
@@ -5258,11 +5471,9 @@
PurpleAccount *convaccount = purple_conversation_get_account(conv);
PurpleConnection *gc = purple_account_get_connection(convaccount);
- PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
- GdkAtom target = gtk_selection_data_get_target(sd);
- const guchar *data = gtk_selection_data_get_data(sd);
- if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
+ PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; + if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) PurpleBlistNode *n = NULL;
@@ -5270,7 +5481,7 @@
PurpleAccount *buddyaccount;
- n = *(PurpleBlistNode **) data;
+ n = *(PurpleBlistNode **)sd->data; if (PURPLE_BLIST_NODE_IS_CONTACT(n))
b = purple_contact_get_priority_buddy((PurpleContact*)n);
@@ -5318,17 +5529,16 @@
pidgin_conv_window_switch_gtkconv(win, gtkconv);
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
- else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); + else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) PidginConversation *gtkconv;
- if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
+ if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, &protocol, &username, NULL))
@@ -5359,14 +5569,12 @@
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
- else if (target == gdk_atom_intern("text/uri-list", FALSE)) {
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); + else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) { if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); gtk_drag_finish(dc, FALSE, FALSE, t);
@@ -5383,7 +5591,7 @@
static PidginConversation *
pidgin_conv_find_gtkconv(PurpleConversation * conv)
- PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *bud = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); PurpleBlistNode *cn, *bn;
@@ -5397,9 +5605,9 @@
for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) {
PurpleBuddy *b = PURPLE_BUDDY(bn);
PurpleConversation *conv;
- if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) {
+ if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(b), purple_buddy_get_account(b)))) { + if (PIDGIN_CONVERSATION(conv)) + return PIDGIN_CONVERSATION(conv); @@ -5441,6 +5649,8 @@
static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv)
static PangoFontDescription *font_desc = NULL;
static GdkColor *color = NULL;
static gboolean enable = TRUE;
@@ -5471,6 +5681,7 @@
g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv);
/**************************************************************************
@@ -5480,14 +5691,14 @@
private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
PidginConversation *gtkconv;
PurpleConversationType conv_type = purple_conversation_get_type(conv);
PurpleBlistNode *convnode;
if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
- conv->ui_data = gtkconv;
+ purple_conversation_set_ui_data(conv, gtkconv); if (!g_list_find(gtkconv->convs, conv))
gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
pidgin_conv_switch_active_conversation(conv);
@@ -5495,7 +5706,7 @@
gtkconv = g_new0(PidginConversation, 1);
- conv->ui_data = gtkconv;
+ purple_conversation_set_ui_data(conv, gtkconv); gtkconv->active_conv = conv;
gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
gtkconv->send_history = g_list_append(NULL, NULL);
@@ -5506,6 +5717,11 @@
gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
gtkconv->unseen_count = 0;
+ theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); + theme = purple_theme_manager_find_theme("Default", "conversation"); + gtkconv->theme = PIDGIN_CONV_THEME(g_object_ref(theme)); + gtkconv->last_flags = 0; if (conv_type == PURPLE_CONV_TYPE_IM) {
gtkconv->u.im = g_malloc0(sizeof(PidginImPane));
@@ -5514,9 +5730,6 @@
pane = setup_common_pane(gtkconv);
- gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml),
- gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE);
if (conv_type == PURPLE_CONV_TYPE_CHAT)
@@ -5524,7 +5737,7 @@
+ purple_conversation_set_ui_data(conv, NULL); @@ -5539,7 +5752,7 @@
te, sizeof(te) / sizeof(GtkTargetEntry),
- gtk_drag_dest_set(gtkconv->imhtml, 0,
+ gtk_drag_dest_set(gtkconv->webview, 0, te, sizeof(te) / sizeof(GtkTargetEntry),
@@ -5551,12 +5764,12 @@
G_CALLBACK(ignore_middle_click), NULL);
g_signal_connect(G_OBJECT(pane), "drag_data_received",
G_CALLBACK(conv_dnd_recv), gtkconv);
- g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received",
+ g_signal_connect(G_OBJECT(gtkconv->webview), "drag_data_received", G_CALLBACK(conv_dnd_recv), gtkconv);
g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received",
G_CALLBACK(conv_dnd_recv), gtkconv);
- g_signal_connect(gtkconv->imhtml, "style-set", G_CALLBACK(set_typing_font), gtkconv);
+ g_signal_connect(gtkconv->webview, "style-set", G_CALLBACK(set_typing_font), gtkconv); /* Setup the container for the tab. */
gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -5569,11 +5782,9 @@
if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound"))
gtkconv->make_sound = TRUE;
- if (convnode != NULL &&
- (value = g_hash_table_lookup(convnode->settings, "enable-logging")) &&
- purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
- purple_conversation_set_logging(conv, purple_value_get_boolean(value));
+ if (convnode != NULL) { + gboolean logging = purple_blist_node_get_bool(convnode, "enable-logging"); + purple_conversation_set_logging(conv, logging); if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"))
@@ -5586,10 +5797,6 @@
gtk_widget_hide(gtkconv->infopane_hbox);
- gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
- purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
- gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
- purple_account_get_protocol_name(conv->account));
g_signal_connect_swapped(G_OBJECT(pane), "focus",
G_CALLBACK(gtk_widget_grab_focus),
@@ -5602,10 +5809,10 @@
if (nick_colors == NULL) {
nbr_nick_colors = NUM_NICK_COLORS;
- nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
- if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->webview)->base[GTK_STATE_NORMAL]); + if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) pidgin_themes_smiley_themeize_custom(gtkconv->entry);
@@ -5718,6 +5925,10 @@
g_source_remove(gtkconv->attach.timer);
+ g_object_disconnect(G_OBJECT(gtkconv->theme), "any_signal::notify", + conv_variant_changed_cb, gtkconv, NULL); + g_object_unref(gtkconv->theme); @@ -5745,6 +5956,7 @@
purple_conversation_write(conv, who, message, flags, mtime);
get_text_tag_color(GtkTextTag *tag)
@@ -5772,37 +5984,33 @@
GdkEventButton *btn_event = (GdkEventButton*) event;
PurpleConversation *conv = data;
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
/* strlen("BUDDY " or "HILIT ") == 6 */
- g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE);
+ g_return_val_if_fail((tag->name != NULL) + && (strlen(tag->name) > 6), FALSE); + buddyname = (tag->name) + 6; /* emit chat-nick-clicked signal */
if (event->type == GDK_BUTTON_PRESS) {
gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
pidgin_conversations_get_handle(), "chat-nick-clicked",
data, buddyname, btn_event->button));
- if (btn_event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
+ if (btn_event->button == 1 && + event->type == GDK_2BUTTON_PRESS) { chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
+ } else if (btn_event->button == 2 + && event->type == GDK_2BUTTON_PRESS) { + chat_do_info(PIDGIN_CONVERSATION(conv), buddyname); - } else if (btn_event->button == 2 && event->type == GDK_2BUTTON_PRESS) {
- chat_do_info(PIDGIN_CONVERSATION(conv), buddyname);
- } else if (btn_event->button == 3 && event->type == GDK_BUTTON_PRESS) {
+ } else if (btn_event->button == 3 + && event->type == GDK_BUTTON_PRESS) { /* we shouldn't display the popup
@@ -5812,7 +6020,7 @@
- purple_conversation_get_gc(conv);
+ purple_conversation_get_connection(conv); menu = create_chat_menu(conv, buddyname, gc);
@@ -5821,22 +6029,21 @@
/* Don't propagate the event any further */
static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag,
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
@@ -5870,8 +6077,11 @@
static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime)
struct tm *tm = localtime(&mtime);
@@ -5917,6 +6127,111 @@
+ PurpleConversation *conv, + PurpleMessageFlags flags, + const char *cur = text; + const char *prev = cur; + str = g_string_new(NULL); + while ((cur = strchr(cur, '%'))) { + const char *replace = NULL; + const char *fin = NULL; + if (g_str_has_prefix(cur, "%message%")) { + } else if (g_str_has_prefix(cur, "%messageClasses%")) { + replace = flags & PURPLE_MESSAGE_SEND ? "outgoing" : + flags & PURPLE_MESSAGE_RECV ? "incoming" : "event"; + } else if (g_str_has_prefix(cur, "%time")) { + const char *tmp = cur + strlen("%time"); + end = strstr(tmp, "}%"); + if (!end) /* Invalid string */ + format = g_strndup(tmp, end - tmp); + replace = purple_utf8_strftime(format ? format : "%X", NULL); + } else if (g_str_has_prefix(cur, "%shortTime%")) { + replace = purple_utf8_strftime("%H:%M", NULL); + } else if (g_str_has_prefix(cur, "%userIconPath%")) { + if (flags & PURPLE_MESSAGE_SEND) { + if (purple_account_get_bool(purple_conversation_get_account(conv), "use-global-buddyicon", TRUE)) { + replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"); + PurpleStoredImage *img = purple_buddy_icons_find_account_icon(purple_conversation_get_account(conv)); + replace = purple_imgstore_get_filename(img); + if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { + replace = g_build_filename("Outgoing", "buddy_icon.png", NULL); + } else if (flags & PURPLE_MESSAGE_RECV) { + PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); + replace = purple_buddy_icon_get_full_path(icon); + if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { + replace = g_build_filename("Incoming", "buddy_icon.png", NULL); + } else if (g_str_has_prefix(cur, "%senderScreenName%")) { + } else if (g_str_has_prefix(cur, "%sender%")) { + } else if (g_str_has_prefix(cur, "%service%")) { + replace = purple_account_get_protocol_name(purple_conversation_get_account(conv)); + } else if (g_str_has_prefix(cur, "%messageDirection%")) { + replace = purple_markup_is_rtl(message) ? "rtl" : "ltr"; + /* Here we have a replacement to make */ + g_string_append_len(str, prev, cur - prev); + g_string_append(str, replace); + /* And update the pointers */ + prev = cur = strchr(cur + 1, '%') + 1; + g_string_append(str, prev); + return g_string_free(str, FALSE); pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
@@ -5926,23 +6241,31 @@
PidginConversation *gtkconv;
int gtk_font_options = 0;
int gtk_font_options_all = 0;
- int max_scrollback_lines;
PurpleConversationType type;
gboolean is_rtl_message = FALSE;
+ const char *message_html; + PurpleMessageFlags old_flags; + const char *func = "appendMessage"; g_return_if_fail(conv != NULL);
gtkconv = PIDGIN_CONVERSATION(conv);
@@ -5999,56 +6322,39 @@
length = strlen(displaying) + 1;
- /* Awful hack to work around GtkIMHtml's inefficient rendering of messages with lots of formatting changes.
- * If a message has over 100 '<' characters, strip formatting before appending it. Hopefully nobody actually
- * needs that much formatting, anyway.
- for (bracket = strchr(displaying, '<'); bracket && *(bracket + 1); bracket = strchr(bracket + 1, '<'))
- char *tmp = displaying;
- displaying = purple_markup_strip_html(tmp);
- line_count = gtk_text_buffer_get_line_count(
- gtk_text_view_get_buffer(GTK_TEXT_VIEW(
- max_scrollback_lines = purple_prefs_get_int(
- PIDGIN_PREFS_ROOT "/conversations/scrollback_lines");
- /* If we're sitting at more than 100 lines more than the
- max scrollback, trim down to max scrollback */
- if (max_scrollback_lines > 0
- && line_count > (max_scrollback_lines + 100)) {
- GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(
- GTK_TEXT_VIEW(gtkconv->imhtml));
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter(text_buffer, &start);
- gtk_text_buffer_get_iter_at_line(text_buffer, &end,
- (line_count - max_scrollback_lines));
- gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end);
- if (type == PURPLE_CONV_TYPE_CHAT)
- /* Create anchor for user */
- char *tmp = g_strconcat("user:", name, NULL);
- gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), &iter);
- gtk_text_buffer_create_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)),
- if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling"))
- gtk_font_options_all |= GTK_IMHTML_USE_SMOOTHSCROLLING;
- if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
+ old_flags = gtkconv->last_flags; + if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) { + message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT); + func = "appendNextMessage"; + } else if (flags & PURPLE_MESSAGE_SEND) { + message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT); + } else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) { + message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT); + func = "appendNextMessage"; + } else if (flags & PURPLE_MESSAGE_RECV) { + message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT); + message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS); + gtkconv->last_flags = flags; + smileyed = smiley_parse_markup(message, purple_account_get_protocol_id(account)); + msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime); + escape = gtk_webview_quote_js_string(msg); + script = g_strdup_printf("%s(%s)", func, escape); + purple_debug_info("webkit", "JS: %s\n", script); + gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script); + /* if the buffer is not empty add a <br> */ + if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview))) + gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />"); /* First message in a conversation. */
if (gtkconv->newday == 0)
@@ -6091,40 +6397,40 @@
gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING;
/* this is gonna crash one day, I can feel it. */
- if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(conv->account)))->options &
+ if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(purple_conversation_get_account(conv))))->options & OPT_PROTO_USE_POINTSIZE) {
gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
- if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) /* We want to see our own smileys. Need to revert it after send*/
- pidgin_themes_smiley_themeize_custom(gtkconv->imhtml);
+ pidgin_themes_smiley_themeize_custom(gtkconv->webview); /* TODO: These colors should not be hardcoded so log.c can use them */
if (flags & PURPLE_MESSAGE_RAW) {
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), message); } else if (flags & PURPLE_MESSAGE_SYSTEM) {
g_snprintf(buf2, sizeof(buf2),
- "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT>",
+ "<font %s><font size=\"2\"><span class='timestamp'>%s</span></font><b>%s</b></font>", sml_attrib ? sml_attrib : "", mdate, displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); } else if (flags & PURPLE_MESSAGE_ERROR) {
g_snprintf(buf2, sizeof(buf2),
- "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT></FONT>",
+ "<font color=\"#ff0000\"><font %s><font size=\"2\"><span class='timestamp'>%s</span> </font><b>%s</b></font></font>", sml_attrib ? sml_attrib : "", mdate, displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); } else if (flags & PURPLE_MESSAGE_NO_LOG) {
g_snprintf(buf2, BUF_LONG,
- "<B><FONT %s COLOR=\"#777777\">%s</FONT></B>",
+ "<b><font %s color=\"#777777\">%s</font></b>", sml_attrib ? sml_attrib : "", displaying);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); char *new_message = g_memdup(displaying, length);
char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup(""));
@@ -6134,11 +6440,6 @@
const char *tagname = NULL;
- GtkTextIter start, end;
- GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer;
/* Enforce direction on alias */
str_embed_direction_chars(&alias_escaped);
@@ -6199,55 +6500,41 @@
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname);
tag = get_buddy_tag(conv, name, flags, TRUE);
if (GTK_IMHTML(gtkconv->imhtml)->show_comments) {
/* The color for the timestamp has to be set in the font-tags, unfortunately.
* Applying the nick-tag to timestamps would work, but that can make it
* bold. I thought applying the "comment" tag again, which has "weight" set
* to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So
* this will have to do. I don't terribly like it. -- sadrul */
- const char *color = get_text_tag_color(tag);
+ /* const char *color = get_text_tag_color(tag); */ g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>",
color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
- gtk_text_buffer_get_end_iter(buffer, &end);
- mark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE);
- g_snprintf(buf2, BUF_LONG, "<FONT %s>%s</FONT> ", sml_attrib ? sml_attrib : "", str);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
- gtk_text_buffer_get_end_iter(buffer, &end);
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- gtk_text_buffer_apply_tag(buffer, tag, &start, &end);
- gtk_text_buffer_delete_mark(buffer, mark);
+ gtk_webview_append_html (GTK_WEBVIEW(gtkconv->webview), buf2); + g_snprintf(buf2, BUF_LONG, "<font %s>%s</font> ", sml_attrib ? sml_attrib : "", str); + gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2);
char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : "");
- int pre_len = strlen(pre);
- int post_len = strlen(post);
- with_font_tag = g_malloc(length + pre_len + post_len + 1);
- strcpy(with_font_tag, pre);
- memcpy(with_font_tag + pre_len, new_message, length);
- strcpy(with_font_tag + pre_len + length, post);
- length += pre_len + post_len;
+ with_font_tag = g_strdup_printf("%s%s%s", pre, new_message, post); with_font_tag = g_memdup(new_message, length);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml),
- with_font_tag, gtk_font_options | gtk_font_options_all);
+ gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), @@ -6256,6 +6543,8 @@
/* Tab highlighting stuff */
if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv))
@@ -6274,11 +6563,13 @@
gtkconv_set_unseen(gtkconv, unseen);
- if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
+ if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) /* Restore the smiley-data */
- pidgin_themes_smiley_themeize(gtkconv->imhtml);
+ pidgin_themes_smiley_themeize(gtkconv->webview); purple_signal_emit(pidgin_conversations_get_handle(),
(type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
@@ -6289,7 +6580,7 @@
static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter)
- GtkTreeRowReference *ref = cb->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); @@ -6373,23 +6664,23 @@
if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
- old_cbuddy = purple_conv_chat_cb_find(chat, old_name);
- if (get_iter_from_chatbuddy(old_cbuddy, &iter)) {
- GtkTreeRowReference *ref = old_cbuddy->ui_data;
- gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
- gtk_tree_row_reference_free(ref);
- old_cbuddy->ui_data = NULL;
if ((tag = get_buddy_tag(conv, old_name, 0, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE)))
g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
+ old_cbuddy = purple_conv_chat_cb_find(chat, old_name); + if (get_iter_from_chatbuddy(old_cbuddy, &iter)) { + GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(old_cbuddy); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + gtk_tree_row_reference_free(ref); + purple_conv_chat_cb_set_ui_data(old_cbuddy, NULL); g_return_if_fail(new_alias != NULL);
new_cbuddy = purple_conv_chat_cb_find(chat, new_name);
@@ -6473,10 +6764,10 @@
cbuddy = purple_conv_chat_cb_find(chat, user);
if (get_iter_from_chatbuddy(cbuddy, &iter)) {
- GtkTreeRowReference *ref = cbuddy->ui_data;
+ GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cbuddy); gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
gtk_tree_row_reference_free(ref);
- cbuddy->ui_data = NULL;
+ purple_conv_chat_cb_set_ui_data(cbuddy, NULL); @@ -6523,6 +6814,13 @@
+add_custom_smiley_for_webview(GtkWebView *webview, const char *sml, const char *smile) + /* TODO WEBKIT: Smileys need to be added to webkit stuff */ pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote)
PidginConversation *gtkconv;
@@ -6539,7 +6837,7 @@
/* If possible add this smiley to the current theme.
* The addition is only temporary: custom smilies aren't saved to disk. */
- conv_sml = purple_account_get_protocol_name(conv->account);
+ conv_sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); gtkconv = PIDGIN_CONVERSATION(conv);
for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) {
@@ -6549,7 +6847,7 @@
- if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->imhtml), sml, smile))
+ if (!add_custom_smiley_for_webview(GTK_WEBVIEW(gtkconv->webview), sml, smile)) if (!remote) /* If it's a local custom smiley, then add it for the entry */
@@ -6563,12 +6861,14 @@
pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
const guchar *data, gsize size)
PidginConversation *gtkconv;
- sml = purple_account_get_protocol_name(conv->account);
+ sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); gtkconv = PIDGIN_CONVERSATION(conv);
smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
@@ -6584,7 +6884,7 @@
if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) {
purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() "
- "failed with size=%zu: %s\n", size,
+ "failed with size=%" G_GSIZE_FORMAT ": %s\n", size, error ? error->message : "(no error message)");
@@ -6597,11 +6897,14 @@
g_object_unref(G_OBJECT(smiley->loader));
smiley->loader = gdk_pixbuf_loader_new();
pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
PidginConversation *gtkconv;
@@ -6610,7 +6913,7 @@
g_return_if_fail(conv != NULL);
g_return_if_fail(smile != NULL);
- sml = purple_account_get_protocol_name(conv->account);
+ sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); gtkconv = PIDGIN_CONVERSATION(conv);
smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
@@ -6638,6 +6941,7 @@
g_object_unref(G_OBJECT(smiley->loader));
smiley->loader = gdk_pixbuf_loader_new();
@@ -6665,11 +6969,11 @@
win = pidgin_conv_get_window(gtkconv);
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv); account = purple_conversation_get_account(conv);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (win->menu.send_to != NULL)
update_send_to_selection(win);
@@ -6688,7 +6992,7 @@
/* Deal with menu items */
gtk_action_set_visible(win->menu.view_log, TRUE);
gtk_action_set_visible(win->menu.send_file, TRUE);
- gtk_action_set_visible(GTK_ACTION(g_object_get_data(G_OBJECT(win->window), "get_attention")), TRUE);
+ gtk_action_set_visible(win->menu.get_attention, TRUE); gtk_action_set_visible(win->menu.add_pounce, TRUE);
gtk_action_set_visible(win->menu.get_info, TRUE);
gtk_action_set_visible(win->menu.invite, FALSE);
@@ -6717,7 +7021,7 @@
/* Deal with menu items */
gtk_action_set_visible(win->menu.view_log, TRUE);
gtk_action_set_visible(win->menu.send_file, FALSE);
- gtk_action_set_visible(g_object_get_data(G_OBJECT(win->window), "get_attention"), FALSE);
+ gtk_action_set_visible(win->menu.get_attention, FALSE); gtk_action_set_visible(win->menu.add_pounce, FALSE);
gtk_action_set_visible(win->menu.get_info, FALSE);
gtk_action_set_visible(win->menu.invite, TRUE);
@@ -6747,31 +7051,35 @@
((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) ||
!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) ))
+ PurpleConnectionFlags features = purple_conversation_get_features(conv); /* Deal with the toolbar */
- if (conv->features & PURPLE_CONNECTION_HTML)
+ if (features & PURPLE_CONNECTION_HTML) buttons = GTK_IMHTML_ALL; /* Everything on */
- if (conv->features & PURPLE_CONNECTION_NO_BGCOLOR)
+ if (features & PURPLE_CONNECTION_NO_BGCOLOR) buttons &= ~GTK_IMHTML_BACKCOLOR;
- if (conv->features & PURPLE_CONNECTION_NO_FONTSIZE)
+ if (features & PURPLE_CONNECTION_NO_FONTSIZE) buttons &= ~GTK_IMHTML_GROW;
buttons &= ~GTK_IMHTML_SHRINK;
- if (conv->features & PURPLE_CONNECTION_NO_URLDESC)
+ if (features & PURPLE_CONNECTION_NO_URLDESC) buttons &= ~GTK_IMHTML_LINKDESC;
buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE;
- if (!(prpl_info->options & OPT_PROTO_IM_IMAGE))
- conv->features |= PURPLE_CONNECTION_NO_IMAGES;
- if(conv->features & PURPLE_CONNECTION_NO_IMAGES)
+ if (!(prpl_info->options & OPT_PROTO_IM_IMAGE) + && !(features & PURPLE_CONNECTION_NO_IMAGES)) { + features |= PURPLE_CONNECTION_NO_IMAGES; + purple_conversation_set_features(conv, features); + if (features & PURPLE_CONNECTION_NO_IMAGES) buttons &= ~GTK_IMHTML_IMAGE;
- if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
+ if (features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) buttons |= GTK_IMHTML_CUSTOM_SMILEY;
buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
@@ -6785,17 +7093,17 @@
gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
- gtk_action_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
- gtk_action_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
+ gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); + gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
- gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL));
+ gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
gtk_action_set_sensitive(win->menu.send_file,
(prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
- gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
+ gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); gtk_action_set_sensitive(win->menu.alias,
(purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
@@ -6816,8 +7124,7 @@
/* Then deal with menu items */
gtk_action_set_sensitive(win->menu.view_log, TRUE);
gtk_action_set_sensitive(win->menu.send_file, FALSE);
- gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window),
- "get_attention"), FALSE);
+ gtk_action_set_sensitive(win->menu.get_attention, FALSE); gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
gtk_action_set_sensitive(win->menu.get_info, FALSE);
gtk_action_set_sensitive(win->menu.invite, FALSE);
@@ -6837,7 +7144,7 @@
if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) &&
- PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+ PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
@@ -6885,6 +7192,7 @@
gray_stuff_out(PIDGIN_CONVERSATION(conv));
generate_send_to_items(win);
+ regenerate_plugins_items(win); if (fields & PIDGIN_CONV_TAB_ICON)
@@ -6915,12 +7223,14 @@
if (fields & PIDGIN_CONV_SMILEY_THEME)
- pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml);
+ pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview); if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
(fields & PIDGIN_CONV_SET_TITLE) ||
- (fields & PIDGIN_CONV_TOPIC))
+ (fields & PIDGIN_CONV_TOPIC)) @@ -6943,7 +7253,7 @@
title = g_strdup(purple_conversation_get_title(conv));
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- buddy = purple_find_buddy(account, conv->name);
+ buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
@@ -6988,7 +7298,7 @@
style = "tab-label-attention";
} else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) {
atk_object_set_description(accessibility_obj, _("Unread Messages"));
- if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT)
+ if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT) style = "tab-label-unreadchat";
style = "tab-label-attention";
@@ -7200,7 +7510,7 @@
if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
- if (purple_conversation_get_gc(conv) == NULL)
+ if (purple_conversation_get_connection(conv) == NULL) buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
@@ -7286,7 +7596,7 @@
gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE);
gtk_widget_add_events(event,
- GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
+ GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); g_signal_connect(G_OBJECT(event), "button-press-event",
G_CALLBACK(icon_menu), gtkconv);
@@ -7328,14 +7638,11 @@
gint pane_x, pane_y, x_rel;
PidginConversation *gtkconv;
- GtkAllocation allocation;
- gdk_window_get_origin(gtk_widget_get_window(win->notebook),
+ gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y); gtkconv = pidgin_conv_window_get_active_gtkconv(win);
- gtk_widget_get_allocation(gtkconv->infopane, &allocation);
- return (x_rel > allocation.x + allocation.width / 2);
+ return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2); @@ -7353,7 +7660,7 @@
notebook = GTK_NOTEBOOK(win->notebook);
- gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
+ gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); @@ -7363,32 +7670,30 @@
count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
for (i = 0; i < count; i++) {
- GtkAllocation allocation;
page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
- gtk_widget_get_allocation(tab, &allocation);
/* Make sure the tab is not hidden beyond an arrow */
if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
- if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE &&
- x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) {
+ if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE && + x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) { - if (to_right && x_rel >= allocation.x + allocation.width/2)
+ if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2) - if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE &&
- y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) {
+ if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE && + y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) { - if (to_right && y_rel >= allocation.y + allocation.height/2)
+ if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2) @@ -7499,8 +7804,11 @@
GTK_TOGGLE_ACTION(win->menu.show_timestamps),
(gboolean)GPOINTER_TO_INT(value));
+/* TODO WEBKIT: Use WebKit version of this. */ gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
(gboolean)GPOINTER_TO_INT(value));
@@ -7668,7 +7976,7 @@
conv = gtkconv->active_conv;
- if (conv->type == PURPLE_CONV_TYPE_CHAT ||
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT || gtkconv->unseen_count == 0 ||
(when_away && !purple_status_is_available(
purple_account_get_active_status(
@@ -7708,7 +8016,7 @@
PurpleBuddy *buddy = (PurpleBuddy*)node;
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); return PIDGIN_CONVERSATION(conv);
@@ -7733,16 +8041,18 @@
PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE);
if (PURPLE_CONNECTION_IS_CONNECTED(gc) &&
- conv->type == PURPLE_CONV_TYPE_CHAT &&
- conv->account == gc->account &&
+ purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && + purple_conversation_get_account(conv) == purple_connection_get_account(gc) && purple_conversation_get_data(conv, "want-to-rejoin")) {
GHashTable *comps = NULL;
- PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
+ PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); - if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
- comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); + if (prpl_info->chat_info_defaults != NULL) + comps = prpl_info->chat_info_defaults(gc, purple_conversation_get_name(conv)); - comps = chat->components;
+ comps = purple_chat_get_components(chat); serv_join_chat(gc, comps);
if (chat == NULL && comps != NULL)
@@ -7809,7 +8119,7 @@
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON);
@@ -7819,7 +8129,7 @@
PurpleConversation *conv;
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); pidgin_conv_update_fields(conv, PIDGIN_CONV_BUDDY_ICON);
@@ -7884,7 +8194,7 @@
message_compare(gconstpointer p1, gconstpointer p2)
const PurpleConvMessage *m1 = p1, *m2 = p2;
- return (m1->when > m2->when);
+ return (purple_conversation_message_get_timestamp(m1) > purple_conversation_message_get_timestamp(m2)); /* Adds some message history to the gtkconv. This happens in a idle-callback. */
@@ -7895,16 +8205,22 @@
int timer = gtkconv->attach.timer;
time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time"));
- gboolean im = (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM);
+ gboolean im = (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM); gtkconv->attach.timer = 0;
while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */
PurpleConvMessage *msg = gtkconv->attach.current->data;
- if (!im && when && when < msg->when) {
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
+ if (!im && when && when < purple_conversation_message_get_timestamp(msg)) { + gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
- pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
+ pidgin_conv_write_conv( + purple_conversation_message_get_conv(msg), + purple_conversation_message_get_sender(msg), + purple_conversation_message_get_alias(msg), + purple_conversation_message_get_message(msg), + purple_conversation_message_get_flags(msg), + purple_conversation_message_get_timestamp(msg)); gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current);
@@ -7927,16 +8243,22 @@
GList *history = purple_conversation_get_message_history(conv);
for (; history; history = history->next) {
PurpleConvMessage *msg = history->data;
+ if (purple_conversation_message_get_timestamp(msg) > when) msgs = g_list_prepend(msgs, msg);
msgs = g_list_sort(msgs, message_compare);
for (; msgs; msgs = g_list_delete_link(msgs, msgs)) {
PurpleConvMessage *msg = msgs->data;
- pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when);
- gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
+ pidgin_conv_write_conv( + purple_conversation_message_get_conv(msg), + purple_conversation_message_get_sender(msg), + purple_conversation_message_get_alias(msg), + purple_conversation_message_get_message(msg), + purple_conversation_message_get_flags(msg), + purple_conversation_message_get_timestamp(msg)); + gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
@@ -8012,16 +8334,16 @@
g_return_val_if_reached(TRUE);
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time",
- GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when));
+ GINT_TO_POINTER(purple_conversation_message_get_timestamp((PurpleConvMessage*)(list->data)))); gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv);
purple_signal_emit(pidgin_conversations_get_handle(),
"conversation-displayed", gtkconv);
- if (conv->type == PURPLE_CONV_TYPE_CHAT) {
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC);
- pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE);
+ pidgin_conv_chat_add_users(conv, purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)), TRUE); @@ -8043,6 +8365,7 @@
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/themes"); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE);
@@ -8130,7 +8453,7 @@
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
show_protocol_icons_pref_cb, NULL);
purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new",
- hide_new_pref_cb, NULL);
+ hide_new_pref_cb, NULL); @@ -8287,7 +8610,7 @@
window_list = g_list_remove(window_list, hidden_convwin);
purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
- handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
+ handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); /* Callbacks to update a conversation */
purple_signal_connect(blist_handle, "blist-node-added", handle,
@@ -8326,6 +8649,8 @@
purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle,
PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
+ purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_CONV_THEME_LOADER, "type", "conversation", NULL)); /* Set default tab colors */
GString *str = g_string_new(NULL);
@@ -8471,15 +8796,12 @@
gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
- /* TODO: figure out how to set no separator in GTK+ 3.0 */
- gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
+#if !GTK_CHECK_VERSION(2,22,0) + gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), FALSE); /* Setup the outside spacing. */
- vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog));
+ vbox = GTK_DIALOG(warn_close_dialog)->vbox; gtk_box_set_spacing(GTK_BOX(vbox), 12);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
@@ -8633,7 +8955,7 @@
always be true after a button press. */
if (!gdk_pointer_is_grabbed())
- gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE,
+ gdk_pointer_grab(gtkwin->notebook->window, FALSE, GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
NULL, cursor, GDK_CURRENT_TIME);
@@ -8753,9 +9075,6 @@
- GtkAllocation allocation;
- gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation);
if (gtkconv->win->in_drag)
@@ -8763,12 +9082,12 @@
gtkconv->win->in_predrag = TRUE;
gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
- gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y);
- gtkconv->win->drag_min_x = allocation.x + nb_x;
- gtkconv->win->drag_min_y = allocation.y + nb_y;
- gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x;
- gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y;
+ gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); + gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; + gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; + gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; + gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
G_CALLBACK(notebook_motion_cb), gtkconv->win);
@@ -8781,10 +9100,9 @@
/* Right click was pressed. Popup the context menu. */
GtkWidget *menu = gtk_menu_new(), *sub;
gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
- if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
+ if (sub && gtk_widget_is_sensitive(gtkconv->win->menu.send_to)) { GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To"));
@@ -8796,7 +9114,7 @@
gtk_widget_destroy(menu);
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
@@ -8811,7 +9129,6 @@
- GtkAllocation allocation;
if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
PidginConversation *gtkconv;
@@ -8849,7 +9166,7 @@
* Get the relative position of the press event, with regards to
* the position of the notebook.
- gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
+ gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); /* Reset the min/max x/y */
@@ -8861,12 +9178,10 @@
page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked);
tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page);
- gtk_widget_get_allocation(tab, &allocation);
- win->drag_min_x = allocation.x + nb_x;
- win->drag_min_y = allocation.y + nb_y;
- win->drag_max_x = allocation.width + win->drag_min_x;
- win->drag_max_y = allocation.height + win->drag_min_y;
+ win->drag_min_x = tab->allocation.x + nb_x; + win->drag_min_y = tab->allocation.y + nb_y; + win->drag_max_x = tab->allocation.width + win->drag_min_x; + win->drag_max_y = tab->allocation.height + win->drag_min_y; /* Make sure the click occurred in the tab. */
if (e->x_root < win->drag_min_x ||
@@ -8874,8 +9189,8 @@
e->y_root < win->drag_min_y ||
e->y_root >= win->drag_max_y) {
win->drag_tab = tab_clicked;
@@ -9103,14 +9418,11 @@
close_conv_cb(NULL, gtkconv);
-/* TODO: I don't know if this doable in GTK+ 3.0 */
right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
+ GtkWidget *item, *menu; PidginConversation *gtkconv;
- GtkWidget *menu = gtk_notebook_get_menu
if (event->type != GDK_BUTTON_PRESS || event->button != 3)
@@ -9157,7 +9469,6 @@
remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry)
@@ -9179,7 +9490,7 @@
alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
- if (event->keyval == GDK_KEY_Escape) {
+ if (event->keyval == GDK_Escape) { remove_edit_entry(user_data, widget);
@@ -9206,7 +9517,8 @@
buddy = purple_find_buddy(account, name);
- purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry));
+ purple_blist_alias_buddy(buddy, + gtk_entry_get_text(entry)); } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
@@ -9228,13 +9540,13 @@
- if (!purple_account_is_connected(gtkconv->active_conv->account)) {
+ if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { /* Do not allow aliasing someone on a disconnected account. */
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name);
+ PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); /* This buddy isn't in your buddy list, so we can't alias him */
@@ -9244,9 +9556,9 @@
PurplePluginProtocolInfo *prpl_info = NULL;
- gc = purple_conversation_get_gc(conv);
+ gc = purple_conversation_get_connection(conv); - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info && prpl_info->set_chat_topic == NULL)
/* This protocol doesn't support setting the chat room topic */
@@ -9352,18 +9664,14 @@
make_status_icon_list(const char *stock, GtkWidget *w)
- gtk_widget_render_icon(w, stock,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow"));
- gtk_widget_render_icon(w, stock,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"));
- gtk_widget_render_icon(w, stock,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow"));
- gtk_widget_render_icon(w, stock,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow"));
+ l = g_list_append(l, gtk_widget_render_icon (w, stock, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow")); + l = g_list_append(l, gtk_widget_render_icon (w, stock, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow")); + l = g_list_append(l, gtk_widget_render_icon (w, stock, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow")); + l = g_list_append(l, gtk_widget_render_icon (w, stock, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow")); @@ -9394,7 +9702,7 @@
/* Workaround for GTK+ bug # 169811 - "configure_event" is fired
* when the window is being maximized */
- if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
+ if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) /* don't save off-screen positioning */
@@ -9419,8 +9727,8 @@
pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
int conv_width, int conv_height)
- /* if the window exists, is hidden, we're saving positions, and the
- * position is sane... */
+ /* if the window exists, is hidden, we're saving positions, and the + * position is sane... */ if (win && win->window &&
!gtk_widget_get_visible(win->window) && conv_width != 0) {
@@ -9507,12 +9815,8 @@
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
- /* TODO: figure out how to add custom stuff to the right-click menu in
- GtkNotebook in GTK+ 3.0 */
g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
G_CALLBACK(right_click_menu_cb), win);
gtk_widget_show(win->notebook);
@@ -9604,7 +9908,7 @@
pidgin_conv_window_raise(PidginWindow *win)
- gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window)));
+ gdk_window_raise(GDK_WINDOW(win->window->window)); @@ -9779,7 +10083,7 @@
g_signal_connect(G_OBJECT(ebox), "enter-notify-event",
G_CALLBACK(gtkconv_tab_set_tip), gtkconv);
- if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) {
+ if (gtkconv->tab_label->parent == NULL) { /* Pack if it's a new widget */
gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0);
@@ -9800,7 +10104,9 @@
gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
- g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL);
+ gtk_container_child_set(GTK_CONTAINER(win->notebook), gtkconv->tab_cont, + "tab-expand", !tabs_side && !angle, + "tab-fill", TRUE, NULL); if (pidgin_conv_window_get_gtkconv_count(win) == 1)
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
@@ -9824,12 +10130,7 @@
index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
-#if GTK_CHECK_VERSION(2,10,0)
g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
- g_object_ref(gtkconv->tab_cont);
- gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
@@ -9912,7 +10213,7 @@
for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
- if (gdkwin == gtk_widget_get_window(win->window))
+ if (gdkwin == win->window->window) @@ -10041,7 +10342,7 @@
/* Workaround for GTK+ bug # 169811 - "configure_event" is fired
* when the window is being maximized */
- if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
+ if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) /* don't save off-screen positioning */
--- a/pidgin/gtkimhtml.c Mon Aug 22 22:46:08 2011 +0000
+++ b/pidgin/gtkimhtml.c Fri Dec 23 08:21:58 2011 +0000
@@ -65,6 +65,16 @@
#define TOOLTIP_TIMEOUT 500
+#if !GTK_CHECK_VERSION(2,20,0) +#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x) +#if !GTK_CHECK_VERSION(2,18,0) +#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x) +#define gtk_widget_get_state(x) GTK_WIDGET_STATE(x) +#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x) static GtkTextViewClass *parent_class = NULL;
@@ -83,6 +93,36 @@
+struct _GtkIMHtmlScalable { + void (*scale)(struct _GtkIMHtmlScalable *, int, int); + void (*add_to)(struct _GtkIMHtmlScalable *, GtkIMHtml *, GtkTextIter *); + void (*free)(struct _GtkIMHtmlScalable *); + GtkIMHtmlScalable scalable; +struct _GtkIMHtmlImage { + GtkIMHtmlScalable scalable; + GtkImage *image; /**< Contains the scaled version of this pixbuf. */ + GdkPixbuf *pixbuf; /**< The original pixbuf, before any scaling. */ +struct _GtkIMHtmlAnimation { + GtkIMHtmlImage imhtmlimage; + GdkPixbufAnimation *anim; /**< The original animation, before any scaling. */ + GdkPixbufAnimationIter *iter; @@ -90,8 +130,13 @@
-typedef struct _GtkIMHtmlProtocol
+ GtkSmileyTree **children; + GtkIMHtmlSmiley *image; @@ -99,7 +144,8 @@
gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu);
-typedef struct _GtkIMHtmlFontDetail {
+/* The five elements contained in a FONT tag */ @@ -511,20 +557,18 @@
gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
- cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window));
g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
- gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip",
- gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr,
- GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout);
+ gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, + "tooltip", 0, 0, -1, -1); + gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, + FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); @@ -536,15 +580,12 @@
PangoFontMetrics *font_metrics;
- GtkStyle *style = gtk_widget_get_style(imhtml->tip_window);
- GtkAllocation allocation;
gint gap, x, y, h, w, scr_w, baseline_skip;
g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
- gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation);
- if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) {
+ if (!imhtml->tip || !gtk_widget_is_drawable (GTK_WIDGET(imhtml))) { @@ -568,10 +609,11 @@
gtk_widget_ensure_style (imhtml->tip_window);
layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
font = pango_context_load_font(pango_layout_get_context(layout),
+ imhtml->tip_window->style->font_desc); - char *tmp = pango_font_description_to_string(style->font_desc);
+ char *tmp = pango_font_description_to_string( + imhtml->tip_window->style->font_desc); purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip",
"pango_context_load_font() couldn't load font: '%s'\n",
@@ -596,8 +638,8 @@
gdk_window_get_pointer (NULL, &x, &y, NULL);
- if ((!gtk_widget_get_has_window(GTK_WIDGET(imhtml))))
+ if (!gtk_widget_get_has_window (GTK_WIDGET(imhtml))) + y += GTK_WIDGET(imhtml)->allocation.y; scr_w = gdk_screen_width();
@@ -637,7 +679,7 @@
oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag;
- gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL);
+ gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET,
event->x, event->y, &x, &y);
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y);
@@ -765,8 +807,6 @@
-/* TODO: I think this can be removed for GTK+ 3.0... */
gtk_imhtml_expose_event (GtkWidget *widget,
@@ -794,8 +834,7 @@
gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
gdk_cairo_set_source_color(cr, &gcolor);
- gdk_cairo_set_source_color(cr,
- &(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
+ gdk_cairo_set_source_color(cr, &(widget->style->base[gtk_widget_get_state(widget)])); @@ -901,7 +940,6 @@
static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
@@ -1073,7 +1111,7 @@
if (primary) /* This was allocated here */
static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml)
@@ -1178,12 +1216,11 @@
GtkIMHtml *imhtml = data;
- gint length = gtk_selection_data_get_length(selection_data);
if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
- if (imhtml->wbfo || length <= 0) {
+ if (imhtml->wbfo || selection_data->length <= 0) { gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
@@ -1207,13 +1244,13 @@
- text = g_malloc(length + 1);
- memcpy(text, gtk_selection_data_get_data(selection_data), length);
+ text = g_malloc(selection_data->length + 1); + memcpy(text, selection_data->data, selection_data->length); /* Make sure the paste data is null-terminated. Given that
* we're passed length (but assume later that it is
* null-terminated), this seems sensible to me.
+ text[selection_data->length] = '\0'; @@ -1224,10 +1261,10 @@
+ if (selection_data->length >= 2 && (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) {
- char *utf8 = utf16_to_utf8_with_bom_check(text, length);
+ char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length); @@ -1342,7 +1379,7 @@
paste_received_cb, imhtml);
@@ -1588,8 +1625,7 @@
gobject_class->finalize = gtk_imhtml_finalize;
widget_class->drag_motion = gtk_text_view_drag_motion;
- /* TODO: I _think_ this should be removed for GTK+ 3.0 */
- /*widget_class->expose_event = gtk_imhtml_expose_event;*/
+ widget_class->expose_event = gtk_imhtml_expose_event; parent_size_allocate = widget_class->size_allocate;
widget_class->size_allocate = gtk_imhtml_size_allocate;
parent_style_set = widget_class->style_set;
@@ -1651,20 +1687,20 @@
TRUE, G_PARAM_READABLE));
binding_set = gtk_binding_set_by_class (parent_class);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
+ gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD); + gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC); + gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE); + gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); + gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); + gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK); binding_set = gtk_binding_set_by_class(klass);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
+ gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0); + gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0); + gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0); + gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0); + gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0); + gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text"); static void gtk_imhtml_init (GtkIMHtml *imhtml)
@@ -1891,23 +1927,23 @@
/* can't accept any of the offered targets */
GtkWidget *source_widget;
- suggested_action = gdk_drag_context_get_suggested_action(context);
+ suggested_action = context->suggested_action; source_widget = gtk_drag_get_source_widget (context);
if (source_widget == widget) {
/* Default to MOVE, unless the user has
* pressed ctrl or alt to affect available actions
- if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
+ if ((context->actions & GDK_ACTION_MOVE) != 0) suggested_action = GDK_ACTION_MOVE;
gdk_drag_status (context, suggested_action, time);
- /* TRUE return means don't propagate the drag motion to parent
- * widgets that may also be drop sites.
+ /* TRUE return means don't propagate the drag motion to parent + * widgets that may also be drop sites. @@ -1929,22 +1965,21 @@
- char *text = (char *) gtk_selection_data_get_data(sd);
+ char *text = (char *)sd->data; GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer);
- gint length = gtk_selection_data_get_length(sd);
gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark);
- if (gtk_imhtml_get_editable(imhtml) && text) {
+ if(gtk_imhtml_get_editable(imhtml) && sd->data){ case GTK_IMHTML_DRAG_URL:
/* TODO: Is it really ok to change sd->data...? */
- purple_str_strip_char(text, '\r');
- links = g_strsplit(text, "\n", 0);
- while ((link = links[i]) != NULL) {
+ purple_str_strip_char((char *)sd->data, '\r'); + links = g_strsplit((char *)sd->data, "\n", 0); + while((link = links[i]) != NULL){ if (gtk_imhtml_is_protocol(link)) {
@@ -1966,7 +2001,7 @@
case GTK_IMHTML_DRAG_HTML:
@@ -1982,8 +2017,8 @@
* See also the comment on text/html here:
* http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html
- if (length >= 2 && !g_utf8_validate(text, length - 1, NULL)) {
- utf8 = utf16_to_utf8_with_bom_check(text, length);
+ if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) { + utf8 = utf16_to_utf8_with_bom_check(text, sd->length); purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n");
@@ -2012,8 +2047,7 @@
gtk_drag_finish(dc, FALSE, FALSE, t);
- gtk_drag_finish(dc, TRUE,
- gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+ gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); gtk_drag_finish(dc, FALSE, FALSE, t);
@@ -2544,8 +2578,8 @@
static gboolean smooth_scroll_cb(gpointer data)
GtkIMHtml *imhtml = data;
- GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
- gdouble max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
+ GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; + gdouble max_val = adj->upper - adj->page_size; gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE);
@@ -2568,10 +2602,9 @@
static gboolean scroll_idle_cb(gpointer data)
GtkIMHtml *imhtml = data;
- GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
- gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) -
- gtk_adjustment_get_page_size(adj));
+ GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; + gtk_adjustment_set_value(adj, adj->upper - adj->page_size); @@ -3606,125 +3639,38 @@
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0);
-/* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */
-GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id)
- GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage));
- GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
- GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
- GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free;
- im_image->pixbuf = img;
- im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
- im_image->width = gdk_pixbuf_get_width(img);
- im_image->height = gdk_pixbuf_get_height(img);
- im_image->filename = g_strdup(filename);
- im_image->filesel = NULL;
- return GTK_IMHTML_SCALABLE(im_image);
-animate_image_cb(gpointer data)
- GtkIMHtmlImage *im_image;
- /* Update the pointer to this GdkPixbuf frame of the animation */
- if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) {
- GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
- g_object_unref(G_OBJECT(im_image->pixbuf));
- im_image->pixbuf = gdk_pixbuf_copy(pb);
- /* Update the displayed GtkImage */
- width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image));
- height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image));
- if (width > 0 && height > 0)
- /* Need to scale the new frame to the same size as the old frame */
- tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, tmp);
- g_object_unref(G_OBJECT(tmp));
- /* Display at full-size */
- gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf);
- delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
- GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
-GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id)
- GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1);
- GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale;
- GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to;
- GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free;
- GTK_IMHTML_ANIMATION(im_image)->anim = anim;
- if (gdk_pixbuf_animation_is_static_image(anim)) {
- im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim);
- g_object_ref(im_image->pixbuf);
- GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL);
- pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter);
- im_image->pixbuf = gdk_pixbuf_copy(pb);
- delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100);
- GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image);
- im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf));
- im_image->width = gdk_pixbuf_animation_get_width(anim);
- im_image->height = gdk_pixbuf_animation_get_height(anim);
- im_image->filename = g_strdup(filename);
- return GTK_IMHTML_SCALABLE(im_image);
-void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height)
- GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale;
- if (im_image->width > width || im_image->height > height) {
- double ratio_w, ratio_h, ratio;
- GdkPixbuf *new_image = NULL;
- ratio_w = ((double)width - 2) / im_image->width;
- ratio_h = ((double)height - 2) / im_image->height;
- ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h;
- new_w = (int)(im_image->width * ratio);
- new_h = (int)(im_image->height * ratio);
- new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, new_image);
- g_object_unref(G_OBJECT(new_image));
- } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) {
- /* Enough space to show the full-size of the image. */
- new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf(im_image->image, new_image);
- g_object_unref(G_OBJECT(new_image));
+ * Destroys and frees a GTK+ IM/HTML scalable image. + * @param scale The GTK+ IM/HTML scalable. +static void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) + GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; + g_object_unref(image->pixbuf); + g_free(image->filename); + gtk_widget_destroy(image->filesel); + * Destroys and frees a GTK+ IM/HTML scalable animation. + * @param scale The GTK+ IM/HTML scalable. +static void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale) + GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale; + if (animation->timer > 0) + g_source_remove(animation->timer); + if (animation->iter != NULL) + g_object_unref(animation->iter); + g_object_unref(animation->anim); + gtk_imhtml_image_free(scale); @@ -3931,55 +3877,51 @@
-static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
- GdkPixbufAnimation *anim = NULL;
- GtkIMHtmlImageSave *save = NULL;
- if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
- anim = gtk_smiley_get_image(smiley);
- save = g_new0(GtkIMHtmlImageSave, 1);
- save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0);
- save->data = smiley->data; /* Do not need to memdup here, since the smiley is not
- destroyed before this GtkIMHtmlImageSave */
- save->datasize = smiley->datasize;
- ret = gtk_imhtml_image_clicked(w, event, save);
- g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free);
- g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free);
-void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
- GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
- g_object_unref(image->pixbuf);
- g_free(image->filename);
- gtk_widget_destroy(image->filesel);
-void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale)
- GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale;
- if (animation->timer > 0)
- g_source_remove(animation->timer);
- if (animation->iter != NULL)
- g_object_unref(animation->iter);
- g_object_unref(animation->anim);
- gtk_imhtml_image_free(scale);
-void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
+ * Rescales a GTK+ IM/HTML scalable image to a given size. + * @param scale The GTK+ IM/HTML scalable. + * @param width The new width. + * @param height The new height. +static void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) + GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale; + if (im_image->width > width || im_image->height > height) { + double ratio_w, ratio_h, ratio; + GdkPixbuf *new_image = NULL; + ratio_w = ((double)width - 2) / im_image->width; + ratio_h = ((double)height - 2) / im_image->height; + ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h; + new_w = (int)(im_image->width * ratio); + new_h = (int)(im_image->height * ratio); + new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(im_image->image, new_image); + g_object_unref(G_OBJECT(new_image)); + } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) { + /* Enough space to show the full-size of the image. */ + new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(im_image->image, new_image); + g_object_unref(G_OBJECT(new_image)); + * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter. + * @param scale The GTK+ IM/HTML scalable. + * @param imhtml The GTK+ IM/HTML. + * @param iter The GtkTextIter at which to add the scalable. +static void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
GtkWidget *box = gtk_event_box_new();
@@ -4007,6 +3949,121 @@
g_object_set_data_full(G_OBJECT(box), "image-save-data", save, (GDestroyNotify)g_free);
+ * Creates and returns a new GTK+ IM/HTML scalable object with an image. + * @param img A GdkPixbuf of the image to add. + * @param filename The filename to associate with the image. + * @param id The id to associate with the image. + * @return A new IM/HTML Scalable object with an image. +static GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id) + GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); + GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; + GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; + GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; + im_image->pixbuf = img; + im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); + im_image->width = gdk_pixbuf_get_width(img); + im_image->height = gdk_pixbuf_get_height(img); + im_image->filename = g_strdup(filename); + im_image->filesel = NULL; + return GTK_IMHTML_SCALABLE(im_image); +animate_image_cb(gpointer data) + GtkIMHtmlImage *im_image; + /* Update the pointer to this GdkPixbuf frame of the animation */ + if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) { + GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); + g_object_unref(G_OBJECT(im_image->pixbuf)); + im_image->pixbuf = gdk_pixbuf_copy(pb); + /* Update the displayed GtkImage */ + width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)); + height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image)); + if (width > 0 && height > 0) + /* Need to scale the new frame to the same size as the old frame */ + tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(im_image->image, tmp); + g_object_unref(G_OBJECT(tmp)); + /* Display at full-size */ + gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf); + delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); + GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); + * Creates and returns a new GTK+ IM/HTML scalable object with an + * @param img A GdkPixbufAnimation of the image to add. + * @param filename The filename to associate with the image. + * @param id The id to associate with the image. + * @return A new IM/HTML Scalable object with an image. + * TODO: All this animation code could be combined much better with + * the image code. It couldn't be done when it was written + * because it requires breaking backward compatibility. It + * would be good to do it for 3.0.0. +static GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id) + GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1); + GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; + GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; + GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free; + GTK_IMHTML_ANIMATION(im_image)->anim = anim; + if (gdk_pixbuf_animation_is_static_image(anim)) { + im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim); + g_object_ref(im_image->pixbuf); + GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL); + pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); + im_image->pixbuf = gdk_pixbuf_copy(pb); + delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); + GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); + im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); + im_image->width = gdk_pixbuf_animation_get_width(anim); + im_image->height = gdk_pixbuf_animation_get_height(anim); + im_image->filename = g_strdup(filename); + return GTK_IMHTML_SCALABLE(im_image); GtkIMHtmlScalable *gtk_imhtml_hr_new()
GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr));
@@ -4229,14 +4286,9 @@
for (l = tags; l; l = l->next) {
GtkTextTag *tag = l->data;
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
- if (name && !strncmp(name, prefix, len))
+ if (tag->name && !strncmp(tag->name, prefix, len)) gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e);
@@ -4252,14 +4304,9 @@
for (l = tags; l; l = l->next) {
GtkTextTag *tag = l->data;
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
- if (name && !strncmp(name, prefix, len))
+ if (tag->name && !strncmp(tag->name, prefix, len)) gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e);
@@ -4380,16 +4427,11 @@
gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */
(!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */
gtk_text_iter_ends_tag(end, tag))) {
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end);
- if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) {
+ strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) { gtk_imhtml_toggle_link(imhtml, NULL);
@@ -4611,32 +4653,27 @@
for (l = tags; l != NULL; l = l->next) {
GtkTextTag *tag = GTK_TEXT_TAG(l->data);
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
- if (strcmp(name, "BOLD") == 0)
+ if (strcmp(tag->name, "BOLD") == 0) imhtml->edit.bold = TRUE;
- else if (strcmp(name, "ITALICS") == 0)
+ else if (strcmp(tag->name, "ITALICS") == 0) imhtml->edit.italic = TRUE;
- else if (strcmp(name, "UNDERLINE") == 0)
+ else if (strcmp(tag->name, "UNDERLINE") == 0) imhtml->edit.underline = TRUE;
- else if (strcmp(name, "STRIKE") == 0)
+ else if (strcmp(tag->name, "STRIKE") == 0) imhtml->edit.strike = TRUE;
- else if (strncmp(name, "FORECOLOR ", 10) == 0)
- imhtml->edit.forecolor = g_strdup(&(name)[10]);
- else if (strncmp(name, "BACKCOLOR ", 10) == 0)
- imhtml->edit.backcolor = g_strdup(&(name)[10]);
- else if (strncmp(name, "FONT FACE ", 10) == 0)
- imhtml->edit.fontface = g_strdup(&(name)[10]);
- else if (strncmp(name, "FONT SIZE ", 10) == 0)
- imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10);
- else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
+ else if (strncmp(tag->name, "FORECOLOR ", 10) == 0) + imhtml->edit.forecolor = g_strdup(&(tag->name)[10]); + else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0) + imhtml->edit.backcolor = g_strdup(&(tag->name)[10]); + else if (strncmp(tag->name, "FONT FACE ", 10) == 0) + imhtml->edit.fontface = g_strdup(&(tag->name)[10]); + else if (strncmp(tag->name, "FONT SIZE ", 10) == 0) + imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10); + else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
@@ -4927,8 +4964,6 @@
gtk_text_buffer_end_user_action(imhtml->text_buffer);
-/* TODO: I think this can be removed for GTK+ 3.0... */
image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
@@ -4936,10 +4971,9 @@
/* In case the smiley gets removed from the imhtml before it gets removed from the queue */
-static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml)
+static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml) GList *l = imhtml->animations->head;
@@ -4954,6 +4988,30 @@
+static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley) + GdkPixbufAnimation *anim = NULL; + GtkIMHtmlImageSave *save = NULL; + if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3) + anim = gtk_smiley_get_image(smiley); + save = g_new0(GtkIMHtmlImageSave, 1); + save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0); + save->data = smiley->data; /* Do not need to memdup here, since the smiley is not + destroyed before this GtkIMHtmlImageSave */ + save->datasize = smiley->datasize; + ret = gtk_imhtml_image_clicked(w, event, save); + g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free); + g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free); void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter)
GdkPixbuf *pixbuf = NULL;
@@ -5010,7 +5068,7 @@
- imhtml->num_animations++;
+ imhtml->num_animations++; g_signal_connect(G_OBJECT(icon), "destroy", G_CALLBACK(animated_smiley_destroy_cb), imhtml);
g_queue_push_tail(imhtml->animations, icon);
@@ -5034,9 +5092,7 @@
* images, and ensures that they are handled by the image
* itself, without propagating to the textview and causing
- /* TODO: I think this should be removed for GTK+ 3.0?
g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
@@ -5130,29 +5186,22 @@
static const gchar *tag_to_html_start(GtkTextTag *tag)
g_return_val_if_fail(name != NULL, "");
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
if (strcmp(name, "BOLD") == 0) {
} else if (strcmp(name, "ITALICS") == 0) {
} else if (strcmp(name, "UNDERLINE") == 0) {
} else if (strcmp(name, "STRIKE") == 0) {
} else if (strncmp(name, "LINK ", 5) == 0) {
char *tmp = g_object_get_data(G_OBJECT(tag), "link_url");
g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
buf[sizeof(buf)-1] = '\0';
@@ -5162,29 +5211,18 @@
} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]);
} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]);
} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]);
} else if (strncmp(name, "FONT FACE ", 10) == 0) {
g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]);
} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]);
@@ -5247,7 +5285,6 @@
g_snprintf(str, sizeof(buf) - (str - buf), "'>");
return (empty ? "" : buf);
@@ -5255,40 +5292,30 @@
static const gchar *tag_to_html_end(GtkTextTag *tag)
g_return_val_if_fail(name != NULL, "");
- g_object_get(G_OBJECT(tag), "name", &name, NULL);
if (strcmp(name, "BOLD") == 0) {
} else if (strcmp(name, "ITALICS") == 0) {
} else if (strcmp(name, "UNDERLINE") == 0) {
} else if (strcmp(name, "STRIKE") == 0) {
} else if (strncmp(name, "LINK ", 5) == 0) {
} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
} else if (strncmp(name, "FONT FACE ", 10) == 0) {
} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
const char *props[] = {"weight-set", "foreground-set", "background-set",
@@ -5301,8 +5328,6 @@