changeset 14010:7573bd40a190

[gaim-migrate @ 16602] Allow plugins to be loaded and unloaded. Remember the window positions and sizes. All turning on/off shadow from ~/.gntrc (off by default). committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Mon, 31 Jul 2006 23:19:12 +0000
parents 1e283c3566ab
children 735c4e927eb8
files console/Makefile console/gntblist.c console/gntconv.c console/gntdebug.c console/gntplugin.c console/gntplugin.h console/gntui.c console/libgnt/gntbox.c console/libgnt/gntbutton.c console/libgnt/gntline.c console/libgnt/gntmain.c console/libgnt/gntstyle.c console/libgnt/gntstyle.h console/libgnt/gnttextview.c console/libgnt/gnttree.c console/libgnt/gntwidget.c console/libgnt/gntwidget.h console/libgnt/test/multiwin.c
diffstat 18 files changed, 365 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/console/Makefile	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/Makefile	Mon Jul 31 23:19:12 2006 +0000
@@ -1,7 +1,7 @@
 VERSION=gntgaim-0.0.0dev
 CC=gcc
 CFLAGS=`pkg-config --cflags gaim gobject-2.0 gnt` -g -Wall -DVERSION=\"$(VERSION)\" -DSTANDALONE
-LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg
+LDFLAGS=`pkg-config --libs gaim gobject-2.0 libxml-2.0 gnt` -pg -lgaim
 
 GG_SOURCES = \
 	gntaccount.c \
@@ -10,6 +10,7 @@
 	gntconv.c \
 	gntdebug.c \
 	gntnotify.c \
+	gntplugin.c \
 	gntprefs.c \
 	gntrequest.c \
 	gntui.c
@@ -22,6 +23,7 @@
 	gntdebug.h \
 	gntnotify.h \
 	gntprefs.h \
+	gntplugin.h \
 	gntrequest.h \
 	gntui.h
 
@@ -32,6 +34,7 @@
 	gntconv.o \
 	gntdebug.o \
 	gntnotify.o \
+	gntplugin.o \
 	gntprefs.o \
 	gntrequest.o \
 	gntui.o
--- a/console/gntblist.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/gntblist.c	Mon Jul 31 23:19:12 2006 +0000
@@ -13,6 +13,8 @@
 #include "gntblist.h"
 #include <string.h>
 
+#define PREF_ROOT "/gaim/gnt/blist"
+
 typedef struct
 {
 	GntWidget *window;
@@ -274,6 +276,8 @@
 gnt_append_menu_action(GntTree *tree, GaimMenuAction *action, gpointer parent)
 {
 	GList *list;
+	if (action == NULL)
+		return;
 	
 	gnt_tree_add_row_after(tree, action,
 			gnt_tree_create_row(tree, action->label), parent, NULL);
@@ -677,8 +681,30 @@
 		remove_context_menu(ggblist);
 }
 
+static void
+size_changed_cb(GntWidget *w, int width, int height)
+{
+	gaim_prefs_set_int(PREF_ROOT "/size/width", width);
+	gaim_prefs_set_int(PREF_ROOT "/size/height", height);
+}
+
+static void
+save_position_cb(GntWidget *w, int x, int y)
+{
+	gaim_prefs_set_int(PREF_ROOT "/position/x", x);
+	gaim_prefs_set_int(PREF_ROOT "/position/y", y);
+}
+
 void gg_blist_init()
 {
+	gaim_prefs_add_none(PREF_ROOT);
+	gaim_prefs_add_none(PREF_ROOT "/size");
+	gaim_prefs_add_int(PREF_ROOT "/size/width", 20);
+	gaim_prefs_add_int(PREF_ROOT "/size/height", 20);
+	gaim_prefs_add_none(PREF_ROOT "/position");
+	gaim_prefs_add_int(PREF_ROOT "/position/x", 0);
+	gaim_prefs_add_int(PREF_ROOT "/position/y", 0);
+
 	ggblist = g_new0(GGBlist, 1);
 
 	gaim_get_blist()->ui_data = ggblist;
@@ -692,7 +718,10 @@
 	ggblist->tree = gnt_tree_new();
 	GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER);
 	gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0, 25);
-	gnt_widget_set_size(ggblist->tree, 0, getmaxy(stdscr) - 4);
+	gnt_widget_set_size(ggblist->tree, gaim_prefs_get_int(PREF_ROOT "/size/width"),
+			gaim_prefs_get_int(PREF_ROOT "/size/height"));
+	gnt_widget_set_position(ggblist->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
+			gaim_prefs_get_int(PREF_ROOT "/position/y"));
 
 	gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree);
 	gnt_widget_show(ggblist->window);
@@ -725,6 +754,9 @@
 				ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
 	g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_peripherals),
 				ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+	g_signal_connect(G_OBJECT(ggblist->tree), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	g_signal_connect(G_OBJECT(ggblist->window), "position_set", G_CALLBACK(save_position_cb), NULL);
+
 }
 
 void gg_blist_uninit()
--- a/console/gntconv.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/gntconv.c	Mon Jul 31 23:19:12 2006 +0000
@@ -1,6 +1,7 @@
 #include <string.h>
 
 #include <cmds.h>
+#include <prefs.h>
 #include <util.h>
 
 #include "gntgaim.h"
@@ -12,6 +13,8 @@
 #include "gntentry.h"
 #include "gnttextview.h"
 
+#define PREF_ROOT	"/gaim/gnt/conversations"
+
 GHashTable *ggconvs;
 
 typedef struct _GGConv GGConv;
@@ -142,19 +145,29 @@
 }
 
 static void
+size_changed_cb(GntWidget *w, int width, int height)
+{
+	gaim_prefs_set_int(PREF_ROOT "/size/width", width);
+	gaim_prefs_set_int(PREF_ROOT "/size/height", height);
+}
+
+static void
+save_position_cb(GntWidget *w, int x, int y)
+{
+	gaim_prefs_set_int(PREF_ROOT "/position/x", x);
+	gaim_prefs_set_int(PREF_ROOT "/position/y", y);
+}
+
+static void
 gg_create_conversation(GaimConversation *conv)
 {
 	GGConv *ggc = g_hash_table_lookup(ggconvs, conv);
 	char *title;
 	GaimConversationType type;
-	int x, width;
 
 	if (ggc)
 		return;
 
-	gg_blist_get_position(&x, NULL);
-	gg_blist_get_size(&width, NULL);
-
 	ggc = g_new0(GGConv, 1);
 	g_hash_table_insert(ggconvs, conv, ggc);
 
@@ -172,7 +185,8 @@
 	ggc->tv = gnt_text_view_new();
 	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv);
 	gnt_widget_set_name(ggc->tv, "conversation-window-textview");
-	gnt_widget_set_size(ggc->tv, getmaxx(stdscr) - 3 - x - width, getmaxy(stdscr) - 5);
+	gnt_widget_set_size(ggc->tv, gaim_prefs_get_int(PREF_ROOT "/size/width"),
+			gaim_prefs_get_int(PREF_ROOT "/size/height"));
 
 	ggc->entry = gnt_entry_new(NULL);
 	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry);
@@ -181,12 +195,13 @@
 	g_signal_connect(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);
 
-	/* XXX: I am assuming the buddylist is on the leftmost corner.
-	 *      That may not always be correct, since the windows can be moved.
-	 *      It might be an option to remember the position of conv. windows. */
-	gnt_widget_set_position(ggc->window, x + width, 0);
+	gnt_widget_set_position(ggc->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
+			gaim_prefs_get_int(PREF_ROOT "/position/y"));
 	gnt_widget_show(ggc->window);
 
+	g_signal_connect(G_OBJECT(ggc->tv), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	g_signal_connect(G_OBJECT(ggc->window), "position_set", G_CALLBACK(save_position_cb), NULL);
+
 	g_free(title);
 }
 
@@ -465,7 +480,15 @@
 {
 	ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv);
 
-	/* Xerox */
+	gaim_prefs_add_none(PREF_ROOT);
+	gaim_prefs_add_none(PREF_ROOT "/size");
+	gaim_prefs_add_int(PREF_ROOT "/size/width", 70);
+	gaim_prefs_add_int(PREF_ROOT "/size/height", 20);
+	gaim_prefs_add_none(PREF_ROOT "/position");
+	gaim_prefs_add_int(PREF_ROOT "/position/x", 0);
+	gaim_prefs_add_int(PREF_ROOT "/position/y", 0);
+
+	/* Xerox the commands */
 	gaim_cmd_register("say", "S", GAIM_CMD_P_DEFAULT,
 	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
 	                  say_command_cb, _("say &lt;message&gt;:  Send a message normally as if you weren't using a command."), NULL);
--- a/console/gntdebug.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/gntdebug.c	Mon Jul 31 23:19:12 2006 +0000
@@ -39,9 +39,7 @@
 gg_debug_print(GaimDebugLevel level, const char *category,
 		const char *args)
 {
-	if (debug.window == NULL)
-		fprintf(stderr, "%s: %s\n", category, args);
-	else
+	if (debug.window)
 	{
 		GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL;
 
@@ -105,7 +103,8 @@
 
 void gg_debug_init()
 {
-	gg_debug_window_show();
+	if (gaim_debug_is_enabled())
+		gg_debug_window_show();
 }
 
 void gg_debug_uninit()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntplugin.c	Mon Jul 31 23:19:12 2006 +0000
@@ -0,0 +1,124 @@
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
+
+#include "notify.h"
+
+#include "gntgaim.h"
+#include "gntplugin.h"
+
+static struct
+{
+	GntWidget *tree;
+	GntWidget *window;
+	GntWidget *aboot;
+} plugins;
+
+static void
+plugin_toggled_cb(GntWidget *tree, GaimPlugin *plugin, gpointer null)
+{
+	if (gnt_tree_get_choice(GNT_TREE(tree), plugin))
+	{
+		if(!gaim_plugin_load(plugin))
+			gaim_notify_error(NULL, "ERROR", "loading plugin failed", NULL);
+	}
+	else
+	{
+		if (!gaim_plugin_unload(plugin))
+			gaim_notify_error(NULL, "ERROR", "unloading plugin failed", NULL);
+	}
+	gg_plugins_save_loaded();
+}
+
+/* Xerox */
+void
+gg_plugins_save_loaded(void)
+{
+	GList *pl;
+	GList *files = NULL;
+	GaimPlugin *p;
+
+	for (pl = gaim_plugins_get_loaded(); pl != NULL; pl = pl->next) {
+		p = pl->data;
+
+		if (p->info->type != GAIM_PLUGIN_PROTOCOL &&
+			p->info->type != GAIM_PLUGIN_LOADER) {
+
+			files = g_list_append(files, p->path);
+		}
+	}
+
+	gaim_prefs_set_string_list("/gaim/gnt/plugins/loaded", files);
+	g_list_free(files);
+}
+
+static void
+selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
+{
+	GaimPlugin *plugin = current;
+	char *text;
+
+	/* XXX: Use formatting and stuff */
+	gnt_text_view_clear(GNT_TEXT_VIEW(plugins.aboot));
+	text = g_strdup_printf(_("Name: %s\nVersion: %s\nDescription: %s\nAuthor: %s\nWebsite: %s\nFilename: %s\n"),
+			plugin->info->name, plugin->info->version, plugin->info->description,
+			plugin->info->author, plugin->info->homepage, plugin->path);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(plugins.aboot),
+			text, GNT_TEXT_FLAG_NORMAL);
+	gnt_text_view_scroll(GNT_TEXT_VIEW(plugins.aboot), 0);
+}
+
+void gg_plugins_show_all()
+{
+	GntWidget *window, *tree, *box, *aboot;
+	GList *iter;
+	if (plugins.window)
+		return;
+
+	gaim_plugins_probe(G_MODULE_SUFFIX);
+
+	plugins.window = window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), _("Plugins"));
+	gnt_box_set_pad(GNT_BOX(window), 0);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new(_("You can (un)load plugins from the following list.")));
+	gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
+
+	gnt_box_set_pad(GNT_BOX(box), 0);
+	plugins.tree = tree = gnt_tree_new();
+	GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
+	gnt_box_add_widget(GNT_BOX(box), tree);
+	gnt_box_add_widget(GNT_BOX(box), gnt_vline_new());
+
+	plugins.aboot = aboot = gnt_text_view_new();
+	gnt_widget_set_size(aboot, 40, 20);
+	gnt_box_add_widget(GNT_BOX(box), aboot);
+
+	for (iter = gaim_plugins_get_all(); iter; iter = iter->next)
+	{
+		GaimPlugin *plug = iter->data;
+
+		if (plug->info->type != GAIM_PLUGIN_STANDARD ||
+			(plug->info->flags & GAIM_PLUGIN_FLAG_INVISIBLE) ||
+			plug->error)
+			continue;
+
+		gnt_tree_add_choice(GNT_TREE(tree), plug,
+				gnt_tree_create_row(GNT_TREE(tree), plug->info->name), NULL, NULL);
+		gnt_tree_set_choice(GNT_TREE(tree), plug, gaim_plugin_is_loaded(plug));
+	}
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 30);
+	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(plugin_toggled_cb), NULL);
+	g_signal_connect(G_OBJECT(tree), "selection_changed", G_CALLBACK(selection_changed), NULL);
+
+	gnt_widget_show(window);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntplugin.h	Mon Jul 31 23:19:12 2006 +0000
@@ -0,0 +1,6 @@
+#include <plugin.h>
+
+void gg_plugins_show_all();
+
+void gg_plugins_save_loaded();
+
--- a/console/gntui.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/gntui.c	Mon Jul 31 23:19:12 2006 +0000
@@ -5,13 +5,19 @@
 #include "gntconn.h"
 #include "gntconv.h"
 #include "gntnotify.h"
+#include "gntplugin.h"
 #include "gntrequest.h"
 
+#include <prefs.h>
+
 void init_gnt_ui()
 {
 #ifdef STANDALONE
 	gnt_init();
 #endif
+
+	gaim_prefs_add_none("/gaim/gnt");
+	
 	/* Accounts */
 	gg_accounts_init();
 	gaim_accounts_set_ui_ops(gg_accounts_get_ui_ops());
@@ -35,7 +41,12 @@
 	gg_request_init();
 	gaim_request_set_ui_ops(gg_request_get_ui_ops());
 
+	gg_plugins_show_all();
+
 #ifdef STANDALONE
+
+	gg_plugins_save_loaded();
+
 	gnt_main();
 
 	gaim_accounts_set_ui_ops(NULL);
--- a/console/libgnt/gntbox.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntbox.c	Mon Jul 31 23:19:12 2006 +0000
@@ -430,8 +430,11 @@
 
 	for (i = box->list; i; i = i->next)
 	{
-		gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
-		gnt_widget_set_size(i->data, tw + wchange, th + hchange);
+		if (wid != i->data)
+		{
+			gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
+			gnt_widget_set_size(i->data, tw + wchange, th + hchange);
+		}
 	}
 
 	reposition_children(widget);
--- a/console/libgnt/gntbutton.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntbutton.c	Mon Jul 31 23:19:12 2006 +0000
@@ -33,7 +33,7 @@
 	GntButton *button = GNT_BUTTON(widget);
 	widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 4;
 	widget->priv.height = 1;
-	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
 		widget->priv.height += 2;
 }
 
--- a/console/libgnt/gntline.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntline.c	Mon Jul 31 23:19:12 2006 +0000
@@ -14,10 +14,10 @@
 	GntLine *line = GNT_LINE(widget);
 	if (line->vertical)
 		mvwvline(widget->window, 1, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
-				widget->priv.height - 3);
+				widget->priv.height - 2);
 	else
 		mvwhline(widget->window, 0, 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
-				widget->priv.width - 3);
+				widget->priv.width - 2);
 }
 
 static void
--- a/console/libgnt/gntmain.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntmain.c	Mon Jul 31 23:19:12 2006 +0000
@@ -551,6 +551,7 @@
 
 	initscr();
 	gnt_init_colors();
+	gnt_init_styles();
 
 	filename = g_build_filename(g_get_home_dir(), ".gntrc", NULL);
 	gnt_style_read_configure_file(filename);
@@ -708,6 +709,7 @@
 void gnt_quit()
 {
 	gnt_uninit_colors();
+	gnt_uninit_styles();
 	endwin();
 }
 
--- a/console/libgnt/gntstyle.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntstyle.c	Mon Jul 31 23:19:12 2006 +0000
@@ -1,6 +1,76 @@
 #include "gntstyle.h"
 #include "gntcolors.h"
 
+#include <string.h>
+
+static char * str_styles[GNT_STYLES];
+static int int_styles[GNT_STYLES];
+static int bool_styles[GNT_STYLES];
+
+const char *gnt_style_get(GntStyle style)
+{
+	return str_styles[style];
+}
+
+gboolean gnt_style_get_bool(GntStyle style, gboolean def)
+{
+	int i;
+	const char * str;
+
+	if (bool_styles[style] != -1)
+		return bool_styles[style];
+	
+	str = gnt_style_get(style);
+
+	if (str)
+	{
+		if (strcmp(str, "false") == 0)
+			def = FALSE;
+		else if (strcmp(str, "true") == 0)
+			def = TRUE;
+		else if (sscanf(str, "%d", &i) == 1)
+		{
+			if (i)
+				def = TRUE;
+			else
+				def = FALSE;
+		}
+	}
+
+	bool_styles[style] = def;
+	return bool_styles[style];
+}
+
+static void
+read_general_style(GKeyFile *kfile)
+{
+	GError *error = NULL;
+	gsize nkeys;
+	char **keys = g_key_file_get_keys(kfile, "general", &nkeys, &error);
+	int i;
+	struct
+	{
+		const char *style;
+		GntStyle en;
+	} styles[] = {{"shadow", GNT_STYLE_SHADOW},
+	              {NULL, 0}};
+
+	if (error)
+	{
+		/* XXX: some error happened. */
+		g_error_free(error);
+	}
+	else
+	{
+		for (i = 0; styles[i].style; i++)
+		{
+			error = NULL;
+			str_styles[styles[i].en] =
+					g_key_file_get_string(kfile, "general", styles[i].style, &error);
+		}
+	}
+}
+
 void gnt_style_read_configure_file(const char *filename)
 {
 #if GLIB_CHECK_VERSION(2,6,0)
@@ -14,8 +84,27 @@
 		return;
 	}
 	gnt_colors_parse(kfile);
+	read_general_style(kfile);
 
 	g_key_file_free(kfile);
 #endif
 }
 
+void gnt_init_styles()
+{
+	int i;
+	for (i = 0; i < GNT_STYLES; i++)
+	{
+		str_styles[i] = NULL;
+		int_styles[i] = -1;
+		bool_styles[i] = -1;
+	}
+}
+
+void gnt_uninit_styles()
+{
+	int i;
+	for (i = 0; i < GNT_STYLES; i++)
+		g_free(str_styles[i]);
+}
+
--- a/console/libgnt/gntstyle.h	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntstyle.h	Mon Jul 31 23:19:12 2006 +0000
@@ -1,4 +1,19 @@
 #include "gnt.h"
 
+typedef enum
+{
+	GNT_STYLE_SHADOW = 0,
+	GNT_STYLES
+} GntStyle;
+
 void gnt_style_read_configure_file(const char *filename);
 
+/* Returned strings are all lowercase */
+const char *gnt_style_get(GntStyle style);
+
+gboolean gnt_style_get_bool(GntStyle style, gboolean def);
+
+void gnt_init_styles();
+
+void gnt_uninit_styles();
+
--- a/console/libgnt/gnttextview.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gnttextview.c	Mon Jul 31 23:19:12 2006 +0000
@@ -182,14 +182,22 @@
 
 	view->list = g_list_first(view->list);
 
-	split = g_strsplit(text, "\n", 0);
+	split = g_strsplit(text, "\n", -1);
 	for (i = 0; split[i]; i++)
 	{
-		GntTextLine *line = view->list->data;
+		GntTextLine *line;
 		int len = g_utf8_strlen(split[i], -1);
 		char *iter = split[i];
 		int prev = 0;
 
+		if (i)
+		{
+			line = g_new0(GntTextLine, 1);
+			view->list = g_list_prepend(g_list_first(view->list), line);
+		}
+
+		line = view->list->data;
+
 		while (iter && *iter)
 		{
 			GntTextSegment *seg = g_new0(GntTextSegment, 1);
--- a/console/libgnt/gnttree.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gnttree.c	Mon Jul 31 23:19:12 2006 +0000
@@ -387,7 +387,7 @@
 static void
 tree_selection_changed(GntTree *tree, GntTreeRow *old, GntTreeRow *current)
 {
-	g_signal_emit(tree, signals[SIG_SELECTION_CHANGED], 0, old, current);
+	g_signal_emit(tree, signals[SIG_SELECTION_CHANGED], 0, old->key, current->key);
 }
 
 static GntTreeRow *
--- a/console/libgnt/gntwidget.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntwidget.c	Mon Jul 31 23:19:12 2006 +0000
@@ -1,6 +1,7 @@
 /* Stuff brutally ripped from Gflib */
 
 #include "gntwidget.h"
+#include "gntstyle.h"
 #include "gntmarshal.h"
 #include "gnt.h"
 
@@ -290,7 +291,7 @@
 	{
 		gboolean shadow = TRUE;
 
-		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+		if (!gnt_widget_has_shadow(widget))
 			shadow = FALSE;
 
 		widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow,
@@ -325,7 +326,7 @@
 	wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
 #if 1
 	/* XXX: I have no clue why, but this seems to be necessary. */
-	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+	if (gnt_widget_has_shadow(widget))
 		mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height);
 #endif
 	gnt_screen_release(widget);
@@ -361,7 +362,7 @@
 gnt_widget_get_size(GntWidget *wid, int *width, int *height)
 {
 	gboolean shadow = TRUE;
-	if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_NO_SHADOW))
+	if (!gnt_widget_has_shadow(wid))
 		shadow = FALSE;
 
 	if (width)
@@ -376,7 +377,7 @@
 {
 	gboolean shadow = TRUE;
 
-	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+	if (!gnt_widget_has_shadow(widget))
 		shadow = FALSE;
 
 	wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
@@ -384,9 +385,16 @@
 
 	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
 	{
-		WINDOW *tmp = derwin(widget->window, widget->priv.height, widget->priv.width, 0, 0);
-		box(tmp, 0, 0);
-		delwin(tmp);
+		/* - This is ugly. */
+		/* - What's your point? */
+		mvwvline(widget->window, 0, 0, ACS_VLINE, widget->priv.height);
+		mvwvline(widget->window, 0, widget->priv.width - 1, ACS_VLINE, widget->priv.height);
+		mvwhline(widget->window, widget->priv.height - 1, 0, ACS_HLINE, widget->priv.width);
+		mvwhline(widget->window, 0, 0, ACS_HLINE, widget->priv.width);
+		mvwaddch(widget->window, 0, 0, ACS_ULCORNER);
+		mvwaddch(widget->window, 0, widget->priv.width - 1, ACS_URCORNER);
+		mvwaddch(widget->window, widget->priv.height - 1, 0, ACS_LLCORNER);
+		mvwaddch(widget->window, widget->priv.height - 1, widget->priv.width - 1, ACS_LRCORNER);
 	}
 
 	if (shadow)
@@ -402,7 +410,7 @@
 {
 	gboolean ret = TRUE;
 
-	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+	if (gnt_widget_has_shadow(widget))
 	{
 		width--;
 		height--;
@@ -418,7 +426,7 @@
 		gboolean shadow = TRUE;
 		int oldw, oldh;
 
-		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW))
+		if (!gnt_widget_has_shadow(widget))
 			shadow = FALSE;
 
 		oldw = widget->priv.width;
@@ -518,3 +526,9 @@
 		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE);
 }
 
+gboolean gnt_widget_has_shadow(GntWidget *widget)
+{
+	return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) &&
+			gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE));
+}
+
--- a/console/libgnt/gntwidget.h	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/gntwidget.h	Mon Jul 31 23:19:12 2006 +0000
@@ -129,6 +129,8 @@
 
 void gnt_widget_set_visible(GntWidget *widget, gboolean set);
 
+gboolean gnt_widget_has_shadow(GntWidget *widget);
+
 G_END_DECLS
 
 #endif /* GNT_WIDGET_H */
--- a/console/libgnt/test/multiwin.c	Sat Jul 29 20:22:39 2006 +0000
+++ b/console/libgnt/test/multiwin.c	Mon Jul 31 23:19:12 2006 +0000
@@ -27,6 +27,7 @@
 	gnt_widget_set_name(box2, "box2");
 
 	tree = gnt_tree_new_with_columns(3);
+	GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
 	gnt_tree_set_column_titles(GNT_TREE(tree), "12345678901234567890", "column 2", "column3");
 	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
 	gnt_widget_set_name(tree, "tree");