Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save yoshikaw/4971296 to your computer and use it in GitHub Desktop.
Save yoshikaw/4971296 to your computer and use it in GitHub Desktop.
Support SGR 1006 mouse reporting, for GNU Screen 4.1 after add Bracketed Paste Mode and DECSCUSR support https://gist.github.com/saitoha/2977889
--- a/src/ansi.c
+++ b/src/ansi.c
@@ -195,6 +195,7 @@ register struct win *p;
p->w_mouse = 0;
p->w_bracketed = 0;
p->w_cursorstyle = 0;
+ p->w_mouse_protocol = 0;
p->w_curinv = 0;
p->w_curvvis = 0;
p->w_autolf = 0;
@@ -1471,6 +1471,11 @@ int c, intermediate;
curr->w_mouse = i ? a1 : 0;
LMouseMode(&curr->w_layer, curr->w_mouse);
break;
+ case 1006: /* sgr mouse*/
+ curr->w_mouse_protocol = i ? a1 : 0;
+ LMouseProtocol(&curr->w_layer, curr->w_mouse_protocol);
+ break;
+ /* case 1015: urxvt mouse */
case 2004: /* bracketed paste mode */
curr->w_bracketed = i ? 1 : 0;
LBracketedPasteMode(&curr->w_layer, curr->w_bracketed);
--- a/src/display.c
+++ b/src/display.c
@@ -187,6 +187,7 @@ DefRestore()
LMouseMode(flayer, 0);
LBracketedPasteMode(flayer, 0);
LCursorStyle(flayer, 0);
+ LMouseProtocol(flayer, 0);
LSetRendition(flayer, &mchar_null);
LSetFlow(flayer, nwin_default.flowflag & FLOW_NOW);
}
@@ -888,6 +888,35 @@ int mode;
}
}
+void
+MouseProtocol(mode)
+int mode;
+{
+ if (!display)
+ return;
+
+ if (mode < D_mousetrack)
+ mode = D_mousetrack;
+
+ if (D_mouseprotocol != mode)
+ {
+ char mousebuf[20];
+ if (!D_CXT)
+ return;
+ if (D_mouseprotocol)
+ {
+ sprintf(mousebuf, "\033[?%dl", D_mouseprotocol);
+ AddStr(mousebuf);
+ }
+ if (mode)
+ {
+ sprintf(mousebuf, "\033[?%dh", mode);
+ AddStr(mousebuf);
+ }
+ D_mouseprotocol = mode;
+ }
+}
+
static int StrCost;
/* ARGSUSED */
@@ -1315,6 +315,7 @@ int cur_only;
MouseMode(0);
BracketedPasteMode(0);
CursorStyle(0);
+ MouseProtocol(0);
SetRendition(&mchar_null);
SetFlow(FLOW_NOW);
@@ -3177,6 +3177,7 @@ NukePending()
int oldmouse = D_mouse;
int oldbracketed = D_bracketed;
int oldcursorstyle = D_cursorstyle;
+ int oldmouseprotocol = D_mouseprotocol;
oldrend = D_rend;
len = D_obufp - D_obuf;
@@ -3241,6 +3241,7 @@ NukePending()
MouseMode(oldmouse);
BracketedPasteMode(oldbracketed);
CursorStyle(oldcursorstyle);
+ MouseProtocol(oldmouseprotocol);
if (D_CWS)
{
debug("ResizeDisplay: using WS\n");
@@ -3465,20 +3465,65 @@ char *data;
if (D_mouse && D_forecv)
{
unsigned char *bp = (unsigned char *)buf;
- int x, y, i = size;
+ int x, y, i = size, j, k;
/* XXX this assumes that the string is read in as a whole... */
for (i = size; i > 0; i--, bp++)
{
- if (i > 5 && bp[0] == 033 && bp[1] == '[' && bp[2] == 'M')
+ if (bp[0] == 033 && bp[1] == '[' && bp[2] == 'M')
+ {
+ /* 8bit Normal protocol */
+ bp++;
+ i--;
+ }
+ else if (bp[0] == 033 && bp[1] == '[' && bp[2] == '<')
{
+ /* 8bit SGR 1006 protocol */
bp++;
i--;
}
- else if (i < 5 || bp[0] != 0233 || bp[1] != 'M')
+ else if (bp[0] == 0233 && bp[1] == 'M')
+ {
+ /* 7bit Normal protocol */
+ }
+ else if (bp[0] == 0233 && bp[1] == '<')
+ {
+ /* 7bit SGR 1006 protocol */
+ }
+ else
continue;
- x = bp[3] - 33;
- y = bp[4] - 33;
+
+ if (bp[1] == 'M') {
+ /* Normal protocol:
+ *
+ * CSI M Cb Cx Cy
+ * (Cb, Cx, Cy as byte.)
+ *
+ * This coordinate values (Cx, Cy) are added origin offset +1
+ * and base offset +32 (to make it printable)
+ */
+ x = bp[3] - 33;
+ y = bp[4] - 33;
+ } else if (bp[1] == '<') {
+ /* SGR 1006 protocol:
+ *
+ * CSI M Db ; Dx ; Dy M/m
+ * (Db, Dx, Dy as decimal formatted strings.)
+ *
+ * The coordinate values (Dx, Dy) are added origin offset +1
+ */
+ for (j = 2; '0' <= bp[j] && bp[j] <= '9'; j++)
+ ;
+ if (bp[j++] != ';')
+ continue;
+ for (x = 0; '0' <= bp[j] && bp[j] <= '9'; j++)
+ x = x * 10 + bp[j] - '0';
+ if (bp[j++] != ';')
+ continue;
+ for (y = 0; '0' <= bp[j] && bp[j] <= '9'; j++)
+ y = y * 10 + bp[j] - '0';
+ }
+
if (x >= D_forecv->c_xs && x <= D_forecv->c_xe && y >= D_forecv->c_ys && y <= D_forecv->c_ye)
{
if ((D_fore && D_fore->w_mouse) || (D_mousetrack && D_forecv->c_layer->l_mode == 1))
@@ -3488,15 +3588,36 @@ char *data;
y -= D_forecv->c_yoff;
if (x >= 0 && x < D_forecv->c_layer->l_width && y >= 0 && y < D_forecv->c_layer->l_height)
{
- bp[3] = x + 33;
- bp[4] = y + 33;
- i -= 4;
- bp += 4;
+ if (bp[1] == 'M')
+ {
+ bp[3] = x + 33;
+ bp[4] = y + 33;
+ i -= 4;
+ bp += 4;
+ }
+ else if (bp[1] == '<')
+ {
+ k = j;
+ while (bp[--k] != ';')
+ {
+ bp[k] = y % 10 + '0';
+ y /= 10;
+ }
+ while (bp[--k] != ';')
+ {
+ bp[k] = x % 10 + '0';
+ x /= 10;
+ }
+ i -= j;
+ bp += j;
+ }
continue;
}
}
}
- else if (D_mousetrack && bp[2] == '#')
+ else if (D_mousetrack && (
+ (bp[1] == 'M' && bp[2] == '#') || /* Normal protocol */
+ (bp[1] == '<' && bp[j] == 'm'))) /* SGR 1006 protocol */
{
/* 'focus' to the clicked region, only on mouse up */
struct canvas *cv = FindCanvas(x, y);
@@ -3512,11 +3512,23 @@ char *data;
bp--;
size--;
}
- if (i > 5)
- bcopy((char *)bp + 5, (char *)bp, i - 5);
- bp--;
- i -= 4;
- size -= 5;
+
+ if (bp[1] == 'M')
+ {
+ if (i > 5)
+ bcopy((char *)bp + 5, (char *)bp, i - 5);
+ bp--;
+ i -= 4;
+ size -= 5;
+ }
+ else if (bp[1] == '<')
+ {
+ if (i > j + 1)
+ bcopy((char *)bp + j + 1, (char *)bp, i - j - 1);
+ bp--;
+ i -= j;
+ size -= j + 1;
+ }
}
}
#ifdef ENCODINGS
--- a/src/display.h
+++ b/src/display.h
@@ -100,6 +100,7 @@ struct display
int d_hstatus; /* hardstatus used */
int d_lp_missing; /* last character on bot line missing */
int d_mouse; /* mouse mode */
+ int d_mouseprotocol; /* mouse protocol */
int d_mousetrack; /* set when user wants to use mouse even when the window
does not */
int d_bracketed; /* bracketed paste mode */
@@ -231,6 +231,7 @@ extern struct display TheDisplay;
#define D_hstatus DISPLAY(d_hstatus)
#define D_lp_missing DISPLAY(d_lp_missing)
#define D_mouse DISPLAY(d_mouse)
+#define D_mouseprotocol DISPLAY(d_mouseprotocol)
#define D_mousetrack DISPLAY(d_mousetrack)
#define D_xtermosc DISPLAY(d_xtermosc)
#define D_lpchar DISPLAY(d_lpchar)
--- a/src/layer.c
+++ b/src/layer.c
@@ -945,6 +945,23 @@ int on;
}
void
+LMouseProtocol(l, on)
+struct layer *l;
+int on;
+{
+ struct canvas *cv;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (D_blocked)
+ continue;
+ if (cv != D_forecv)
+ continue;
+ MouseProtocol(on);
+ }
+}
+
+void
LClearAll(l, uself)
struct layer *l;
int uself;
--- a/src/window.c
+++ b/src/window.c
@@ -500,6 +500,7 @@ WinRestore()
MouseMode(fore->w_mouse);
BracketedPasteMode(fore->w_bracketed);
CursorStyle(fore->w_cursorstyle);
+ MouseProtocol(fore->w_mouse_protocol);
}
}
--- a/src/window.h
+++ b/src/window.h
@@ -237,6 +237,7 @@ struct win
int w_mouse; /* mouse mode 0,9,1000 */
int w_bracketed; /* bracketed paste mode */
int w_cursorstyle; /* cursor style */
+ int w_mouse_protocol; /* mouse protocol 0,1006,1015 */
#ifdef HAVE_BRAILLE
int w_bd_x, w_bd_y; /* Braille cursor position */
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment