Beispiel #1
0
void
hybrid_conv_clear_input(HybridAccount *account, const gchar *buddy_id)
{
    HybridBuddy      *buddy;
    HybridChatWindow *chat;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        return;
    }

    if (chat->input_source) {
        g_source_remove(chat->input_source);
    }

    text_ops->notify(chat->textview, "" , MSG_NOTIFICATION_INPUT);
}
Beispiel #2
0
void
fetion_update_portrait(fetion_account *ac, fetion_buddy *buddy)
{
	portrait_data *data;
	HybridBuddy *hybrid_buddy;
	const gchar *checksum;

	g_return_if_fail(ac != NULL);
	g_return_if_fail(buddy != NULL);

	data = g_new0(portrait_data, 1);
	data->buddy = buddy;
	data->ac = ac;
	data->portrait_type = PORTRAIT_TYPE_BUDDY;

	if (!(hybrid_buddy = hybrid_blist_find_buddy(ac->account, buddy->userid))) {
		hybrid_debug_error("fetion", "FATAL, update portrait,"
				" unable to find a buddy.");
		return;
	}

	checksum = hybrid_blist_get_buddy_checksum(hybrid_buddy);

	if (checksum != NULL && g_strcmp0(checksum, buddy->portrait_crc) == 0) {
		hybrid_debug_info("fetion", "portrait for %s(%s) up to date",
		buddy->nickname && *(buddy->nickname) != '\0' ? buddy->nickname : buddy->userid,
		buddy->portrait_crc);
		return;
	}

	hybrid_proxy_connect(ac->portrait_host_name, 80, portrait_conn_cb, data);
}
Beispiel #3
0
void
hybrid_conv_got_status(HybridAccount *account, const gchar *buddy_id, const gchar *text, gint type)
{
    HybridChatWindow *chat;
    HybridBuddy      *buddy;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        /*
         * Well, we haven't find an existing chat panel so far, check the type
         * to determine whether to create a new one.
         */
        if (type == MSG_NOTIFICATION_INPUT) {
            return;

        } else {
            chat = hybrid_chat_window_create(account, buddy->id, HYBRID_CHAT_PANEL_SYSTEM);
        }
    }

    if (type == MSG_NOTIFICATION_INPUT) {
        text_ops->notify(chat->textview, text, MSG_NOTIFICATION_INPUT);
    }

}
Beispiel #4
0
/**
 * Process the synchronization message, when the contact list or the personal info
 * changed, the server will push this message to tell the client to update its
 * local cache file, well, we will not update the local cache file, we keep the
 * old version numbers, and reload it after the next logining.
 */
static void
process_sync_info(fetion_account *ac, const gchar *sipmsg)
{
    GSList       *list;
    gchar        *sid;
    fetion_buddy *buddy;
    HybridBuddy  *hb;

    hybrid_debug_info("fetion", "sync info,recv:\n%s", sipmsg);

    if (!(list = sip_parse_sync(ac, sipmsg))) {
        return;
    }

    while (list) {
        buddy = (fetion_buddy*)list->data;

        list = g_slist_remove(list, buddy);

        if (buddy->status == 0) {
            continue;
        }

        if (!(hb = hybrid_blist_find_buddy(ac->account, buddy->userid))) {
            continue;
        }

        if (buddy->status == 1) {

            hybrid_blist_set_buddy_status(hb, TRUE);

        } else {
            hybrid_blist_set_buddy_status(hb, FALSE);
        }

        sid = get_sid_from_sipuri(buddy->sipuri);

        hybrid_message_box_show(HYBRID_MESSAGE_INFO,
                _("Buddy <b>%s</b> has %s your add-buddy request."),
                buddy->localname && *(buddy->localname) != '\0' ?
                buddy->localname : sid,
                buddy->status == 1 ? _("accepted") : _("declined"));
    }

}
Beispiel #5
0
/**
 * Process "presence changed" message.
 */
static void
process_presence(fetion_account *ac, const gchar *sipmsg)
{
    GSList       *list;
    GSList       *pos;
    fetion_buddy *buddy;
    HybridBuddy  *imbuddy;

    list = sip_parse_presence(ac, sipmsg);

    for (pos = list; pos; pos = pos->next) {

        buddy   = (fetion_buddy*)pos->data;
        imbuddy = hybrid_blist_find_buddy(ac->account, buddy->userid);

        if (buddy->localname && *(buddy->localname) != '\0') {
            hybrid_blist_set_buddy_name(imbuddy, buddy->localname);
        }
        hybrid_blist_set_buddy_mood(imbuddy, buddy->mood_phrase);

        switch (buddy->state) {
            case P_ONLINE:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_ONLINE);
                break;
            case P_OFFLINE:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_OFFLINE);
                break;
            case P_INVISIBLE:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_OFFLINE);
                break;
            case P_AWAY:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_AWAY);
                break;
            case P_BUSY:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_BUSY);
                break;
            default:
                hybrid_blist_set_buddy_state(imbuddy, HYBRID_STATE_AWAY);
                break;
        }

        fetion_update_portrait(ac, buddy);
    }
}
Beispiel #6
0
void
hybrid_conv_got_input(HybridAccount *account, const gchar *buddy_id, gboolean auto_stop)
{
    HybridBuddy      *buddy;
    HybridChatWindow *chat;
    gchar            *text;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        return;
    }

    text = g_strdup_printf(_(" %s is typing..."), buddy->name);

    text_ops->notify(chat->textview, text , MSG_NOTIFICATION_INPUT);

    g_free(text);

    if (!auto_stop) {
        return;
    }

    if (chat->input_source) {
        g_source_remove(chat->input_source);
    }

    chat->input_source =
        g_timeout_add_seconds(4, (GSourceFunc)(input_finished_cb), chat);
}
Beispiel #7
0
void
hybrid_conv_stop_input(HybridAccount *account, const gchar *buddy_id)
{
    HybridBuddy      *buddy;
    HybridChatWindow *chat;
    gchar            *text;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        return;
    }

    text = g_strdup_printf(_(" %s stopped typing"), buddy->name);
    text_ops->notify(chat->textview, text , MSG_NOTIFICATION_INPUT);
    g_free(text);
}
Beispiel #8
0
void
hybrid_conv_got_message(HybridAccount *account,
                const gchar *buddy_id, const gchar *message,
                time_t time)
{
    HybridConversation *conv;
    HybridChatWindow   *chat;
    HybridBuddy        *buddy;
    gchar              *msg;
    gchar              *notify_msg;
    GdkPixbuf          *pixbuf;

    gint current_page;
    gint chat_page;

    msg = hybrid_strip_html(message);

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);
    g_return_if_fail(message != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        g_free(msg);

        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {

        /* Well, we haven't find an existing chat panel so far, so create one. */
        chat = hybrid_chat_window_create(account, buddy->id,
                HYBRID_CHAT_PANEL_SYSTEM);
    }

    /* check whether the chat window is active. */
    conv = chat->parent;
    if (gtk_window_is_active(GTK_WINDOW(conv->window))) {

        current_page = gtk_notebook_current_page(GTK_NOTEBOOK(conv->notebook));
        chat_page = gtk_notebook_page_num(GTK_NOTEBOOK(conv->notebook), chat->vbox);

        if (current_page == chat_page) {
            goto just_show_msg;
        }
    }

    /* change the callback function of the status icon's activate signal. */
    hybrid_status_icon_blinking(buddy);

    /* notify. */
    notify_msg = g_strdup_printf(_("%s said:"),
            buddy->name && *buddy->name ? buddy->name : buddy->id);
    pixbuf = hybrid_create_round_pixbuf(buddy->icon_data,
                                  buddy->icon_data_length, 48);

    hybrid_notify_popup(pixbuf, notify_msg, msg);

    g_object_unref(pixbuf);
    g_free(notify_msg);

    chat->unread ++;

    hybrid_chat_window_update_tips(chat);

just_show_msg:

    hybrid_sound_play_file(SOUND_DIR"newmessage.wav");

    text_ops->append(chat->textview, buddy->account, buddy, msg, time);
    hybrid_logs_write(chat->logs, buddy->name, msg, FALSE);

    g_free(msg);
}
Beispiel #9
0
HybridChatWindow*
hybrid_chat_window_create(HybridAccount *account, const gchar *id,
                          HybridChatWindowType type)
{
    HybridChatWindow   *chat = NULL;
    HybridConversation *conv = NULL;
    HybridBuddy        *buddy;
    HybridModule       *proto;
    HybridIMOps        *ops;

    g_return_val_if_fail(account != NULL, NULL);
    g_return_val_if_fail(id != NULL, NULL);

    if (type == HYBRID_CHAT_PANEL_SYSTEM) {
        if (!(buddy = (hybrid_blist_find_buddy(account, id)))) {
            hybrid_debug_error("conv", "FATAL, can't find buddy");
            return NULL;
        }

        proto = account->proto;
        ops = proto->info->im_ops;

        /* we will check whether the protocol allows this buddy to be activated. */
        if (ops->chat_start) {
            if (!ops->chat_start(account, buddy)) {
                return NULL;
            }
        }
    }

    if ((chat = hybrid_conv_find_chat(id))) {
        conv = chat->parent;
        goto found;
    }

    /*
     * Whether to show the chat dialog in a single window.
     */
    if (hybrid_pref_get_boolean(NULL, "single_chat_window")) {

        if (!conv_list) {
            conv = hybrid_conv_create();
            conv_list = g_slist_append(conv_list, conv);

        } else {
            conv = conv_list->data;
        }

    } else {

        conv = hybrid_conv_create();
        conv_list = g_slist_append(conv_list, conv);
    }

    chat          = g_new0(HybridChatWindow, 1);
    chat->id      = g_strdup(id);
    chat->parent  = conv;
    chat->account = account;
    chat->type    = type;
    chat->logs    = hybrid_logs_create(account, id);

    if (type == HYBRID_CHAT_PANEL_SYSTEM) {
        chat->data = buddy;
    }

    conv->chat_buddies = g_slist_append(conv->chat_buddies, chat);

    init_chat_window(chat);
    return chat;

found:
    gtk_notebook_set_current_page(GTK_NOTEBOOK(conv->notebook),
        gtk_notebook_page_num(GTK_NOTEBOOK(conv->notebook), chat->vbox));

    /* focus the send textview */
    gtk_widget_grab_focus(chat->sendtext);
    gtk_window_present(GTK_WINDOW(chat->parent->window));

    return chat;
}
Beispiel #10
0
void
hybrid_info_notify(HybridAccount *account, HybridNotifyInfo *info,
        const gchar *buddy_id)
{
    GtkTreeIter iter;
    GtkTreeModel *model;
    HybridBuddy *buddy;
    HybridInfo *info_panel;
    HybridInfoItem *item;
    GSList *info_pos;
    GSList *pos;
    gchar *name_markup;
    gchar *name_escaped;
    gchar *value_escaped;

    g_return_if_fail(info != NULL);

    for (info_pos = info_list; info_pos; info_pos = info_pos->next) {

        info_panel = (HybridInfo*)info_pos->data;

        if (g_strcmp0(info_panel->buddy->id, buddy_id) == 0) {
            goto buddy_ok;
        }

    }

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("info", "can not find buddy with id :\'%s\'",
                buddy_id);

        return;
    }

    info_panel = hybrid_info_create(buddy);

buddy_ok:

    model = gtk_tree_view_get_model(GTK_TREE_VIEW(info_panel->treeview));

    for (pos = info->item_list; pos; pos = pos->next) {

        item = (HybridInfoItem*)pos->data;

        name_escaped = g_markup_escape_text(item->name, -1);

        if (item->value) {
            value_escaped = g_markup_escape_text(item->value, -1);

        } else {
            value_escaped = NULL;
        }

        name_markup = g_strdup_printf("<b>%s:</b>", name_escaped);

        gtk_list_store_append(GTK_LIST_STORE(model), &iter);
        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
                HYBRID_INFO_NAME_COLUMN, name_markup,
                HYBRID_INFO_VALUE_COLUMN, value_escaped,
                HYBRID_INFO_PIXBUF_COLUMN, item->pixbuf,
                HYBRID_INFO_VALUE_COLUMN_VISIBLE,
                item->type == HYBRID_INFO_ITEM_TYPE_TEXT ? TRUE : FALSE,
                HYBRID_INFO_PIXBUF_COLUMN_VISIBLE,
                item->type == HYBRID_INFO_ITEM_TYPE_PIXBUF ? TRUE : FALSE,
                -1);

        g_free(name_markup);
        g_free(name_escaped);
        g_free(value_escaped);

    }
}
Beispiel #11
0
/**
 * Callback function to handle the portrait receive event.
 */
static gboolean
portrait_recv_cb(gint sk, gpointer user_data)
{
	gchar buf[BUF_LENGTH];
	gint n;
	gchar *pos;
	HybridBuddy *imbuddy;
	portrait_trans *trans = (portrait_trans*)user_data;

	if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) {
		hybrid_debug_error("fetion", "get portrait for \'%s\':%s",
				trans->buddy ? trans->buddy->sid : trans->ac->sid, 
				strerror(errno));
		return FALSE;
	}

	buf[n] = '\0';

	if (n == 0) {

		if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) {
			imbuddy = hybrid_blist_find_buddy(trans->ac->account,
					trans->buddy->userid);
		}

		if (hybrid_get_http_code(trans->data) != 200) {
			/* 
			 * Note that we got no portrait, but we still need
			 * to set buddy icon, just for the portrait checksum, we 
			 * set it default to "0" instead of leaving it NULL,
			 * so that in the next login, we just check the changes
			 * of the buddy's checksum to determine whether to fetch a 
			 * portrait from the server. 
			 */
			if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) {
				hybrid_blist_set_buddy_icon(imbuddy, NULL, 0,
						trans->buddy->portrait_crc);

			} else {
				hybrid_account_set_icon(trans->ac->account, NULL,
						0, trans->ac->portrait_crc);
			}

			goto pt_fin;
		}

		trans->data_len = hybrid_get_http_length(trans->data);

		if (!(pos = strstr(trans->data, "\r\n\r\n"))) {
			goto pt_fin;
		}

		pos += 4;

		if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { /**< buddy portrait */
			hybrid_blist_set_buddy_icon(imbuddy, (guchar*)pos,
					trans->data_len, trans->buddy->portrait_crc);

		} else {
			hybrid_account_set_icon(trans->ac->account, (guchar*)pos,
					trans->data_len, trans->ac->portrait_crc);
		}

		goto pt_fin;

	} else {
		trans->data = realloc(trans->data, trans->data_size + n);
		memcpy(trans->data + trans->data_size, buf, n);
		trans->data_size += n;
	}

	return TRUE;

pt_fin:
	g_free(trans->data);
	g_free(trans);

	return FALSE;
}
Beispiel #12
0
/**
 * Callback function for the get_info transaction.
 */
static gint
get_info_cb(fetion_account *ac, const gchar *sipmsg, fetion_transaction *trans)
{
    HybridNotifyInfo *info;
    HybridBuddy      *hybrid_buddy;
    fetion_buddy     *buddy;
    gchar            *province;
    gchar            *city;
    GdkPixbuf        *pixbuf = NULL;

    //info = (HybridInfo*)trans->data;

    if (!(buddy = fetion_buddy_parse_info(ac, trans->userid, sipmsg))) {
        /* TODO show an error msg in the get-info box. */
        return HYBRID_ERROR;
    }

    province = buddy->province && *(buddy->province) != '\0' ?
                get_province_name(buddy->province) : g_strdup(_("Unknown"));

    city = buddy->city && *(buddy->city) != '\0' ?
                get_city_name(buddy->province, buddy->city) :
                g_strdup(_("Unknown"));

    info = hybrid_notify_info_create();

    hybrid_info_add_pair(info, _("Nickname"), buddy->nickname);
    if (*buddy->localname) {
        hybrid_info_add_pair(info, _("Localname"), buddy->localname);
    }
    hybrid_info_add_pair(info, _("Fetion-no"), buddy->sid);
    if (buddy->mobileno && *buddy->mobileno) {
        hybrid_info_add_pair(info, _("Mobile-no"), buddy->mobileno);
    }
    hybrid_info_add_pair(info, _("Gender"),
        buddy->gender == 1 ? _("Male") :
        (buddy->gender == 2 ? _("Female") : _("Secrecy")));

    if (*buddy->mood_phrase) {
        hybrid_info_add_pair(info, _("Mood"), buddy->mood_phrase);
    }

    hybrid_info_add_pair(info, _("Country"),
            !buddy->country || g_strcmp0(buddy->country, "CN") == 0 || !*buddy->country ?
            "China" : buddy->country);
    hybrid_info_add_pair(info, _("Province"), province);
    hybrid_info_add_pair(info, _("City"), city);

    if ((hybrid_buddy = hybrid_blist_find_buddy(ac->account, buddy->userid))) {

        if (hybrid_buddy->icon_data) {
            pixbuf = hybrid_create_pixbuf(hybrid_buddy->icon_data,
                    hybrid_buddy->icon_data_length);
            hybrid_info_add_pixbuf_pair(info, _("Photo"), pixbuf);

            if (pixbuf) {
                g_object_unref(pixbuf);
            }
        }
    }

    g_free(province);
    g_free(city);

    hybrid_info_notify(ac->account, info, buddy->userid);

    hybrid_notify_info_destroy(info);

    return HYBRID_OK;
}