diff -urP irssi-0.8.10-rc5/src/fe-text/gui-readline.c irssi-0.8.10-rc5-mouse_xterm/src/fe-text/gui-readline.c
--- irssi-0.8.10-rc5/src/fe-text/gui-readline.c	2004-03-24 17:24:57.000000000 +0000
+++ irssi-0.8.10-rc5-mouse_xterm/src/fe-text/gui-readline.c	2005-04-15 11:50:03.000000000 +0100
@@ -69,6 +69,11 @@
 
 static void sig_input(void);
 
+#include <math.h>
+static int mouse_xterm_status = -1; /* -1:off 0,1,2:filling mouse_xterm_combo */
+static unichar mouse_xterm_combo[3]; /* 0:button 1:x 2:y */
+static unichar mouse_xterm_previous[3]; /* previous contents of mouse_xterm_combo */
+
 void input_listen_init(int handle)
 {
         GIOChannel *stdin_channel;
@@ -442,6 +447,108 @@
 	return paste_state == 2;
 }
 
+/* Handle mouse event (button press or release) */
+static void sig_mouse_event(int b, int x, int y, int oldb, int oldx, int oldy)
+{
+	int xd, yd;
+	double distance, angle;
+
+	/* proceed only if a button is being released */
+	if (b != 3)
+		return;
+
+	/* if it was a mouse click (press and release in the same position) */
+	if (x == oldx && y == oldy) {
+		signal_emit("mouse click", 3, oldb, x, y);
+		return;
+	}
+
+	/* otherwise, find mouse gestures on left button*/
+	if (oldb != 0)
+		return;
+	xd = x - oldx;
+	yd = -1 * (y - oldy);
+	distance = sqrt(xd*xd + yd*yd);
+	/* ignore small gestures */
+	if (distance < 3)
+		return;
+	angle = asin(yd/distance) * 180 / 3.14159265358979;
+	if (angle < 20 && angle > -20 && xd > 0) {
+		if (distance <= 40)
+			signal_emit("mouse gesture right", 0);
+		else
+			signal_emit("mouse gesture bigright", 0);
+	} else if (angle < 20 && angle > -20 && xd < 0) {
+		if (distance <= 40)
+			signal_emit("mouse gesture left", 0);
+		else
+			signal_emit("mouse gesture bigleft", 0);
+	} else if (angle > 40) {
+		signal_emit("mouse gesture up", 0);
+	} else if (angle < -40) {
+		signal_emit("mouse gesture down", 0);
+	}
+}
+
+/* Mouse click (press and release in the same position) */
+static void sig_mouse_click(int b, int x, int y)
+{
+	GSList *l_bar;
+	
+	switch (b) {
+	/* mouse wheel up */
+	case 64:
+		window_prev_page();
+		break;
+	/* mouse wheel down */
+	case 65:
+		window_next_page();
+		break;
+	}
+}
+
+static void sig_mouse_gesture_up(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_up");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
+static void sig_mouse_gesture_down(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_down");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
+static void sig_mouse_gesture_left(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_left");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
+static void sig_mouse_gesture_bigleft(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_bigleft");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
+static void sig_mouse_gesture_right(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_right");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
+static void sig_mouse_gesture_bigright(void)
+{
+	const char *cmd = settings_get_str("mouse_gesture_bigright");
+	if (cmd[0])
+		signal_emit("send command", 3, cmd, active_win->active_server, active_win->active);
+}
+
 static void sig_gui_key_pressed(gpointer keyp)
 {
 	GTimeVal now;
@@ -456,6 +563,21 @@
 		return;
 	}
 
+	if (mouse_xterm_status != -1) {
+		if (mouse_xterm_status == 0)
+			memcpy(mouse_xterm_previous, mouse_xterm_combo, 3*sizeof(unichar));
+		mouse_xterm_combo[mouse_xterm_status] = key-32;
+		mouse_xterm_status++;
+		if (mouse_xterm_status == 3) {
+			mouse_xterm_status = -1;
+			/* match screen coordinates */
+			mouse_xterm_combo[1]--;
+			mouse_xterm_combo[2]--;
+			signal_emit("mouse event", 6, mouse_xterm_combo[0], mouse_xterm_combo[1], mouse_xterm_combo[2], mouse_xterm_previous[0], mouse_xterm_previous[1], mouse_xterm_previous[2]);
+		}
+		return;
+	}
+
         g_get_current_time(&now);
 	diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
 		(now.tv_usec - last_keypress.tv_usec)/1000;
@@ -565,6 +687,11 @@
 {
 }
 
+static void key_start_mouse_xterm(void)
+{
+	mouse_xterm_status = 0;
+}
+
 static void key_backward_history(void)
 {
 	const char *text;
@@ -1010,6 +1137,12 @@
 	g_get_current_time(&last_keypress);
         input_listen_init(STDIN_FILENO);
 
+	settings_add_str("lookandfeel", "mouse_gesture_up", "/window last");
+	settings_add_str("lookandfeel", "mouse_gesture_down", "/window goto active");
+	settings_add_str("lookandfeel", "mouse_gesture_left", "/window prev");
+	settings_add_str("lookandfeel", "mouse_gesture_bigleft", "/eval window prev;window prev");
+	settings_add_str("lookandfeel", "mouse_gesture_right", "/window next");
+	settings_add_str("lookandfeel", "mouse_gesture_bigright", "/eval window next;window next");
 	settings_add_str("history", "scroll_page_count", "/2");
 	settings_add_time("misc", "paste_detect_time", "5msecs");
 	settings_add_int("misc", "paste_detect_keycount", 5);
@@ -1034,6 +1167,7 @@
 	key_bind("key", NULL, "meta-[", "meta2", (SIGNAL_FUNC) key_combo);
 	key_bind("key", NULL, "meta-O", "meta2", (SIGNAL_FUNC) key_combo);
 	key_bind("key", NULL, "meta-[O", "meta2", (SIGNAL_FUNC) key_combo);
+	key_bind("key", NULL, "meta-[M", "mouse_xterm", (SIGNAL_FUNC) key_combo);
 
         /* arrow keys */
 	key_bind("key", NULL, "meta2-A", "up", (SIGNAL_FUNC) key_combo);
@@ -1137,6 +1271,7 @@
 
         /* misc */
 	key_bind("stop_irc", "Send SIGSTOP to client", "^Z", NULL, (SIGNAL_FUNC) key_sig_stop);
+	key_bind("start_mouse_xterm", "Start of xterm mouse tracking sequence", "mouse_xterm", NULL, (SIGNAL_FUNC) key_start_mouse_xterm);
 
         key_configure_thaw();
 
@@ -1144,6 +1279,14 @@
 	signal_add("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
 	signal_add("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
 	signal_add("setup changed", (SIGNAL_FUNC) setup_changed);
+	signal_add("mouse event", (SIGNAL_FUNC) sig_mouse_event);
+	signal_add("mouse click", (SIGNAL_FUNC) sig_mouse_click);
+	signal_add("mouse gesture up", (SIGNAL_FUNC) sig_mouse_gesture_up);
+	signal_add("mouse gesture down", (SIGNAL_FUNC) sig_mouse_gesture_down);
+	signal_add("mouse gesture left", (SIGNAL_FUNC) sig_mouse_gesture_left);
+	signal_add("mouse gesture bigleft", (SIGNAL_FUNC) sig_mouse_gesture_bigleft);
+	signal_add("mouse gesture right", (SIGNAL_FUNC) sig_mouse_gesture_right);
+	signal_add("mouse gesture bigright", (SIGNAL_FUNC) sig_mouse_gesture_bigright);
 }
 
 void gui_readline_deinit(void)
@@ -1201,6 +1344,7 @@
 	key_unbind("insert_text", (SIGNAL_FUNC) key_insert_text);
 	key_unbind("change_window", (SIGNAL_FUNC) key_change_window);
 	key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop);
+	key_unbind("start_mouse_xterm", (SIGNAL_FUNC) key_start_mouse_xterm);
 	keyboard_destroy(keyboard);
         g_array_free(paste_buffer, TRUE);
 
@@ -1210,4 +1354,12 @@
 	signal_remove("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
 	signal_remove("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
 	signal_remove("setup changed", (SIGNAL_FUNC) setup_changed);
+	signal_remove("mouse event", (SIGNAL_FUNC) sig_mouse_event);
+	signal_remove("mouse click", (SIGNAL_FUNC) sig_mouse_click);
+	signal_remove("mouse gesture up", (SIGNAL_FUNC) sig_mouse_gesture_up);
+	signal_remove("mouse gesture down", (SIGNAL_FUNC) sig_mouse_gesture_down);
+	signal_remove("mouse gesture left", (SIGNAL_FUNC) sig_mouse_gesture_left);
+	signal_remove("mouse gesture bigleft", (SIGNAL_FUNC) sig_mouse_gesture_bigleft);
+	signal_remove("mouse gesture right", (SIGNAL_FUNC) sig_mouse_gesture_right);
+	signal_remove("mouse gesture bigright", (SIGNAL_FUNC) sig_mouse_gesture_bigright);
 }
diff -urP irssi-0.8.10-rc5/src/fe-text/term.c irssi-0.8.10-rc5-mouse_xterm/src/fe-text/term.c
--- irssi-0.8.10-rc5/src/fe-text/term.c	2004-08-20 01:02:29.000000000 +0100
+++ irssi-0.8.10-rc5-mouse_xterm/src/fe-text/term.c	2005-04-15 11:54:34.000000000 +0100
@@ -42,6 +42,7 @@
 
 int term_use_colors;
 int term_type;
+int term_mouse_xterm = 0;
 
 static int force_colors;
 static int resize_dirty;
@@ -110,11 +111,21 @@
 	irssi_redraw();
 }
 
+static void mouse_xterm_tracking(int start)
+{
+	term_mouse_xterm = start;
+	if (start)
+		printf("\e[?1000h");
+	else
+		printf("\e[?1000l");
+}
+
 static void read_settings(void)
 {
         const char *str;
 	int old_colors = term_use_colors;
         int old_type = term_type;
+        int old_mouse_xterm = term_mouse_xterm;
 
         term_auto_detach(settings_get_bool("term_auto_detach"));
 
@@ -141,6 +152,32 @@
 
 	if (term_use_colors != old_colors)
 		irssi_redraw();
+
+	term_mouse_xterm = settings_get_bool("term_mouse_xterm");
+	if (term_mouse_xterm != old_mouse_xterm)
+		mouse_xterm_tracking(term_mouse_xterm);
+}
+
+/* Return 1 if $TERM is set to a xterm-compatible terminal, 0 otherwise */
+static int term_is_xterm_compatible(void)
+{
+	char *term;
+	int i;
+	static char *terms[] = {
+		"rxvt",
+		"screen",
+		"xterm",
+		"xterm-color",
+		NULL
+	};
+
+	term = getenv("TERM");
+	if (term == NULL)
+		return 0;
+	for (i = 0; terms[i] != NULL; i++)
+		if (strcmp(term, terms[i]) == 0)
+			return 1;
+	return 0;
 }
 
 void term_common_init(void)
@@ -148,6 +185,7 @@
 #ifdef SIGWINCH
 	struct sigaction act;
 #endif
+        settings_add_bool("lookandfeel", "term_mouse_xterm", TRUE);
 	settings_add_bool("lookandfeel", "colors", TRUE);
 	settings_add_bool("lookandfeel", "term_force_colors", FALSE);
         settings_add_bool("lookandfeel", "term_auto_detach", FALSE);
@@ -158,6 +196,10 @@
 	term_use_colors = term_has_colors() && settings_get_bool("colors");
         read_settings();
 
+	/* start xterm mouse tracking */
+	if (settings_get_bool("term_mouse_xterm") && term_is_xterm_compatible())
+		mouse_xterm_tracking(1);
+
 #if defined (HAVE_NL_LANGINFO) && defined(CODESET)
 	if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
 		term_type = TERM_TYPE_UTF8;
@@ -180,6 +222,10 @@
 
 void term_common_deinit(void)
 {
+	/* stop xterm mouse tracking */
+	if (settings_get_bool("term_mouse_xterm") && term_is_xterm_compatible())
+		mouse_xterm_tracking(0);
+
 	command_unbind("resize", (SIGNAL_FUNC) cmd_resize);
 	command_unbind("redraw", (SIGNAL_FUNC) cmd_redraw);
 	signal_remove("beep", (SIGNAL_FUNC) term_beep);
