Skip to content

Instantly share code, notes, and snippets.

@saitoha
Created July 13, 2012 12:26
Show Gist options
  • Select an option

  • Save saitoha/3104633 to your computer and use it in GitHub Desktop.

Select an option

Save saitoha/3104633 to your computer and use it in GitHub Desktop.
SGR 1006/urxvt 1015/any event mouse reporting, for putty r9575
Index: terminal.c
===================================================================
--- terminal.c (revision 9575)
+++ terminal.c (working copy)
@@ -45,6 +45,17 @@
#define TM_VTXXX (TM_VT220|CL_VT340TEXT|CL_VT510|CL_VT420|CL_VT320)
#define TM_SCOANSI (CL_ANSIMIN|CL_SCOANSI)
+/** Mouse tracking modes */
+#define MM_NONE 0x00 /* No tracking */
+#define MM_NORMAL 0x01 /* Normal tracking mode */
+#define MM_BTN_EVENT 0x02 /* Button event mode */
+#define MM_ANY_EVENT 0x03 /* Any event mode */
+
+/** Mouse tracking protocols */
+#define MP_NORMAL 0x00 /* CSI M Cb Cx Cy */
+#define MP_URXVT 0x01 /* CSI Db ; Dx ; Dy M */
+#define MP_SGR 0x02 /* CSI Db ; Dx ; Dy M/m */
+
#define TM_PUTTY (0xFFFF)
#define UPDATE_DELAY ((TICKSPERSEC+49)/50)/* ticks to defer window update */
@@ -1223,7 +1234,8 @@
term->erase_char = term->basic_erase_char;
term->alt_which = 0;
term_print_finish(term);
- term->xterm_mouse = 0;
+ term->xterm_mouse_mode = MM_NONE;
+ term->xterm_mouse_protocol = MP_NORMAL;
set_raw_mouse_mode(term->frontend, FALSE);
term->bracketed_paste = FALSE;
{
@@ -1469,7 +1481,7 @@
if (conf_get_int(term->conf, CONF_no_alt_screen))
swap_screen(term, 0, FALSE, FALSE);
if (conf_get_int(term->conf, CONF_no_mouse_rep)) {
- term->xterm_mouse = 0;
+ term->xterm_mouse_mode = MM_NONE;
set_raw_mouse_mode(term->frontend, 0);
}
if (conf_get_int(term->conf, CONF_no_remote_charset)) {
@@ -2475,13 +2487,23 @@
term->disptop = 0;
break;
case 1000: /* xterm mouse 1 (normal) */
- term->xterm_mouse = state ? 1 : 0;
+ term->xterm_mouse_mode = state ? MM_NORMAL : MM_NONE;
set_raw_mouse_mode(term->frontend, state);
break;
case 1002: /* xterm mouse 2 (inc. button drags) */
- term->xterm_mouse = state ? 2 : 0;
+ term->xterm_mouse_mode = state ? MM_BTN_EVENT : MM_NONE;
set_raw_mouse_mode(term->frontend, state);
break;
+ case 1003: /* xterm any event tracking */
+ term->xterm_mouse_mode = state ? MM_ANY_EVENT : MM_NONE;
+ set_raw_mouse_mode(term->frontend, state);
+ break;
+ case 1006: /* use SGR 1006 mouse protocol */
+ term->xterm_mouse_protocol = state ? MP_SGR : MP_NORMAL;
+ break;
+ case 1015: /* use URXVT 1015 mouse protocol */
+ term->xterm_mouse_protocol = state ? MP_URXVT : MP_NORMAL;
+ break;
case 1047: /* alternate screen */
compatibility(OTHER);
deselect(term);
@@ -5755,7 +5777,7 @@
{
pos selpoint;
termline *ldata;
- int raw_mouse = (term->xterm_mouse &&
+ int raw_mouse = (term->xterm_mouse_mode &&
!term->no_mouse_rep &&
!(term->mouse_override && shift));
int default_seltype;
@@ -5808,36 +5830,47 @@
if (raw_mouse &&
(term->selstate != ABOUT_TO) && (term->selstate != DRAGGING)) {
int encstate = 0, r, c;
- char abuf[16];
+ char abuf[64];
+ char m; /* SGR 1006's postfix character ('M' or 'm') */
+ size_t l;
if (term->ldisc) {
switch (braw) {
case MBT_LEFT:
- encstate = 0x20; /* left button down */
+ encstate = 0x00; /* left button down */
break;
case MBT_MIDDLE:
- encstate = 0x21;
+ encstate = 0x01;
break;
case MBT_RIGHT:
- encstate = 0x22;
+ encstate = 0x02;
break;
case MBT_WHEEL_UP:
- encstate = 0x60;
+ encstate = 0x40;
break;
case MBT_WHEEL_DOWN:
- encstate = 0x61;
+ encstate = 0x41;
break;
+ case MBT_NOTHING: /* for any event tracking */
+ encstate = 0x03;
+ break;
default: break; /* placate gcc warning about enum use */
}
switch (a) {
case MA_DRAG:
- if (term->xterm_mouse == 1)
+ if (term->xterm_mouse_mode == MM_NORMAL)
return;
encstate += 0x20;
break;
+ case MA_MOVE:
+ if (term->xterm_mouse_mode != MM_ANY_EVENT)
+ return;
+ encstate += 0x20; /* add motion indicator */
+ break;
case MA_RELEASE:
- encstate = 0x23;
+ if (term->xterm_mouse_protocol != MP_SGR)
+ encstate = 0x03;
term->mouse_is_down = 0;
break;
case MA_CLICK:
@@ -5851,11 +5884,33 @@
encstate += 0x04;
if (ctrl)
encstate += 0x10;
- r = y + 33;
- c = x + 33;
- sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
- ldisc_send(term->ldisc, abuf, 6, 0);
+ switch (term->xterm_mouse_protocol) {
+ case MP_NORMAL:
+ encstate += 0x20;
+ r = y + 33;
+ c = x + 33;
+ sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
+ ldisc_send(term->ldisc, abuf, 6, 0);
+ break;
+ case MP_URXVT:
+ encstate += 0x20;
+ r = y + 1;
+ c = x + 1;
+ sprintf(abuf, "\033[%d;%d;%dM", encstate, c, r);
+ l = strlen(abuf);
+ ldisc_send(term->ldisc, abuf, l, 0);
+ break;
+ case MP_SGR:
+ r = y + 1;
+ c = x + 1;
+ m = a == MA_RELEASE ? 'm': 'M';
+ sprintf(abuf, "\033[<%d;%d;%d%c", encstate, c, r, m);
+ l = strlen(abuf);
+ ldisc_send(term->ldisc, abuf, l, 0);
+ break;
+ default: break; /* placate gcc warning about enum use */
+ }
}
return;
}
Index: terminal.h
===================================================================
--- terminal.h (revision 9575)
+++ terminal.h (working copy)
@@ -151,7 +151,8 @@
int seen_disp_event;
int big_cursor;
- int xterm_mouse; /* send mouse messages to host */
+ int xterm_mouse_mode; /* mouse event mode */
+ int xterm_mouse_protocol; /* mouse protocol */
int mouse_is_down; /* used while tracking mouse buttons */
int bracketed_paste;
Index: unix/gtkwin.c
===================================================================
--- unix/gtkwin.c (revision 9575)
+++ unix/gtkwin.c (working copy)
@@ -1321,7 +1321,7 @@
gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
struct gui_data *inst = (struct gui_data *)data;
- int shift, ctrl, alt, x, y, button;
+ int shift, ctrl, alt, x, y, button, act;
/* Remember the timestamp. */
inst->input_event_time = event->time;
@@ -1331,19 +1331,24 @@
shift = event->state & GDK_SHIFT_MASK;
ctrl = event->state & GDK_CONTROL_MASK;
alt = event->state & GDK_MOD1_MASK;
- if (event->state & GDK_BUTTON1_MASK)
+ if (event->state & GDK_BUTTON1_MASK) {
button = MBT_LEFT;
- else if (event->state & GDK_BUTTON2_MASK)
+ act = MA_DRAG;
+ } else if (event->state & GDK_BUTTON2_MASK) {
button = MBT_MIDDLE;
- else if (event->state & GDK_BUTTON3_MASK)
+ act = MA_DRAG;
+ } else if (event->state & GDK_BUTTON3_MASK) {
button = MBT_RIGHT;
- else
- return FALSE; /* don't even know what button! */
+ act = MA_DRAG;
+ } else {
+ button = MBT_NOTHING; /* no button is pressed */
+ act = MA_MOVE;
+ }
x = (event->x - inst->window_border) / inst->font_width;
y = (event->y - inst->window_border) / inst->font_height;
- term_mouse(inst->term, button, translate_button(button), MA_DRAG,
+ term_mouse(inst->term, button, translate_button(button), act,
x, y, shift, ctrl, alt);
return TRUE;
Index: putty.h
===================================================================
--- putty.h (revision 9575)
+++ putty.h (working copy)
@@ -196,7 +196,7 @@
} Mouse_Button;
typedef enum {
- MA_NOTHING, MA_CLICK, MA_2CLK, MA_3CLK, MA_DRAG, MA_RELEASE
+ MA_NOTHING, MA_CLICK, MA_2CLK, MA_3CLK, MA_DRAG, MA_MOVE, MA_RELEASE
} Mouse_Action;
/* Keyboard modifiers -- keys the user is actually holding down */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment