diff -ur vte-0.26.2.orig/src/vte.c vte-0.26.2/src/vte.c
--- vte-0.26.2.orig/src/vte.c	2010-11-13 13:18:41.000000000 +0100
+++ vte-0.26.2/src/vte.c	2011-11-07 11:29:47.689857521 +0100
@@ -5566,10 +5566,11 @@
 				      long           col,
 				      long           row,
 				      unsigned char *pb,
-				      unsigned char *px,
-				      unsigned char *py)
+				      long          *px,
+				      long          *py)
 {
-	unsigned char cb = 0, cx = 0, cy = 0;
+	unsigned char cb = 0;
+	long cx, cy;
 
 	/* Encode the button information in cb. */
 	switch (button) {
@@ -5605,11 +5606,11 @@
 		cb |= 16;
 	}
 
-	/* Encode the cursor coordinates. */
-	cx = 32 + CLAMP(1 + col,
-			1, terminal->column_count);
-	cy = 32 + CLAMP(1 + row,
-			1, terminal->row_count);;
+	/* Clamp the cursor coordinates. */
+	cx = CLAMP(1 + col,
+		   1, terminal->column_count);
+	cy = CLAMP(1 + row,
+		   1, terminal->row_count);
 
 	*pb = cb;
 	*px = cx;
@@ -5617,14 +5618,41 @@
 }
 
 static void
+vte_terminal_feed_mouse_event(VteTerminal *terminal,
+                              int          cb,
+                              long         cx,
+                              long         cy)
+{
+	char buf[LINE_MAX];
+	gint len = 0;
+
+	if (terminal->pvt->mouse_urxvt_extension) {
+		/* urxvt's extended mode (1015) */
+		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "%d;%ld;%ldM", cb, cx, cy);
+	} else if (terminal->pvt->mouse_xterm_extension) {
+		if (cx <= 2015 && cy <= 2015) {
+			/* xterm's extended mode (1005): encode in UTF-8, no matter what the actual charset is. */
+			len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c", cb);
+			len += g_unichar_to_utf8(cx + 32, buf + len);
+			len += g_unichar_to_utf8(cy + 32, buf + len);
+		}
+	} else if (cx <= 231 && cy <= 231) {
+		/* legacy mode */
+		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", cb, 32 + (guchar)cx, 32 + (guchar)cy);
+	}
+
+	/* Send event direct to the child, this is binary not text data */
+	vte_terminal_feed_child_binary(terminal, buf, len);
+}
+
+static void
 vte_terminal_send_mouse_button_internal(VteTerminal *terminal,
 					int          button,
 					long         x,
 					long         y)
 {
-	unsigned char cb, cx, cy;
-	char buf[LINE_MAX];
-	gint len;
+	unsigned char cb;
+	long cx, cy;
 	int width = terminal->char_width;
 	int height = terminal->char_height;
 	long col = (x - terminal->pvt->inner_border.left) / width;
@@ -5633,10 +5661,7 @@
 	vte_terminal_get_mouse_tracking_info (terminal,
 					      button, col, row,
 					      &cb, &cx, &cy);
-
-	/* Send event direct to the child, this is binary not text data */
-	len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", cb, cx, cy);
-	vte_terminal_feed_child_binary(terminal, buf, len);
+	vte_terminal_feed_mouse_event(terminal, cb, cx, cy);
 }
 
 /* Send a mouse button click/release notification. */
@@ -5672,9 +5697,8 @@
 static void
 vte_terminal_maybe_send_mouse_drag(VteTerminal *terminal, GdkEventMotion *event)
 {
-	unsigned char cb, cx, cy;
-	char buf[LINE_MAX];
-	gint len;
+	unsigned char cb;
+	long cx, cy;
 	int width = terminal->char_width;
 	int height = terminal->char_height;
 	long col = ((long) event->x - terminal->pvt->inner_border.left) / width;
@@ -5708,9 +5732,7 @@
 					      &cb, &cx, &cy);
 	cb += 32; /* for movement */
 
-	/* Send event direct to the child, this is binary not text data */
-	len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", cb, cx, cy);
-	vte_terminal_feed_child_binary(terminal, buf, len);
+	vte_terminal_feed_mouse_event(terminal, cb, cx, cy);
 }
 
 /* Clear all match hilites. */
@@ -13599,6 +13621,8 @@
 	pvt->mouse_last_button = 0;
 	pvt->mouse_last_x = 0;
 	pvt->mouse_last_y = 0;
+	pvt->mouse_xterm_extension = FALSE;
+	pvt->mouse_urxvt_extension = FALSE;
 	/* Clear modifiers. */
 	pvt->modifiers = 0;
 	/* Cause everything to be redrawn (or cleared). */
diff -ur vte-0.26.2.orig/src/vte-private.h vte-0.26.2/src/vte-private.h
--- vte-0.26.2.orig/src/vte-private.h	2010-11-13 13:18:41.000000000 +0100
+++ vte-0.26.2/src/vte-private.h	2011-11-06 22:42:03.993565595 +0100
@@ -304,6 +304,8 @@
 	long mouse_last_x, mouse_last_y;
 	gboolean mouse_autohide;
 	guint mouse_autoscroll_tag;
+	gboolean mouse_xterm_extension;
+	gboolean mouse_urxvt_extension;
 
 	/* State variables for handling match checks. */
 	char *match_contents;
diff -ur vte-0.26.2.orig/src/vteseq.c vte-0.26.2/src/vteseq.c
--- vte-0.26.2.orig/src/vteseq.c	2010-08-09 13:38:44.000000000 +0200
+++ vte-0.26.2/src/vteseq.c	2011-11-06 22:48:03.436172496 +0100
@@ -668,10 +668,20 @@
 		 GINT_TO_POINTER(0),
 		 GINT_TO_POINTER(MOUSE_TRACKING_ALL_MOTION_TRACKING),
 		 NULL, NULL,},
+		/* 1005: Extended xterm mouse coordinates. */
+		{1005, &terminal->pvt->mouse_xterm_extension, NULL, NULL,
+		 GINT_TO_POINTER(FALSE),
+		 GINT_TO_POINTER(TRUE),
+		 NULL, NULL,},
 		/* 1010/rxvt: disallowed, scroll-on-output is set by user. */
 		{1010, NULL, NULL, NULL, NULL, NULL, NULL, NULL,},
 		/* 1011/rxvt: disallowed, scroll-on-keypress is set by user. */
 		{1011, NULL, NULL, NULL, NULL, NULL, NULL, NULL,},
+		/* 1015: Extended urxvt mouse coordinates. */
+		{1015, &terminal->pvt->mouse_urxvt_extension, NULL, NULL,
+		 GINT_TO_POINTER(FALSE),
+		 GINT_TO_POINTER(TRUE),
+		 NULL, NULL,},
 		/* 1035: disallowed, don't know what to do with it. */
 		{1035, NULL, NULL, NULL, NULL, NULL, NULL, NULL,},
 		/* 1036: Meta-sends-escape. */
