1.1 --- a/libpurple/protocols/gg/gg.c
1.2 +++ b/libpurple/protocols/gg/gg.c
1.3 @@ -52,13 +52,29 @@
1.4 #include "status.h"
1.5 #include "servconn.h"
1.6
1.7 -/* Prototypes */
1.8 +/* ---------------------------------------------------------------------- */
1.9
1.10 -typedef struct
1.11 +ggp_buddy_data * ggp_buddy_get_data(PurpleBuddy *buddy)
1.12 {
1.13 - gboolean blocked;
1.14 -} ggp_buddy_data;
1.15 + ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
1.16 + if (buddy_data)
1.17 + return buddy_data;
1.18 +
1.19 + buddy_data = g_new0(ggp_buddy_data, 1);
1.20 + purple_buddy_set_protocol_data(buddy, buddy_data);
1.21 + return buddy_data;
1.22 +}
1.23
1.24 +static void ggp_buddy_free(PurpleBuddy *buddy)
1.25 +{
1.26 + ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
1.27 +
1.28 + if (!buddy_data)
1.29 + return;
1.30 +
1.31 + g_free(buddy_data);
1.32 + purple_buddy_set_protocol_data(buddy, NULL);
1.33 +}
1.34
1.35 /* ---------------------------------------------------------------------- */
1.36 // buddy list import/export from/to file
1.37 @@ -383,96 +399,6 @@
1.38 /* ---------------------------------------------------------------------- */
1.39
1.40
1.41 -/**
1.42 - * Handle change of the status of the buddy.
1.43 - *
1.44 - * @param gc PurpleConnection
1.45 - * @param uin UIN of the buddy.
1.46 - * @param status ID of the status.
1.47 - * @param descr Description.
1.48 - */
1.49 -static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin,
1.50 - int status, const char *descr)
1.51 -{
1.52 - gchar *from;
1.53 - const char *st;
1.54 - char *status_msg = NULL;
1.55 - ggp_buddy_data *buddy_data;
1.56 - PurpleBuddy *buddy;
1.57 - PurpleAccount *account = purple_connection_get_account(gc);
1.58 -
1.59 - from = g_strdup_printf("%u", uin);
1.60 - buddy = purple_find_buddy(purple_connection_get_account(gc), from);
1.61 -
1.62 - switch (status) {
1.63 - case GG_STATUS_NOT_AVAIL:
1.64 - case GG_STATUS_NOT_AVAIL_DESCR:
1.65 - case GG_STATUS_BLOCKED:
1.66 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE);
1.67 - break;
1.68 - case GG_STATUS_FFC:
1.69 - case GG_STATUS_FFC_DESCR:
1.70 - st = "freeforchat";
1.71 - break;
1.72 - case GG_STATUS_AVAIL:
1.73 - case GG_STATUS_AVAIL_DESCR:
1.74 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE);
1.75 - break;
1.76 - case GG_STATUS_BUSY:
1.77 - case GG_STATUS_BUSY_DESCR:
1.78 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY);
1.79 - break;
1.80 - case GG_STATUS_INVISIBLE:
1.81 - case GG_STATUS_INVISIBLE_DESCR:
1.82 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE);
1.83 - break;
1.84 - case GG_STATUS_DND:
1.85 - case GG_STATUS_DND_DESCR:
1.86 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE);
1.87 - break;
1.88 - default:
1.89 - st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE);
1.90 - purple_debug_info("gg",
1.91 - "GG_EVENT_NOTIFY: Unknown status: %d\n", status);
1.92 - break;
1.93 - }
1.94 -
1.95 - if (descr != NULL) {
1.96 - status_msg = g_strdup(descr);
1.97 - g_strstrip(status_msg);
1.98 - if (status_msg[0] == '\0') {
1.99 - g_free(status_msg);
1.100 - status_msg = NULL;
1.101 - }
1.102 - }
1.103 -
1.104 - buddy_data = purple_buddy_get_protocol_data(buddy);
1.105 - if (!buddy_data)
1.106 - {
1.107 - buddy_data = g_new0(ggp_buddy_data, 1);
1.108 - purple_buddy_set_protocol_data(buddy, buddy_data);
1.109 - }
1.110 - buddy_data->blocked = (status == GG_STATUS_BLOCKED);
1.111 -
1.112 - if (uin == ggp_str_to_uin(purple_account_get_username(account)))
1.113 - {
1.114 - purple_debug_info("gg", "own status changed to %s [%s]\n", st,
1.115 - status_msg ? status_msg : "");
1.116 - }
1.117 -
1.118 - purple_debug_info("gg", "status of %u is %s [%s]\n", uin, st,
1.119 - status_msg ? status_msg : "");
1.120 - if (status_msg == NULL) {
1.121 - purple_prpl_got_user_status(account,
1.122 - from, st, NULL);
1.123 - } else {
1.124 - purple_prpl_got_user_status(account,
1.125 - from, st, "message", status_msg, NULL);
1.126 - g_free(status_msg);
1.127 - }
1.128 - g_free(from);
1.129 -}
1.130 -
1.131 static void ggp_sr_close_cb(gpointer user_data)
1.132 {
1.133 GGPSearchForm *form = user_data;
1.134 @@ -484,57 +410,26 @@
1.135 ggp_search_form_destroy(form);
1.136 }
1.137
1.138 -/**
1.139 - * Translate a status' ID to a more user-friendly name.
1.140 - *
1.141 - * @param id The ID of the status.
1.142 - *
1.143 - * @return The user-friendly name of the status.
1.144 - */
1.145 -static const char *ggp_status_by_id(unsigned int id)
1.146 -{
1.147 - const char *st;
1.148 -
1.149 - purple_debug_info("gg", "ggp_status_by_id: %d\n", id);
1.150 - switch (id) {
1.151 - case GG_STATUS_NOT_AVAIL:
1.152 - case GG_STATUS_NOT_AVAIL_DESCR:
1.153 - st = _("Offline");
1.154 - break;
1.155 - case GG_STATUS_AVAIL:
1.156 - case GG_STATUS_AVAIL_DESCR:
1.157 - st = _("Available");
1.158 - break;
1.159 - case GG_STATUS_FFC:
1.160 - case GG_STATUS_FFC_DESCR:
1.161 - return _("Chatty");
1.162 - case GG_STATUS_DND:
1.163 - case GG_STATUS_DND_DESCR:
1.164 - return _("Do Not Disturb");
1.165 - case GG_STATUS_BUSY:
1.166 - case GG_STATUS_BUSY_DESCR:
1.167 - st = _("Away");
1.168 - break;
1.169 - default:
1.170 - st = _("Unknown");
1.171 - break;
1.172 - }
1.173 -
1.174 - return st;
1.175 -}
1.176 -
1.177 static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req,
1.178 GGPSearchForm *form)
1.179 {
1.180 PurpleNotifyUserInfo *user_info;
1.181 PurpleBuddy *buddy;
1.182 char *val, *who;
1.183 + const gchar *status;
1.184
1.185 user_info = purple_notify_user_info_new();
1.186
1.187 +
1.188 val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS);
1.189 - /* XXX: Use of ggp_str_to_uin() is an ugly hack! */
1.190 - purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
1.191 + status = ggp_status_to_purplestatus(atoi(val));
1.192 + if (g_strcmp0(status, "freeforchat"))
1.193 + //TODO: move to status.h or push to libpurple
1.194 + status = _("Chatty");
1.195 + else
1.196 + status = purple_primitive_get_name_from_type(
1.197 + purple_primitive_get_type_from_id(status));
1.198 + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status);
1.199 g_free(val);
1.200
1.201 who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN);
1.202 @@ -1005,7 +900,6 @@
1.203 PurpleConnection *gc = _gc;
1.204 GGPInfo *info = purple_connection_get_protocol_data(gc);
1.205 struct gg_event *ev;
1.206 - int i;
1.207
1.208 if (!(ev = gg_watch_fd(info->session))) {
1.209 purple_debug_error("gg",
1.210 @@ -1036,63 +930,9 @@
1.211 case GG_EVENT_IMAGE_REQUEST:
1.212 ggp_image_send(gc, &ev->event.image_request);
1.213 break;
1.214 - case GG_EVENT_NOTIFY:
1.215 - case GG_EVENT_NOTIFY_DESCR:
1.216 - {
1.217 - struct gg_notify_reply *n;
1.218 - char *descr;
1.219 -
1.220 - purple_debug_info("gg", "notify_pre: (%d) status: %d\n",
1.221 - ev->event.notify->uin,
1.222 - GG_S(ev->event.notify->status));
1.223 -
1.224 - n = (ev->type == GG_EVENT_NOTIFY) ? ev->event.notify
1.225 - : ev->event.notify_descr.notify;
1.226 -
1.227 - for (; n->uin; n++) {
1.228 - descr = (ev->type == GG_EVENT_NOTIFY) ? NULL
1.229 - : ev->event.notify_descr.descr;
1.230 -
1.231 - purple_debug_info("gg",
1.232 - "notify: (%d) status: %d; descr: %s\n",
1.233 - n->uin, GG_S(n->status), descr ? descr : "(null)");
1.234 -
1.235 - ggp_generic_status_handler(gc,
1.236 - n->uin, GG_S(n->status), descr);
1.237 - }
1.238 - }
1.239 - break;
1.240 case GG_EVENT_NOTIFY60:
1.241 - for (i = 0; ev->event.notify60[i].uin; i++) {
1.242 - purple_debug_info("gg",
1.243 - "notify60: (%d) status=%d; version=%d; descr=%s\n",
1.244 - ev->event.notify60[i].uin,
1.245 - GG_S(ev->event.notify60[i].status),
1.246 - ev->event.notify60[i].version,
1.247 - ev->event.notify60[i].descr ? ev->event.notify60[i].descr : "(null)");
1.248 -
1.249 - ggp_generic_status_handler(gc, ev->event.notify60[i].uin,
1.250 - GG_S(ev->event.notify60[i].status),
1.251 - ev->event.notify60[i].descr);
1.252 - }
1.253 - break;
1.254 - case GG_EVENT_STATUS:
1.255 - purple_debug_info("gg", "status: (%d) status=%d; descr=%s\n",
1.256 - ev->event.status.uin, GG_S(ev->event.status.status),
1.257 - ev->event.status.descr ? ev->event.status.descr : "(null)");
1.258 -
1.259 - ggp_generic_status_handler(gc, ev->event.status.uin,
1.260 - GG_S(ev->event.status.status), ev->event.status.descr);
1.261 - break;
1.262 case GG_EVENT_STATUS60:
1.263 - purple_debug_info("gg",
1.264 - "status60: (%d) status=%d; version=%d; descr=%s\n",
1.265 - ev->event.status60.uin, GG_S(ev->event.status60.status),
1.266 - ev->event.status60.version,
1.267 - ev->event.status60.descr ? ev->event.status60.descr : "(null)");
1.268 -
1.269 - ggp_generic_status_handler(gc, ev->event.status60.uin,
1.270 - GG_S(ev->event.status60.status), ev->event.status60.descr);
1.271 + ggp_status_got_others(gc, ev);
1.272 break;
1.273 case GG_EVENT_PUBDIR50_SEARCH_REPLY:
1.274 ggp_pubdir_reply_handler(gc, ev->event.pubdir50);
1.275 @@ -1319,32 +1159,6 @@
1.276 return normalized;
1.277 }
1.278
1.279 -static char *ggp_status_text(PurpleBuddy *b)
1.280 -{
1.281 - const char *msg;
1.282 - char *text;
1.283 - char *tmp;
1.284 - ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(b);
1.285 -
1.286 - if (buddy_data && buddy_data->blocked)
1.287 - msg = _("Blocked");
1.288 - else
1.289 - {
1.290 - PurpleStatus *status = purple_presence_get_active_status(
1.291 - purple_buddy_get_presence(b));
1.292 - msg = purple_status_get_attr_string(status, "message");
1.293 - }
1.294 -
1.295 - if (msg == NULL)
1.296 - return NULL;
1.297 -
1.298 - tmp = purple_markup_strip_html(msg);
1.299 - text = g_markup_escape_text(tmp, -1);
1.300 - g_free(tmp);
1.301 -
1.302 - return text;
1.303 -}
1.304 -
1.305 static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
1.306 {
1.307 PurpleStatus *status;
1.308 @@ -1374,61 +1188,6 @@
1.309 }
1.310 }
1.311
1.312 -static GList *ggp_status_types(PurpleAccount *account)
1.313 -{
1.314 - PurpleStatusType *type;
1.315 - GList *types = NULL;
1.316 -
1.317 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
1.318 - NULL, NULL, TRUE, TRUE, FALSE,
1.319 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.320 - NULL);
1.321 - types = g_list_append(types, type);
1.322 -
1.323 - /*
1.324 - * New status for GG 8.0: PoGGadaj ze mna (chatty).
1.325 - * NOTE: at this time, this is used only to set our own status.
1.326 - */
1.327 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
1.328 - "freeforchat", _("Chatty"), TRUE, TRUE, FALSE,
1.329 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.330 - NULL);
1.331 - types = g_list_append(types, type);
1.332 -
1.333 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
1.334 - NULL, NULL, TRUE, TRUE, FALSE,
1.335 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.336 - NULL);
1.337 - types = g_list_append(types, type);
1.338 -
1.339 - /*
1.340 - * New status for GG 8.0: Nie przeszkadzac (do not disturb).
1.341 - */
1.342 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
1.343 - NULL, NULL, TRUE, TRUE, FALSE,
1.344 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.345 - NULL);
1.346 - types = g_list_append(types, type);
1.347 -
1.348 - /*
1.349 - * It's used on buddy list if and only if it's showing our own
1.350 - * (invisible) status.
1.351 - */
1.352 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
1.353 - NULL, NULL, TRUE, TRUE, FALSE,
1.354 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.355 - NULL);
1.356 - types = g_list_append(types, type);
1.357 -
1.358 - type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
1.359 - NULL, NULL, TRUE, TRUE, FALSE,
1.360 - "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
1.361 - NULL);
1.362 - types = g_list_append(types, type);
1.363 -
1.364 - return types;
1.365 -}
1.366 -
1.367 static GList *ggp_blist_node_menu(PurpleBlistNode *node)
1.368 {
1.369 PurpleMenuAction *act;
1.370 @@ -1587,31 +1346,9 @@
1.371 info = purple_connection_get_protocol_data(gc);
1.372
1.373 if (info) {
1.374 - PurpleStatus *status = purple_account_get_active_status(account);
1.375 -
1.376 if (info->session != NULL)
1.377 {
1.378 - const gchar *status_msg = purple_status_get_attr_string(status, "message");
1.379 -
1.380 - if (ggp_status_set(account,
1.381 - status_msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL,
1.382 - status_msg))
1.383 - {
1.384 - /*struct gg_event *ev;
1.385 - guint64 wait_start = ggp_microtime(), now;
1.386 - int sleep_time = 5000;
1.387 - while ((ev = gg_watch_fd(info->session)) != NULL)
1.388 - {
1.389 - if (ev->type == GG_EVENT_DISCONNECT_ACK)
1.390 - break;
1.391 - now = ggp_microtime();
1.392 - if (now - wait_start + sleep_time >= 100000)
1.393 - break;
1.394 - usleep(sleep_time);
1.395 - sleep_time *= 2;
1.396 - }*/
1.397 - usleep(100000);
1.398 - }
1.399 + ggp_status_set_disconnected(account);
1.400 gg_logoff(info->session);
1.401 gg_free_session(info->session);
1.402 }
1.403 @@ -1649,14 +1386,14 @@
1.404 gint pos = 0;
1.405 GData *attribs;
1.406 const char *start, *end = NULL, *last;
1.407 - ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(
1.408 + ggp_buddy_data *buddy_data = ggp_buddy_get_data(
1.409 purple_find_buddy(purple_connection_get_account(gc), who));
1.410
1.411 if (msg == NULL || *msg == '\0') {
1.412 return 0;
1.413 }
1.414
1.415 - if (buddy_data && buddy_data->blocked)
1.416 + if (buddy_data->blocked)
1.417 return -1;
1.418
1.419 last = msg;
1.420 @@ -1970,10 +1707,7 @@
1.421
1.422 static const char* ggp_list_emblem(PurpleBuddy *buddy)
1.423 {
1.424 - ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
1.425 -
1.426 - if (!buddy_data)
1.427 - return NULL;
1.428 + ggp_buddy_data *buddy_data = ggp_buddy_get_data(buddy);
1.429
1.430 if (buddy_data->blocked)
1.431 return "not-authorized";
1.432 @@ -1981,18 +1715,6 @@
1.433 return NULL;
1.434 }
1.435
1.436 -static void ggp_buddy_free(PurpleBuddy *buddy)
1.437 -{
1.438 - ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
1.439 -
1.440 - if (!buddy_data)
1.441 - return;
1.442 -
1.443 - g_free(buddy_data);
1.444 -
1.445 - purple_buddy_set_protocol_data(buddy, NULL);
1.446 -}
1.447 -
1.448 static gboolean ggp_offline_message(const PurpleBuddy *buddy)
1.449 {
1.450 return TRUE;
1.451 @@ -2015,7 +1737,7 @@
1.452 {"png", 1, 1, 200, 200, 0, PURPLE_ICON_SCALE_DISPLAY | PURPLE_ICON_SCALE_SEND}, /* icon_spec */
1.453 ggp_list_icon, /* list_icon */
1.454 ggp_list_emblem, /* list_emblem */
1.455 - ggp_status_text, /* status_text */
1.456 + ggp_status_buddy_text, /* status_text */
1.457 ggp_tooltip_text, /* tooltip_text */
1.458 ggp_status_types, /* status_types */
1.459 ggp_blist_node_menu, /* blist_node_menu */
2.1 --- a/libpurple/protocols/gg/gg.h
2.2 +++ b/libpurple/protocols/gg/gg.h
2.3 @@ -63,6 +63,13 @@
2.4 ggp_status_session_data *status_data;
2.5 } GGPInfo;
2.6
2.7 +typedef struct
2.8 +{
2.9 + gboolean blocked;
2.10 +} ggp_buddy_data;
2.11 +
2.12 void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *ev, gboolean multilogon);
2.13
2.14 +ggp_buddy_data * ggp_buddy_get_data(PurpleBuddy *buddy);
2.15 +
2.16 #endif /* _PURPLE_GG_H */
3.1 --- a/libpurple/protocols/gg/status.c
3.2 +++ b/libpurple/protocols/gg/status.c
3.3 @@ -16,7 +16,7 @@
3.4 static inline ggp_status_session_data *
3.5 ggp_status_get_ssdata(PurpleConnection *gc);
3.6
3.7 -gchar * ggp_status_validate_description(const gchar* msg);
3.8 +static gchar * ggp_status_validate_description(const gchar* msg);
3.9 static int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message);
3.10
3.11 ////
3.12 @@ -47,7 +47,7 @@
3.13 g_free(ssdata);
3.14 }
3.15
3.16 -gchar * ggp_status_validate_description(const gchar* msg)
3.17 +static gchar * ggp_status_validate_description(const gchar* msg)
3.18 {
3.19 if (msg == NULL || msg[0] == '\0')
3.20 return NULL;
3.21 @@ -55,6 +55,43 @@
3.22 return ggp_utf8_strndup(msg, GG_STATUS_DESCR_MAXSIZE);
3.23 }
3.24
3.25 +GList * ggp_status_types(PurpleAccount *account)
3.26 +{
3.27 + GList *types = NULL;
3.28 +
3.29 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.30 + PURPLE_STATUS_AVAILABLE, NULL, NULL,
3.31 + TRUE, TRUE, FALSE, "message", _("Message"),
3.32 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.33 +
3.34 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.35 + PURPLE_STATUS_AVAILABLE, "freeforchat", _("Chatty"),
3.36 + TRUE, TRUE, FALSE, "message", _("Message"),
3.37 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.38 +
3.39 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.40 + PURPLE_STATUS_AWAY, NULL, NULL,
3.41 + TRUE, TRUE, FALSE, "message", _("Message"),
3.42 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.43 +
3.44 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.45 + PURPLE_STATUS_UNAVAILABLE, NULL, NULL,
3.46 + TRUE, TRUE, FALSE, "message", _("Message"),
3.47 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.48 +
3.49 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.50 + PURPLE_STATUS_INVISIBLE, NULL, NULL,
3.51 + TRUE, TRUE, FALSE, "message", _("Message"),
3.52 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.53 +
3.54 + types = g_list_append(types, purple_status_type_new_with_attrs(
3.55 + PURPLE_STATUS_OFFLINE, NULL, NULL,
3.56 + TRUE, TRUE, FALSE, "message", _("Message"),
3.57 + purple_value_new(PURPLE_TYPE_STRING), NULL));
3.58 +
3.59 + return types;
3.60 +}
3.61 +
3.62 static int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message)
3.63 {
3.64 const char *status_id = purple_status_get_id(status);
3.65 @@ -91,6 +128,41 @@
3.66 return status_message ? GG_STATUS_AVAIL_DESCR : GG_STATUS_AVAIL;
3.67 }
3.68
3.69 +const gchar * ggp_status_to_purplestatus(int status)
3.70 +{
3.71 + switch (status)
3.72 + {
3.73 + case GG_STATUS_NOT_AVAIL:
3.74 + case GG_STATUS_NOT_AVAIL_DESCR:
3.75 + case GG_STATUS_BLOCKED:
3.76 + return purple_primitive_get_id_from_type(
3.77 + PURPLE_STATUS_OFFLINE);
3.78 + case GG_STATUS_FFC:
3.79 + case GG_STATUS_FFC_DESCR:
3.80 + return "freeforchat";
3.81 + case GG_STATUS_AVAIL:
3.82 + case GG_STATUS_AVAIL_DESCR:
3.83 + return purple_primitive_get_id_from_type(
3.84 + PURPLE_STATUS_AVAILABLE);
3.85 + case GG_STATUS_BUSY:
3.86 + case GG_STATUS_BUSY_DESCR:
3.87 + return purple_primitive_get_id_from_type(
3.88 + PURPLE_STATUS_AWAY);
3.89 + case GG_STATUS_INVISIBLE:
3.90 + case GG_STATUS_INVISIBLE_DESCR:
3.91 + return purple_primitive_get_id_from_type(
3.92 + PURPLE_STATUS_INVISIBLE);
3.93 + case GG_STATUS_DND:
3.94 + case GG_STATUS_DND_DESCR:
3.95 + return purple_primitive_get_id_from_type(
3.96 + PURPLE_STATUS_UNAVAILABLE);
3.97 + default:
3.98 + purple_debug_warning("gg", "ggp_status_to_purplestatus: unknown status %d\n", status);
3.99 + return purple_primitive_get_id_from_type(
3.100 + PURPLE_STATUS_AVAILABLE);
3.101 + }
3.102 +}
3.103 +
3.104 /*******************************************************************************
3.105 * Own status.
3.106 ******************************************************************************/
3.107 @@ -155,6 +227,39 @@
3.108 g_free(msg);
3.109 }
3.110
3.111 +void ggp_status_set_disconnected(PurpleAccount *account)
3.112 +{
3.113 + gchar *msg = NULL;
3.114 +
3.115 + ggp_status_from_purplestatus(purple_account_get_active_status(account),
3.116 + &msg);
3.117 + if (!ggp_status_set(account,
3.118 + msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL, msg))
3.119 + {
3.120 + g_free(msg);
3.121 + return;
3.122 + }
3.123 +
3.124 + /*
3.125 + struct gg_event *ev;
3.126 + guint64 wait_start = ggp_microtime(), now;
3.127 + int sleep_time = 5000;
3.128 + while ((ev = gg_watch_fd(info->session)) != NULL)
3.129 + {
3.130 + if (ev->type == GG_EVENT_DISCONNECT_ACK)
3.131 + break;
3.132 + now = ggp_microtime();
3.133 + if (now - wait_start + sleep_time >= 100000)
3.134 + break;
3.135 + usleep(sleep_time);
3.136 + sleep_time *= 2;
3.137 + }
3.138 + */
3.139 + usleep(100000);
3.140 +
3.141 + g_free(msg);
3.142 +}
3.143 +
3.144 void ggp_status_fake_to_self(PurpleConnection *gc)
3.145 {
3.146 PurpleAccount *account = purple_connection_get_account(gc);
3.147 @@ -226,3 +331,104 @@
3.148 ggp_status_set_status_broadcasting(gc,
3.149 !purple_request_fields_get_bool(fields, "buddies_only"));
3.150 }
3.151 +
3.152 +/*******************************************************************************
3.153 + * Buddy status.
3.154 + ******************************************************************************/
3.155 +
3.156 +void ggp_status_got_others_buddy(PurpleConnection *gc, uin_t uin, int status,
3.157 + const char *descr);
3.158 +
3.159 +/******************************************************************************/
3.160 +
3.161 +void ggp_status_got_others(PurpleConnection *gc, struct gg_event *ev)
3.162 +{
3.163 + if (ev->type == GG_EVENT_NOTIFY60)
3.164 + {
3.165 + struct gg_event_notify60 *notify = ev->event.notify60;
3.166 + int i;
3.167 + for (i = 0; notify[i].uin; i++)
3.168 + ggp_status_got_others_buddy(gc, notify[i].uin,
3.169 + GG_S(notify[i].status), notify[i].descr);
3.170 + }
3.171 + else if (ev->type == GG_EVENT_STATUS60)
3.172 + {
3.173 + struct gg_event_status60 *notify = &ev->event.status60;
3.174 + ggp_status_got_others_buddy(gc, notify->uin,
3.175 + GG_S(notify->status), notify->descr);
3.176 + }
3.177 + else
3.178 + purple_debug_fatal("gg", "ggp_status_got_others: "
3.179 + "unexpected event %d\n", ev->type);
3.180 +}
3.181 +
3.182 +void ggp_status_got_others_buddy(PurpleConnection *gc, uin_t uin, int status,
3.183 + const char *descr)
3.184 +{
3.185 + PurpleAccount *account = purple_connection_get_account(gc);
3.186 + PurpleBuddy *buddy = purple_find_buddy(account, ggp_uin_to_str(uin));
3.187 + const gchar *purple_status = ggp_status_to_purplestatus(status);
3.188 + gchar *status_message = NULL;
3.189 +
3.190 + if (!buddy)
3.191 + {
3.192 + purple_debug_warning("gg", "ggp_status_got_others_buddy: "
3.193 + "buddy %u not found\n", uin);
3.194 + return;
3.195 + }
3.196 + ggp_buddy_get_data(buddy)->blocked = (status == GG_STATUS_BLOCKED);
3.197 +
3.198 + if (descr != NULL)
3.199 + {
3.200 + status_message = g_strdup(descr);
3.201 + g_strstrip(status_message);
3.202 + if (status_message[0] == '\0')
3.203 + {
3.204 + g_free(status_message);
3.205 + status_message = NULL;
3.206 + }
3.207 + }
3.208 +
3.209 + if (uin == ggp_str_to_uin(purple_account_get_username(account)))
3.210 + {
3.211 + purple_debug_info("gg", "ggp_status_got_others_buddy: "
3.212 + "own status changed to %s [%s]\n",
3.213 + purple_status, status_message ? status_message : "");
3.214 + }
3.215 + else
3.216 + {
3.217 + purple_debug_misc("gg", "ggp_status_got_others_buddy: "
3.218 + "status of %u changed to %s [%s]\n", uin,
3.219 + purple_status, status_message ? status_message : "");
3.220 + }
3.221 +
3.222 + if (status_message)
3.223 + {
3.224 + purple_prpl_got_user_status(account, ggp_uin_to_str(uin),
3.225 + purple_status, "message", status_message, NULL);
3.226 + }
3.227 + else
3.228 + {
3.229 + purple_prpl_got_user_status(account, ggp_uin_to_str(uin),
3.230 + purple_status, NULL);
3.231 + }
3.232 +
3.233 + g_free(status_message);
3.234 +}
3.235 +
3.236 +char * ggp_status_buddy_text(PurpleBuddy *buddy)
3.237 +{
3.238 + ggp_buddy_data *buddy_data = ggp_buddy_get_data(buddy);
3.239 + const gchar *purple_message;
3.240 +
3.241 + if (buddy_data->blocked)
3.242 + return g_strdup(_("Blocked"));
3.243 +
3.244 + purple_message = purple_status_get_attr_string(
3.245 + purple_presence_get_active_status(
3.246 + purple_buddy_get_presence(buddy)), "message");
3.247 + if (!purple_message)
3.248 + return NULL;
3.249 +
3.250 + return g_markup_escape_text(purple_message, -1);
3.251 +}
4.1 --- a/libpurple/protocols/gg/status.h
4.2 +++ b/libpurple/protocols/gg/status.h
4.3 @@ -9,12 +9,16 @@
4.4 void ggp_status_setup(PurpleConnection *gc);
4.5 void ggp_status_cleanup(PurpleConnection *gc);
4.6
4.7 +GList * ggp_status_types(PurpleAccount *account);
4.8 +const gchar * ggp_status_to_purplestatus(int status);
4.9 +
4.10 // own status
4.11
4.12 void ggp_status_set_initial(PurpleConnection *gc, struct gg_login_params *glp);
4.13
4.14 gboolean ggp_status_set(PurpleAccount *account, int status, const gchar* msg);
4.15 void ggp_status_set_purplestatus(PurpleAccount *account, PurpleStatus *status);
4.16 +void ggp_status_set_disconnected(PurpleAccount *account);
4.17 void ggp_status_fake_to_self(PurpleConnection *gc);
4.18
4.19 gboolean ggp_status_get_status_broadcasting(PurpleConnection *gc);
4.20 @@ -22,4 +26,9 @@
4.21 gboolean broadcasting);
4.22 void ggp_status_broadcasting_dialog(PurpleConnection *gc);
4.23
4.24 +// buddy status
4.25 +
4.26 +void ggp_status_got_others(PurpleConnection *gc, struct gg_event *ev);
4.27 +char * ggp_status_buddy_text(PurpleBuddy *buddy);
4.28 +
4.29 #endif /* _GGP_STATUS_H */