-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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