changeset 16168:cc5917d70dde

merge of '7c800719ac0b585a5b02eaeb188880c191d1da89' and '8be1fbdce101b63280239db93e1dac106cea6681'
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 15 Apr 2007 23:54:55 +0000
parents aa6160248112 (current diff) 7a2ffa981c1a (diff)
children 49a1fed5ee37 d73ee2690376
files finch/gntconv.h finch/libgnt/Makefile.am gaim.service.in libpurple/dbus-gaim.service libpurple/plugins/autoreply.c pidgin/plugins/gaiminc.c
diffstat 13 files changed, 319 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/finch/gntconv.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/gntconv.c	Sun Apr 15 23:54:55 2007 +0000
@@ -159,23 +159,6 @@
 		gnt_entry_clear(GNT_ENTRY(ggconv->entry));
 		return TRUE;
 	}
-	else if (key[0] == 27)
-	{
-		if (strcmp(key, GNT_KEY_DOWN) == 0)
-			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1);
-		else if (strcmp(key, GNT_KEY_UP) == 0)
-			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1);
-		else if (strcmp(key, GNT_KEY_PGDOWN) == 0)
-			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2);
-		else if (strcmp(key, GNT_KEY_PGUP) == 0)
-			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2));
-		else
-			return FALSE;
-		return TRUE;
-	}
-	else
-	{
-	}
 
 	return FALSE;
 }
@@ -325,6 +308,9 @@
 	gnt_widget_set_size(ggc->tv, purple_prefs_get_int(PREF_ROOT "/size/width"),
 			purple_prefs_get_int(PREF_ROOT "/size/height"));
 
+	ggc->info = gnt_vbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->info);
+
 	ggc->entry = gnt_entry_new(NULL);
 	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry);
 	gnt_widget_set_name(ggc->entry, "conversation-window-entry");
@@ -332,6 +318,7 @@
 	gnt_entry_set_word_suggest(GNT_ENTRY(ggc->entry), TRUE);
 	gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE);
 
+	gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(ggc->tv), ggc->entry);
 	g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc);
 	g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc);
 
@@ -758,3 +745,21 @@
 	g_free(title);
 }
 
+void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget)
+{
+	FinchConv *fc = conv->ui_data;
+	int height, width;
+
+	gnt_box_remove_all(GNT_BOX(fc->info));
+
+	if (widget) {
+		gnt_box_add_widget(GNT_BOX(fc->info), widget);
+		gnt_box_readjust(GNT_BOX(fc->info));
+	}
+
+	gnt_widget_get_size(fc->window, &width, &height);
+	gnt_box_readjust(GNT_BOX(fc->window));
+	gnt_screen_resize_widget(fc->window, width, height);
+	gnt_box_give_focus_to_child(GNT_BOX(fc->window), fc->entry);
+}
+
--- a/finch/gntconv.h	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/gntconv.h	Sun Apr 15 23:54:55 2007 +0000
@@ -48,6 +48,7 @@
 	GntWidget *entry;         /* entry */
 	GntWidget *tv;            /* text-view */
 	GntWidget *menu;          /* future use */
+	GntWidget *info;
 
 	union
 	{
@@ -90,6 +91,15 @@
  */
 void finch_conversation_set_active(PurpleConversation *conv);
 
+/**
+ * Sets the information widget for the conversation window.
+ *
+ * @param conv   The conversation.
+ * @param widget The widget containing the information. If @c NULL,
+ *               the current information widget is removed.
+ */
+void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget);
+
 /*@}*/
 
 #endif
--- a/finch/gntdebug.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/gntdebug.c	Sun Apr 15 23:54:55 2007 +0000
@@ -46,26 +46,6 @@
 	gboolean timestamps;
 } debug;
 
-static gboolean
-debug_window_kpress_cb(GntWidget *wid, const char *key, GntTextView *view)
-{
-	if (key[0] == 27)
-	{
-		if (strcmp(key, GNT_KEY_DOWN) == 0)
-			gnt_text_view_scroll(view, 1);
-		else if (strcmp(key, GNT_KEY_UP) == 0)
-			gnt_text_view_scroll(view, -1);
-		else if (strcmp(key, GNT_KEY_PGDOWN) == 0)
-			gnt_text_view_scroll(view, wid->priv.height - 2);
-		else if (strcmp(key, GNT_KEY_PGUP) == 0)
-			gnt_text_view_scroll(view, -(wid->priv.height - 2));
-		else
-			return FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
 static void
 finch_debug_print(PurpleDebugLevel level, const char *category,
 		const char *args)
@@ -265,7 +245,7 @@
 		gnt_widget_set_name(debug.window, "debug-window");
 
 		g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL);
-		g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview);
+		gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(debug.tview), debug.window);
 	}
 
 	gnt_widget_show(debug.window);
--- a/finch/libgnt/Makefile.am	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/Makefile.am	Sun Apr 15 23:54:55 2007 +0000
@@ -79,9 +79,11 @@
 libgnt_la_LDFLAGS = -export-dynamic
 libgnt_la_LIBADD = \
 	$(GLIB_LIBS) \
-	$(GNT_LIBS)
+	$(GNT_LIBS) \
+	$(LIBXML_LIBS)
 
 AM_CPPFLAGS = \
 	$(GLIB_CFLAGS) \
 	$(GNT_CFLAGS) \
-	$(DEBUG_CFLAGS)
+	$(DEBUG_CFLAGS) \
+	$(LIBXML_CFLAGS)
--- a/finch/libgnt/configure.ac	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/configure.ac	Sun Apr 15 23:54:55 2007 +0000
@@ -203,6 +203,9 @@
 
 GNT_CFLAGS=
 GNT_LIBS=
+AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR],
+		[compile finch against the ncurses includes in DIR])],
+		[ac_ncurses_includes="$withval"], [ac_ncurses_includes=""])
 AC_CHECK_LIB(ncursesw, initscr, [GNT_LIBS="-lncursesw"], [enable_gnt=no])
 AC_CHECK_LIB(panelw, update_panels, [GNT_LIBS="$GNT_LIBS -lpanelw"], [enable_gnt=no])
 
@@ -214,8 +217,9 @@
 else
 	dnl # Some distros put the headers in ncursesw/, some don't
 	found_ncurses_h=no
-	for f in /usr/include/ncursesw/ncurses.h /usr/include/ncurses.h
+	for location in $ac_ncurses_includes /usr/include/ncursesw /usr/include
 	do
+		f="$location/ncurses.h"
 		AC_CHECK_HEADER($f,[
 			AC_MSG_CHECKING([if $f supports wide characters])
 			AC_TRY_COMPILE([
@@ -226,7 +230,7 @@
 				# error get_wch not found!
 				#endif
 			], [
-				dir=`dirname $f`
+				dir=$location
 				if test x"$dir" != x"." ; then
 					GNT_CFLAGS="-I$dir/"
 				else
@@ -241,13 +245,29 @@
 			])
 		])
 	done
+	if test x"$found_ncurses_h" != "xyes"; then
+		enable_gnt="no"
+	fi
 fi
 AC_SUBST(GNT_CFLAGS)
 AC_SUBST(GNT_LIBS)
 
 if test "x$enable_gnt" = "xno"; then
 	AC_MSG_ERROR([
-*** You need ncursesw or ncurses.])
+*** You need ncursesw or ncurses and its header files.])
+fi
+
+dnl Check for libxml
+have_libxml=yes
+PKG_CHECK_MODULES(LIBXML, [libxml-2.0], , [
+		AC_MSG_RESULT(no)
+		have_libxml=no
+	])
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+
+if test "x$have_libxml" = "xno"; then
+	AC_DEFINE(NO_LIBXML, 1, [Do not have libxml2.])
 fi
 
 AC_OUTPUT([Makefile
--- a/finch/libgnt/gnttextview.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gnttextview.c	Sun Apr 15 23:54:55 2007 +0000
@@ -739,3 +739,25 @@
 	return count;
 }
 
+static gboolean
+scroll_tv(GntWidget *wid, const char *key, GntTextView *tv)
+{
+	if (strcmp(key, GNT_KEY_PGUP) == 0) {
+		gnt_text_view_scroll(tv, -(GNT_WIDGET(tv)->priv.height - 2));
+	} else if (strcmp(key, GNT_KEY_PGDOWN) == 0) {
+		gnt_text_view_scroll(tv, GNT_WIDGET(tv)->priv.height - 2);
+	} else if (strcmp(key, GNT_KEY_DOWN) == 0) {
+		gnt_text_view_scroll(tv, 1);
+	} else if (strcmp(key, GNT_KEY_UP) == 0) {
+		gnt_text_view_scroll(tv, -1);
+	} else {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget)
+{
+	g_signal_connect(G_OBJECT(widget), "key_pressed", G_CALLBACK(scroll_tv), view);
+}
+
--- a/finch/libgnt/gnttextview.h	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gnttextview.h	Sun Apr 15 23:54:55 2007 +0000
@@ -81,6 +81,8 @@
 /* If text is NULL, then the tag is removed. */
 int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all);
 
+void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget);
+
 G_END_DECLS
 
 #endif /* GNT_TEXT_VIEW_H */
--- a/finch/libgnt/gnttree.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gnttree.c	Sun Apr 15 23:54:55 2007 +0000
@@ -1525,7 +1525,7 @@
 void gnt_tree_adjust_columns(GntTree *tree)
 {
 	GntTreeRow *row = tree->root;
-	int *widths, i, twidth, height;
+	int *widths, i, twidth;
 
 	widths = g_new0(int, tree->ncol);
 	while (row) {
@@ -1552,8 +1552,7 @@
 	}
 	g_free(widths);
 
-	gnt_widget_get_size(GNT_WIDGET(tree), NULL, &height);
-	gnt_widget_set_size(GNT_WIDGET(tree), twidth, height);
+	gnt_widget_set_size(GNT_WIDGET(tree), twidth, -1);
 }
 
 void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd)
--- a/finch/libgnt/gntutils.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gntutils.c	Sun Apr 15 23:54:55 2007 +0000
@@ -1,9 +1,25 @@
-#include "gntutils.h"
+#include "gntbutton.h"
+#include "gntcheckbox.h"
+#include "gntcombobox.h"
+#include "gntentry.h"
+#include "gntlabel.h"
+#include "gntline.h"
+#include "gnttextview.h"
 #include "gnttree.h"
+#include "gntutils.h"
+#include "gntwindow.h"
 
+#include "config.h"
+
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
+#ifndef NO_LIBXML
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#endif
+
 #include "config.h"
 
 void gnt_util_get_text_bound(const char *text, int *width, int *height)
@@ -184,9 +200,156 @@
 	gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate);
 	g_hash_table_foreach(klass->actions, add_action, &bv);
 	g_hash_table_foreach(klass->bindings, add_binding, &bv);
-	gnt_tree_adjust_columns(bv.tree);
+	if (GNT_TREE(tree)->list == NULL) {
+		gnt_widget_destroy(tree);
+		tree = NULL;
+	} else
+		gnt_tree_adjust_columns(bv.tree);
 	g_hash_table_destroy(hash);
 
 	return tree;
 }
 
+#ifndef NO_LIBXML
+static GntWidget *
+gnt_widget_from_xmlnode(xmlNode *node, GntWidget **data[])
+{
+	GntWidget *widget = NULL;
+	char *name;
+	char *id, *prop, *content;
+	int val;
+
+	if (node == NULL || node->name == NULL || node->type != XML_ELEMENT_NODE)
+		return NULL;
+
+	name = (char*)node->name;
+	content = (char*)xmlNodeGetContent(node);
+	if (strcmp(name + 1, "window") == 0 || strcmp(name + 1, "box") == 0) {
+		xmlNode *ch;
+		char *title;
+		gboolean vert = (*name == 'v');
+
+		if (name[1] == 'w')
+			widget = gnt_window_box_new(FALSE, vert);
+		else
+			widget = gnt_box_new(FALSE, vert);
+
+		title = (char*)xmlGetProp(node, (xmlChar*)"title");
+		if (title) {
+			gnt_box_set_title(GNT_BOX(widget), title);
+			xmlFree(title);
+		}
+
+		prop = (char*)xmlGetProp(node, (xmlChar*)"fill");
+		if (prop) {
+			if (sscanf(prop, "%d", &val) == 1)
+				gnt_box_set_fill(GNT_BOX(widget), !!val);
+			xmlFree(prop);
+		}
+
+		prop = (char*)xmlGetProp(node, (xmlChar*)"align");
+		if (prop) {
+			if (sscanf(prop, "%d", &val) == 1)
+				gnt_box_set_alignment(GNT_BOX(widget), val);
+			xmlFree(prop);
+		}
+
+		prop = (char*)xmlGetProp(node, (xmlChar*)"pad");
+		if (prop) {
+			if (sscanf(prop, "%d", &val) == 1)
+				gnt_box_set_pad(GNT_BOX(widget), val);
+			xmlFree(prop);
+		}
+
+		for (ch = node->children; ch; ch=ch->next)
+			gnt_box_add_widget(GNT_BOX(widget), gnt_widget_from_xmlnode(ch, data));
+	} else if (strcmp(name, "button") == 0) {
+		widget = gnt_button_new(content);
+	} else if (strcmp(name, "label") == 0) {
+		widget = gnt_label_new(content);
+	} else if (strcmp(name, "entry") == 0) {
+		widget = gnt_entry_new(content);
+	} else if (strcmp(name, "combobox") == 0) {
+		widget = gnt_combo_box_new();
+	} else if (strcmp(name, "checkbox") == 0) {
+		widget = gnt_check_box_new(content);
+	} else if (strcmp(name, "tree") == 0) {
+		widget = gnt_tree_new();
+	} else if (strcmp(name, "textview") == 0) {
+		widget = gnt_text_view_new();
+	} else if (strcmp(name + 1, "line") == 0) {
+		widget = gnt_line_new(*name == 'v');
+	}
+
+	xmlFree(content);
+
+	if (widget == NULL) {
+		g_printerr("Invalid widget name %s\n", name);
+		return NULL;
+	}
+
+	id = (char*)xmlGetProp(node, (xmlChar*)"id");
+	if (id) {
+		int i;
+		sscanf(id, "%d", &i);
+		*data[i] = widget;
+		xmlFree(id);
+	}
+
+	prop = (char*)xmlGetProp(node, (xmlChar*)"border");
+	if (prop) {
+		int val;
+		if (sscanf(prop, "%d", &val) == 1) {
+			if (val)
+				GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+			else
+				GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+		}
+		xmlFree(prop);
+	}
+
+	prop = (char*)xmlGetProp(node, (xmlChar*)"shadow");
+	if (prop) {
+		int val;
+		if (sscanf(prop, "%d", &val) == 1) {
+			if (val)
+				GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+			else
+				GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+		}
+		xmlFree(prop);
+	}
+
+	return widget;
+}
+#endif
+
+void gnt_util_parse_widgets(const char *string, int num, ...)
+{
+#ifndef NO_LIBXML
+	xmlParserCtxtPtr ctxt;
+	xmlDocPtr doc;
+	xmlNodePtr node;
+	va_list list;
+	GntWidget ***data;
+	int id;
+
+	ctxt = xmlNewParserCtxt();
+	doc = xmlCtxtReadDoc(ctxt, (xmlChar*)string, NULL, NULL, XML_PARSE_NOBLANKS);
+
+	data = g_new0(GntWidget **, num);
+
+	va_start(list, num);
+	for (id = 0; id < num; id++)
+		data[id] = va_arg(list, gpointer);
+
+	node = xmlDocGetRootElement(doc);
+	gnt_widget_from_xmlnode(node, data);
+
+	xmlFreeDoc(doc);
+	xmlCleanupParser();
+	va_end(list);
+	g_free(data);
+#endif
+}
+
--- a/finch/libgnt/gntutils.h	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gntutils.h	Sun Apr 15 23:54:55 2007 +0000
@@ -39,3 +39,8 @@
  */
 GntWidget *gnt_widget_bindings_view(GntWidget *widget);
 
+/**
+ * Parse widgets from 'string'.
+ */
+void gnt_util_parse_widgets(const char *string, int num, ...);
+
--- a/finch/libgnt/gntwm.c	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/gntwm.c	Sun Apr 15 23:54:55 2007 +0000
@@ -15,10 +15,12 @@
 #include "gntmarshal.h"
 #include "gnt.h"
 #include "gntbox.h"
+#include "gntlabel.h"
 #include "gntmenu.h"
 #include "gnttextview.h"
 #include "gnttree.h"
 #include "gntutils.h"
+#include "gntwindow.h"
 
 #define IDLE_CHECK_INTERVAL 5 /* 5 seconds */
 
@@ -417,6 +419,35 @@
 	return TRUE;
 }
 
+static gboolean
+help_for_widget(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	GntWidget *widget, *tree, *win, *active;
+	char *title;
+
+	if (!wm->ordered)
+		return TRUE;
+
+	widget = wm->ordered->data;
+	if (!GNT_IS_BOX(widget))
+		return TRUE;
+	active = GNT_BOX(widget)->active;
+
+	tree = gnt_widget_bindings_view(active);
+	win = gnt_window_new();
+	title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(active)));
+	gnt_box_set_title(GNT_BOX(win), title);
+	if (tree)
+		gnt_box_add_widget(GNT_BOX(win), tree);
+	else
+		gnt_box_add_widget(GNT_BOX(win), gnt_label_new("This widget has no customizable bindings."));
+
+	gnt_widget_show(win);
+
+	return TRUE;
+}
+
 static void
 destroy__list(GntWidget *widget, GntWM *wm)
 {
@@ -475,11 +506,11 @@
 		GntWidget *sel = gnt_tree_get_selection_data(GNT_TREE(widget));
 		switch (text[0]) {
 			case '-':
-			case '<':
+			case ',':
 				shift_window(wm, sel, -1);
 				break;
-			case '+':
-			case '>':
+			case '=':
+			case '.':
 				shift_window(wm, sel, 1);
 				break;
 			default:
@@ -1006,6 +1037,8 @@
 				"\033" GNT_KEY_CTRL_J, NULL);
 	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-up", window_scroll_up,
 				"\033" GNT_KEY_CTRL_K, NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-widget", help_for_widget,
+				"\033" "/", NULL);
 
 	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
 
@@ -1230,8 +1263,12 @@
 
 	idle_update = TRUE;
 
-	if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys))
+	wm->event_stack = TRUE;
+
+	if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) {
+		wm->event_stack = FALSE;
 		return TRUE;
+	}
 
 	/* Do some manual checking */
 	if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) {
@@ -1262,6 +1299,7 @@
 			if (ox != x || oy != y) {
 				gnt_screen_move_widget(widget, x, y);
 				window_reverse(widget, TRUE, wm);
+				wm->event_stack = FALSE;
 				return TRUE;
 			}
 		} else if (wm->mode == GNT_KP_MODE_RESIZE) {
@@ -1279,6 +1317,7 @@
 			if (oh != h || ow != w) {
 				gnt_screen_resize_widget(widget, w, h);
 				window_reverse(widget, TRUE, wm);
+				wm->event_stack = FALSE;
 				return TRUE;
 			}
 		}
@@ -1286,11 +1325,10 @@
 			window_reverse(widget, FALSE, wm);
 			wm->mode = GNT_KP_MODE_NORMAL;
 		}
+		wm->event_stack = FALSE;
 		return TRUE;
 	}
 
-	wm->event_stack = TRUE;
-
 	/* Escape to close the window-list or action-list window */
 	if (strcmp(keys, "\033") == 0) {
 		if (wm->_list.window) {
--- a/finch/libgnt/test/Makefile	Sun Apr 15 23:53:36 2007 +0000
+++ b/finch/libgnt/test/Makefile	Sun Apr 15 23:54:55 2007 +0000
@@ -2,7 +2,7 @@
 CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE
 LDFLAGS=`pkg-config --libs gobject-2.0 gmodule-2.0 gnt` -pg
 
-EXAMPLES=combo focus tv multiwin keys menu
+EXAMPLES=combo focus tv multiwin keys menu parse
 
 all:
 	make examples
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/test/parse.c	Sun Apr 15 23:54:55 2007 +0000
@@ -0,0 +1,18 @@
+#include "gntutils.h"
+
+int main()
+{
+	GntWidget *win, *button;
+
+	gnt_init();
+
+	gnt_util_parse_widgets("<vwindow id='0' fill='0' align='2'><label>This is a test.</label><button id='1'>OK</button></vwindow>", 2, &win, &button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win);
+	gnt_widget_show(win);
+
+	gnt_main();
+
+	gnt_quit();
+	return 0;
+}
+