📄 gg.c
字号:
*//* static void ggp_bmenu_block(PurpleBlistNode *node, gpointer ignored) {{{ */static void ggp_bmenu_block(PurpleBlistNode *node, gpointer ignored){ PurpleConnection *gc; PurpleBuddy *buddy; GGPInfo *info; uin_t uin; buddy = (PurpleBuddy *)node; gc = purple_account_get_connection(purple_buddy_get_account(buddy)); info = gc->proto_data; uin = ggp_str_to_uin(purple_buddy_get_name(buddy)); if (purple_blist_node_get_bool(node, "blocked")) { purple_blist_node_set_bool(node, "blocked", FALSE); gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED); gg_add_notify_ex(info->session, uin, GG_USER_NORMAL); purple_debug_info("gg", "send: uin=%d; mode=NORMAL\n", uin); } else { purple_blist_node_set_bool(node, "blocked", TRUE); gg_remove_notify_ex(info->session, uin, GG_USER_NORMAL); gg_add_notify_ex(info->session, uin, GG_USER_BLOCKED); purple_debug_info("gg", "send: uin=%d; mode=BLOCKED\n", uin); }}/* }}} *//* ---------------------------------------------------------------------- *//* ----- INTERNAL CALLBACKS --------------------------------------------- *//* ---------------------------------------------------------------------- *//* just a prototype */static void ggp_set_status(PurpleAccount *account, PurpleStatus *status);/** * Handle change of the status of the buddy. * * @param gc PurpleConnection * @param uin UIN of the buddy. * @param status ID of the status. * @param descr Description. *//* static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin, int status, const char *descr) {{{ */static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin, int status, const char *descr){ gchar *from; const char *st; gchar *msg; from = g_strdup_printf("%ld", (unsigned long int)uin); switch (status) { case GG_STATUS_NOT_AVAIL: case GG_STATUS_NOT_AVAIL_DESCR: st = "offline"; break; case GG_STATUS_AVAIL: case GG_STATUS_AVAIL_DESCR: st = "available"; break; case GG_STATUS_BUSY: case GG_STATUS_BUSY_DESCR: st = "away"; break; case GG_STATUS_BLOCKED: /* user is blocking us.... */ st = "blocked"; break; default: st = "available"; purple_debug_info("gg", "GG_EVENT_NOTIFY: Unknown status: %d\n", status); break; } purple_debug_info("gg", "st = %s\n", st); msg = charset_convert(descr, "CP1250", "UTF-8"); purple_prpl_got_user_status(purple_connection_get_account(gc), from, st, "message", msg, NULL); g_free(from); g_free(msg);}/* }}} *//* *//* static void ggp_sr_close_cb(gpointer user_data) {{{ */static void ggp_sr_close_cb(gpointer user_data){ GGPSearchForm *form = user_data; GGPInfo *info = form->user_data; ggp_search_remove(info->searches, form->seq); ggp_search_form_destroy(form);}/* }}} *//** * Translate a status' ID to a more user-friendly name. * * @param id The ID of the status. * * @return The user-friendly name of the status. *//* static const char *ggp_status_by_id(unsigned int id) {{{ */static const char *ggp_status_by_id(unsigned int id){ const char *st; purple_debug_info("gg", "ggp_status_by_id: %d\n", id); switch (id) { case GG_STATUS_NOT_AVAIL: st = _("Offline"); break; case GG_STATUS_AVAIL: st = _("Available"); break; case GG_STATUS_BUSY: st = _("Away"); break; default: st = _("Unknown"); break; } return st;}/* }}} *//* *//* static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form) {{{ */static void ggp_pubdir_handle_info(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form){ PurpleNotifyUserInfo *user_info; PurpleBuddy *buddy; char *val, *who; user_info = purple_notify_user_info_new(); val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS); /* XXX: Use of ggp_str_to_uin() is an ugly hack! */ purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); g_free(val); who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN); purple_notify_user_info_add_pair(user_info, _("UIN"), who); val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME); purple_notify_user_info_add_pair(user_info, _("First Name"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME); purple_notify_user_info_add_pair(user_info, _("Nickname"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY); purple_notify_user_info_add_pair(user_info, _("City"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR); if (strncmp(val, "0", 1)) { purple_notify_user_info_add_pair(user_info, _("Birth Year"), val); } g_free(val); /* * Include a status message, if exists and buddy is in the blist. */ buddy = purple_find_buddy(purple_connection_get_account(gc), who); if (NULL != buddy) { PurpleStatus *status; const char *msg; char *text; status = purple_presence_get_active_status(purple_buddy_get_presence(buddy)); msg = purple_status_get_attr_string(status, "message"); if (msg != NULL) { text = g_markup_escape_text(msg, -1); purple_notify_user_info_add_pair(user_info, _("Message"), text); g_free(text); } } val = ggp_buddy_get_name(gc, ggp_str_to_uin(who)); purple_notify_userinfo(gc, val, user_info, ggp_sr_close_cb, form); g_free(val); g_free(who); purple_notify_user_info_destroy(user_info);}/* }}} *//* *//* static void ggp_pubdir_handle_full(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form) {{{ */static void ggp_pubdir_handle_full(PurpleConnection *gc, gg_pubdir50_t req, GGPSearchForm *form){ PurpleNotifySearchResults *results; PurpleNotifySearchColumn *column; int res_count; int start; int i; g_return_if_fail(form != NULL); res_count = gg_pubdir50_count(req); res_count = (res_count > PUBDIR_RESULTS_MAX) ? PUBDIR_RESULTS_MAX : res_count; results = purple_notify_searchresults_new(); if (results == NULL) { purple_debug_error("gg", "ggp_pubdir_reply_handler: " "Unable to display the search results.\n"); purple_notify_error(gc, NULL, _("Unable to display the search results."), NULL); ggp_sr_close_cb(form); return; } column = purple_notify_searchresults_column_new(_("UIN")); purple_notify_searchresults_column_add(results, column); column = purple_notify_searchresults_column_new(_("First Name")); purple_notify_searchresults_column_add(results, column); column = purple_notify_searchresults_column_new(_("Nickname")); purple_notify_searchresults_column_add(results, column); column = purple_notify_searchresults_column_new(_("City")); purple_notify_searchresults_column_add(results, column); column = purple_notify_searchresults_column_new(_("Birth Year")); purple_notify_searchresults_column_add(results, column); purple_debug_info("gg", "Going with %d entries\n", res_count); start = (int)ggp_str_to_uin(gg_pubdir50_get(req, 0, GG_PUBDIR50_START)); purple_debug_info("gg", "start = %d\n", start); for (i = 0; i < res_count; i++) { GList *row = NULL; char *birth = ggp_search_get_result(req, i, GG_PUBDIR50_BIRTHYEAR); /* TODO: Status will be displayed as an icon. */ /* row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_STATUS)); */ row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_UIN)); row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_FIRSTNAME)); row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_NICKNAME)); row = g_list_append(row, ggp_search_get_result(req, i, GG_PUBDIR50_CITY)); row = g_list_append(row, (birth && strncmp(birth, "0", 1)) ? birth : g_strdup("-")); purple_notify_searchresults_row_add(results, row); if (i == res_count - 1) { g_free(form->last_uin); form->last_uin = ggp_search_get_result(req, i, GG_PUBDIR50_UIN); } } purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_CONTINUE, ggp_callback_show_next); purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_ADD, ggp_callback_add_buddy); purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_IM, ggp_callback_im); if (form->window == NULL) { void *h = purple_notify_searchresults(gc, _("Gadu-Gadu Public Directory"), _("Search results"), NULL, results, (PurpleNotifyCloseCallback)ggp_sr_close_cb, form); if (h == NULL) { purple_debug_error("gg", "ggp_pubdir_reply_handler: " "Unable to display the search results.\n"); purple_notify_error(gc, NULL, _("Unable to display the search results."), NULL); return; } form->window = h; } else { purple_notify_searchresults_new_rows(gc, results, form->window); }}/* }}} *//* *//* static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req) {{{ */static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req){ GGPInfo *info = gc->proto_data; GGPSearchForm *form; int res_count; guint32 seq; seq = gg_pubdir50_seq(req); form = ggp_search_get(info->searches, seq); /* * this can happen when user will request more results * and close the results window before they arrive. */ g_return_if_fail(form != NULL); res_count = gg_pubdir50_count(req); if (res_count < 1) { purple_debug_info("gg", "GG_EVENT_PUBDIR50_SEARCH_REPLY: Nothing found\n"); purple_notify_error(gc, NULL, _("No matching users found"), _("There are no users matching your search criteria.")); ggp_sr_close_cb(form); return; } switch (form->search_type) { case GGP_SEARCH_TYPE_INFO: ggp_pubdir_handle_info(gc, req, form); break; case GGP_SEARCH_TYPE_FULL: ggp_pubdir_handle_full(gc, req, form); break; default: purple_debug_warning("gg", "Unknown search_type!\n"); break; }}/* }}} *//** * Dispatch a message received from a buddy. * * @param gc PurpleConnection. * @param ev Gadu-Gadu event structure. *//* static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev) {{{ */static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev){ GGPInfo *info = gc->proto_data; PurpleConversation *conv; gchar *from; gchar *msg; gchar *tmp; from = g_strdup_printf("%lu", (unsigned long int)ev->event.msg.sender); tmp = charset_convert((const char *)ev->event.msg.message, "CP1250", "UTF-8"); purple_str_strip_char(tmp, '\r'); msg = g_markup_escape_text(tmp, -1); g_free(tmp); purple_debug_info("gg", "msg form (%s): %s (class = %d; rcpt_count = %d)\n", from, msg, ev->event.msg.msgclass, ev->event.msg.recipients_count); if (ev->event.msg.recipients_count == 0) { serv_got_im(gc, from, msg, 0, ev->event.msg.time); } else { const char *chat_name; int chat_id; char *buddy_name; chat_name = ggp_confer_find_by_participants(gc, ev->event.msg.recipients, ev->event.msg.recipients_count); if (chat_name == NULL) { chat_name = ggp_confer_add_new(gc, NULL); serv_got_joined_chat(gc, info->chats_count, chat_name); ggp_confer_participants_add_uin(gc, chat_name, ev->event.msg.sender); ggp_confer_participants_add(gc, chat_name, ev->event.msg.recipients, ev->event.msg.recipients_count); } conv = ggp_confer_find_by_name(gc, chat_name); chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)); 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); g_free(buddy_name); } g_free(msg); g_free(from);}/* }}} *//* *//* static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond) {{{ */static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond){ PurpleConnection *gc = _gc; GGPInfo *info = gc->proto_data; struct gg_event *ev; int i; if (!(ev = gg_watch_fd(info->session))) { purple_debug_error("gg", "ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n"); purple_connection_error(gc, _("Unable to read socket")); return; } switch (ev->type) { case GG_EVENT_NONE: /* Nothing happened. */ break; case GG_EVENT_MSG: ggp_recv_message_handler(gc, ev); break; case GG_EVENT_ACK: purple_debug_info("gg", "message sent to: %ld, delivery status=%d, seq=%d\n", ev->event.ack.recipient, ev->event.ack.status, ev->event.ack.seq); break; case GG_EVENT_NOTIFY: case GG_EVENT_NOTIFY_DESCR: { struct gg_notify_reply *n; char *descr; purple_debug_info("gg", "notify_pre: (%d) status: %d\n", ev->event.notify->uin, ev->event.notify->status);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -