⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmppconsole.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Purple - XMPP debugging tool * * Copyright (C) 2002-2003, Sean Egan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include "internal.h"#include "gtkplugin.h"#include "version.h"#include "prpl.h"#include "xmlnode.h"#include "gtkimhtml.h"#if !GTK_CHECK_VERSION(2,4,0)#include "pidgincombobox.h"#endiftypedef struct {	PurpleConnection *gc;	GtkWidget *window;	GtkWidget *hbox;	GtkWidget *dropdown;	GtkWidget *imhtml;	GtkWidget *entry;	GtkWidget *sw;	int count;	GList *accounts;} XmppConsole;XmppConsole *console = NULL;static void *xmpp_console_handle = NULL;#define BRACKET_COLOR "#940f8c"#define TAG_COLOR "#8b1dab"#define ATTR_NAME_COLOR "#a02961"#define ATTR_VALUE_COLOR "#324aa4"#define XMLNS_COLOR "#2cb12f"static char *xmlnode_to_pretty_str(xmlnode *node, int *len, int depth){	GString *text = g_string_new("");	xmlnode *c;	char *node_name, *esc, *esc2, *tab = NULL;	gboolean need_end = FALSE, pretty = TRUE;	g_return_val_if_fail(node != NULL, NULL);	if(pretty && depth) {		tab = g_strnfill(depth, '\t');		text = g_string_append(text, tab);	}	node_name = g_markup_escape_text(node->name, -1);	g_string_append_printf(text, "<font color='"			       BRACKET_COLOR "'>&lt;</font><font color='"			       TAG_COLOR "'><b>%s</b></font>", node_name);	if (node->xmlns) {		if((!node->parent || 		    !node->parent->xmlns || 		    strcmp(node->xmlns, node->parent->xmlns)) &&		   strcmp(node->xmlns, "jabber:client"))		{			char *xmlns = g_markup_escape_text(node->xmlns, -1);			g_string_append_printf(text, " <font color='"					       ATTR_NAME_COLOR "'><b>xmlns</b></font>='<font color='"					       XMLNS_COLOR "'><b>%s</b></font>'", xmlns);			g_free(xmlns);		}	}	for(c = node->child; c; c = c->next)	{		if(c->type == XMLNODE_TYPE_ATTRIB) {			esc = g_markup_escape_text(c->name, -1);			esc2 = g_markup_escape_text(c->data, -1);			g_string_append_printf(text, " <font color='"					       ATTR_NAME_COLOR "'><b>%s</b></font>='<font color='"					       ATTR_VALUE_COLOR "'>%s</font>'", esc, esc2);			g_free(esc);			g_free(esc2);		} else if(c->type == XMLNODE_TYPE_TAG || c->type == XMLNODE_TYPE_DATA) {			if(c->type == XMLNODE_TYPE_DATA)				pretty = FALSE;			need_end = TRUE;		}	}	if(need_end) {		g_string_append_printf(text, 			       "<font color='"BRACKET_COLOR"'>&gt;</font>%s", pretty ? "<br>" : "");		for(c = node->child; c; c = c->next)		{			if(c->type == XMLNODE_TYPE_TAG) {				int esc_len;				esc = xmlnode_to_pretty_str(c, &esc_len, depth+1);				text = g_string_append_len(text, esc, esc_len);				g_free(esc);			} else if(c->type == XMLNODE_TYPE_DATA && c->data_sz > 0) {				esc = g_markup_escape_text(c->data, c->data_sz);				text = g_string_append(text, esc);				g_free(esc);			}		}		if(tab && pretty)			text = g_string_append(text, tab);		g_string_append_printf(text, "<font color='"BRACKET_COLOR"'>&lt;</font>/<font color='"				       TAG_COLOR"'><b>%s</b></font><font color='"BRACKET_COLOR				       "'>&gt;</font><br>", node_name);	} else {		g_string_append_printf(text, "/<font color='"BRACKET_COLOR"'>&gt;</font><br>");	}	g_free(node_name);	g_free(tab);	if(len)		*len = text->len;	return g_string_free(text, FALSE);}static voidxmlnode_received_cb(PurpleConnection *gc, xmlnode **packet, gpointer null){	char *str, *formatted;	if (!console || console->gc != gc)		return;	str = xmlnode_to_pretty_str(*packet, NULL, 0);	formatted = g_strdup_printf("<body bgcolor='#ffcece'><pre>%s</pre></body>", str);	gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0);	g_free(formatted);	g_free(str);}static voidxmlnode_sent_cb(PurpleConnection *gc, char **packet, gpointer null){	char *str;	char *formatted;	xmlnode *node;	if (!console || console->gc != gc)		return;	node = xmlnode_from_str(*packet, -1);			if (!node)		return;		str = xmlnode_to_pretty_str(node, NULL, 0);	formatted = g_strdup_printf("<body bgcolor='#dcecc4'><pre>%s</pre></body>", str);	gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0);	g_free(formatted);	g_free(str);	xmlnode_free(node);}static void message_send_cb(GtkWidget *widget, gpointer p){	GtkTextIter start, end;	PurplePluginProtocolInfo *prpl_info = NULL;	PurpleConnection *gc = console->gc;	GtkTextBuffer *buffer;	char *text;	gc = console->gc;	if (gc)		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));	gtk_text_buffer_get_start_iter(buffer, &start);	gtk_text_buffer_get_end_iter(buffer, &end);	text = gtk_imhtml_get_text(GTK_IMHTML(console->entry), &start, &end);	if (prpl_info && prpl_info->send_raw != NULL)		prpl_info->send_raw(gc, text, strlen(text));	g_free(text);	gtk_imhtml_clear(GTK_IMHTML(console->entry));}static void entry_changed_cb(GtkTextBuffer *buffer, void *data){	char *xmlstr, *str;        GtkTextIter iter;        int wrapped_lines;        int lines;        GdkRectangle oneline;        int height;        int pad_top, pad_inside, pad_bottom;	GtkTextIter start, end;	xmlnode *node;	        wrapped_lines = 1;        gtk_text_buffer_get_start_iter(buffer, &iter);        gtk_text_view_get_iter_location(GTK_TEXT_VIEW(console->entry), &iter, &oneline);        while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(console->entry), &iter))                wrapped_lines++;        lines = gtk_text_buffer_get_line_count(buffer);        /* Show a maximum of 64 lines */        lines = MIN(lines, 6);        wrapped_lines = MIN(wrapped_lines, 6);        pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(console->entry));        pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(console->entry));        pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(console->entry));        height = (oneline.height + pad_top + pad_bottom) * lines;        height += (oneline.height + pad_inside) * (wrapped_lines - lines);        gtk_widget_set_size_request(console->sw, -1, height+6);	gtk_text_buffer_get_start_iter(buffer, &start);	gtk_text_buffer_get_end_iter(buffer, &end);       	str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);	if (!str)		return;	xmlstr = g_strdup_printf("<xml>%s</xml>", str);	node = xmlnode_from_str(xmlstr, -1);	if (node) {		gtk_imhtml_clear_formatting(GTK_IMHTML(console->entry));	} else {		gtk_imhtml_toggle_background(GTK_IMHTML(console->entry), "#ffcece");	}	g_free(str);	g_free(xmlstr);	if (node)		xmlnode_free(node);}static void iq_clicked_cb(GtkWidget *w, gpointer nul){	GtkWidget *hbox, *to_entry, *label, *type_combo;	GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);	GtkTextIter iter;	GtkTextBuffer *buffer;	const char *to;	int result;	char *stanza;	GtkWidget *dialog = gtk_dialog_new_with_buttons("<iq/>",							GTK_WINDOW(console->window),							GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,							GTK_STOCK_CANCEL,							GTK_RESPONSE_REJECT,							GTK_STOCK_OK,							GTK_RESPONSE_ACCEPT,							NULL);	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);	hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("To:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	to_entry = gtk_entry_new();	gtk_entry_set_activates_default (GTK_ENTRY (to_entry), TRUE);	gtk_box_pack_start(GTK_BOX(hbox), to_entry, FALSE, FALSE, 0);		hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("Type:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	type_combo = gtk_combo_box_new_text();	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "get");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "set");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "result");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);		gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);	result = gtk_dialog_run(GTK_DIALOG(dialog));	if (result != GTK_RESPONSE_ACCEPT) {		gtk_widget_destroy(dialog);		return;	}		to = gtk_entry_get_text(GTK_ENTRY(to_entry));	stanza = g_strdup_printf("<iq %s%s%s id='console%x' type='%s'></iq>", 				 to && *to ? "to='" : "",				 to && *to ? to : "",				 to && *to ? "'" : "",				 g_random_int(),				 gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)));		buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));	gtk_text_buffer_set_text(buffer, stanza, -1);	gtk_text_buffer_get_iter_at_offset(buffer, &iter, strstr(stanza, "</iq>") - stanza);	gtk_text_buffer_place_cursor(buffer, &iter);	g_free(stanza);       	gtk_widget_destroy(dialog);}static void presence_clicked_cb(GtkWidget *w, gpointer nul){	GtkWidget *hbox,   		  *to_entry, 		  *status_entry,		  *priority_entry,		  *label,   		  *show_combo,		  *type_combo;	GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);	GtkTextIter iter;	GtkTextBuffer *buffer;	const char *to, *type, *status, *show, *priority;	int result;	char *stanza;		GtkWidget *dialog = gtk_dialog_new_with_buttons("<presence/>",							GTK_WINDOW(console->window),							GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,							GTK_STOCK_CANCEL,							GTK_RESPONSE_REJECT,							GTK_STOCK_OK,							GTK_RESPONSE_ACCEPT,							NULL);	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);	hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("To:");	gtk_size_group_add_widget(sg, label);	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	to_entry = gtk_entry_new();	gtk_entry_set_activates_default (GTK_ENTRY (to_entry), TRUE);	gtk_box_pack_start(GTK_BOX(hbox), to_entry, FALSE, FALSE, 0);		hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("Type:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	type_combo = gtk_combo_box_new_text();	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "default");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unavailable");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribe");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribe");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribed");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribed");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "probe");	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);	hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("Show:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	show_combo = gtk_combo_box_new_text();	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "default");	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "away");	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "dnd");	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "xa");	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "chat");	gtk_combo_box_set_active(GTK_COMBO_BOX(show_combo), 0);	gtk_box_pack_start(GTK_BOX(hbox), show_combo, FALSE, FALSE, 0);	hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("Status:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	status_entry = gtk_entry_new();	gtk_entry_set_activates_default (GTK_ENTRY (status_entry), TRUE);	gtk_box_pack_start(GTK_BOX(hbox), status_entry, FALSE, FALSE, 0);	hbox = gtk_hbox_new(FALSE, 3);	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);	label = gtk_label_new("Priority:");	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);	gtk_size_group_add_widget(sg, label);	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);	priority_entry = gtk_spin_button_new_with_range(-128, 127, 1);	gtk_spin_button_set_value(GTK_SPIN_BUTTON(priority_entry), 0);	gtk_box_pack_start(GTK_BOX(hbox), priority_entry, FALSE, FALSE, 0);		gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);	result = gtk_dialog_run(GTK_DIALOG(dialog));	if (result != GTK_RESPONSE_ACCEPT) {		gtk_widget_destroy(dialog);		return;	}		to = gtk_entry_get_text(GTK_ENTRY(to_entry));	type = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));	if (!strcmp(type, "default"))		type = "";	show = gtk_combo_box_get_active_text(GTK_COMBO_BOX(show_combo));	if (!strcmp(show, "default"))		show = "";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -