Hello, lists This patch adds the following two features to GNU Screen:
- Bracket Paste Mode (DECSET/DECRST 2004) - DECSCUSR(cursor style manipulation) By using "bracketed paste mode", the pasted text is bracketed with special control sequences. DECSCUSR can change cursor style and shape (blink/steady, block/Vertical bar/horizontal bar). ref: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html These days, many of xterm-compatible terminal emulators support these features. But current GNU Screen blocks them. This patch manages states of "Bracket Paste Mode (DECSET/DECRST 2004)" and DECSCUSR(cursor style manipulation), for each of screens. Please check it. Hayaki Saito <u...@zuse.jp> --- src/ansi.c | 13 +++++++++++++ src/display.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/display.h | 4 ++++ src/extern.h | 4 ++++ src/layer.c | 34 ++++++++++++++++++++++++++++++++++ src/window.c | 2 ++ src/window.h | 2 ++ 7 files changed, 117 insertions(+) diff --git a/src/ansi.c b/src/ansi.c index d88e153..89116c3 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -193,6 +193,8 @@ register struct win *p; p->w_insert = 0; p->w_revvid = 0; p->w_mouse = 0; + p->w_bracketed = 0; + p->w_cursorstyle = 0; p->w_curinv = 0; p->w_curvvis = 0; p->w_autolf = 0; @@ -1340,6 +1342,13 @@ int c, intermediate; break; } break; + case ' ': + if (c == 'q') + { + curr->w_cursorstyle = a1; + LCursorStyle(&curr->w_layer, curr->w_cursorstyle); + } + break; case '?': for (a2 = 0; a2 < curr->w_NumArgs; a2++) { @@ -1462,6 +1471,10 @@ int c, intermediate; curr->w_mouse = i ? a1 : 0; LMouseMode(&curr->w_layer, curr->w_mouse); break; + case 2004: /* bracketed paste mode */ + curr->w_bracketed = i ? 1 : 0; + LBracketedPasteMode(&curr->w_layer, curr->w_bracketed); + break; } } break; diff --git a/src/display.c b/src/display.c index 94c05f1..e507cf3 100644 --- a/src/display.c +++ b/src/display.c @@ -121,6 +121,8 @@ struct display TheDisplay; int defobuflimit = OBUF_MAX; int defnonblock = -1; int defmousetrack = 0; +int defbracketed = 0; +int defcursorstyle = 0; #ifdef AUTO_NUKE int defautonuke = 0; #endif @@ -183,6 +185,8 @@ DefRestore() LCursorkeysMode(flayer, 0); LCursorVisibility(flayer, 0); LMouseMode(flayer, 0); + LBracketedPasteMode(flayer, 0); + LCursorStyle(flayer, 0); LSetRendition(flayer, &mchar_null); LSetFlow(flayer, nwin_default.flowflag & FLOW_NOW); } @@ -314,6 +318,8 @@ struct mode *Mode; D_user = *u; D_processinput = ProcessInput; D_mousetrack = defmousetrack; + D_bracketed = defbracketed; + D_cursorstyle = defcursorstyle; return display; } @@ -487,6 +493,8 @@ FinitTerm() if (D_mousetrack) D_mousetrack = 0; MouseMode(0); + BracketedPasteMode(0); + CursorStyle(0); SetRendition(&mchar_null); SetFlow(FLOW_NOW); #ifdef MAPKEYS @@ -836,6 +844,50 @@ int mode; } } +void +BracketedPasteMode(mode) +int mode; +{ + if (!display) + return; + + if (D_bracketed != mode) + { + if (!D_CXT) + return; + if (D_bracketed) + { + AddStr("\033[?2004l\a"); + } + if (mode) + { + AddStr("\033[?2004h\a"); + } + D_bracketed = mode; + } +} + +void +CursorStyle(mode) +int mode; +{ + char buf[32]; + + if (!display) + return; + + if (D_cursorstyle != mode) + { + if (!D_CXT) + return; + if (mode < 0) + return; + sprintf(buf, "\033[%d q", mode); + AddStr(buf); + D_cursorstyle = mode; + } +} + static int StrCost; /* ARGSUSED */ @@ -1261,6 +1313,8 @@ int cur_only; CursorkeysMode(0); CursorVisibility(0); MouseMode(0); + BracketedPasteMode(0); + CursorStyle(0); SetRendition(&mchar_null); SetFlow(FLOW_NOW); @@ -3121,6 +3175,8 @@ NukePending() int oldkeypad = D_keypad, oldcursorkeys = D_cursorkeys; int oldcurvis = D_curvis; int oldmouse = D_mouse; + int oldbracketed = D_bracketed; + int oldcursorstyle = D_cursorstyle; oldrend = D_rend; len = D_obufp - D_obuf; @@ -3183,6 +3239,8 @@ NukePending() CursorkeysMode(oldcursorkeys); CursorVisibility(oldcurvis); MouseMode(oldmouse); + BracketedPasteMode(oldbracketed); + CursorStyle(oldcursorstyle); if (D_CWS) { debug("ResizeDisplay: using WS\n"); diff --git a/src/display.h b/src/display.h index e8b3b80..34d0a26 100644 --- a/src/display.h +++ b/src/display.h @@ -102,6 +102,8 @@ struct display int d_mouse; /* mouse mode */ int d_mousetrack; /* set when user wants to use mouse even when the window does not */ + int d_bracketed; /* bracketed paste mode */ + int d_cursorstyle; /* cursor style */ #ifdef RXVT_OSC int d_xtermosc[4]; /* osc used */ #endif @@ -189,6 +191,8 @@ extern struct display TheDisplay; #define D_user DISPLAY(d_user) #define D_username (DISPLAY(d_user) ? DISPLAY(d_user)->u_name : 0) +#define D_bracketed DISPLAY(d_bracketed) +#define D_cursorstyle DISPLAY(d_cursorstyle) #define D_canvas DISPLAY(d_canvas) #define D_cvlist DISPLAY(d_cvlist) #define D_layout DISPLAY(d_layout) diff --git a/src/extern.h b/src/extern.h index b8cead4..a2abffa 100644 --- a/src/extern.h +++ b/src/extern.h @@ -286,6 +286,8 @@ extern void CursorkeysMode __P((int)); extern void ReverseVideo __P((int)); extern void CursorVisibility __P((int)); extern void MouseMode __P((int)); +extern void BracketedPasteMode __P((int)); +extern void CursorStyle __P((int)); extern void SetFont __P((int)); extern void SetAttr __P((int)); extern void SetColor __P((int, int)); @@ -445,6 +447,8 @@ extern void LSetFlow __P((struct layer *, int)); extern void LKeypadMode __P((struct layer *, int)); extern void LCursorkeysMode __P((struct layer *, int)); extern void LMouseMode __P((struct layer *, int)); +extern void LBracketedPasteMode __P((struct layer *, int)); +extern void LCursorStyle __P((struct layer *, int)); #ifdef USEVARARGS extern void LMsg __P((int, const char *, ...)) __attribute__((format(printf, 2, 3))); #else diff --git a/src/layer.c b/src/layer.c index 1ae7972..5986901 100644 --- a/src/layer.c +++ b/src/layer.c @@ -911,6 +911,40 @@ int on; } void +LBracketedPasteMode(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; + BracketedPasteMode(on); + } +} + +void +LCursorStyle(l, style) +struct layer *l; +int style; +{ + 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; + CursorStyle(style); + } +} + +void LClearAll(l, uself) struct layer *l; int uself; diff --git a/src/window.c b/src/window.c index 1c6f5b6..0bcfe09 100644 --- a/src/window.c +++ b/src/window.c @@ -498,6 +498,8 @@ WinRestore() ReverseVideo(fore->w_revvid); CursorVisibility(fore->w_curinv ? -1 : fore->w_curvvis); MouseMode(fore->w_mouse); + BracketedPasteMode(fore->w_bracketed); + CursorStyle(fore->w_cursorstyle); } } diff --git a/src/window.h b/src/window.h index 7311ecb..0429c52 100644 --- a/src/window.h +++ b/src/window.h @@ -235,6 +235,8 @@ struct win char w_xtermosc[4][MAXSTR]; /* special xterm/rxvt escapes */ #endif int w_mouse; /* mouse mode 0,9,1000 */ + int w_bracketed; /* bracketed paste mode */ + int w_cursorstyle; /* cursor style */ #ifdef HAVE_BRAILLE int w_bd_x, w_bd_y; /* Braille cursor position */ #endif -- 1.8.1.3