Origin: https://savannah.gnu.org/bugs/download.php?file_id=52911 Author: Hayaki Saito Date: Fri, 15 Mar 2013 16:23:54 +0100 Description: Support "bracket paste mode" and cursor-style manipulation Bug: https://savannah.gnu.org/bugs/?62102 Bug-Debian: https://bugs.debian.org/1019576 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 https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html --- ansi.c | 12 ++++++++++++ display.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ display.h | 4 ++++ extern.h | 4 ++++ layer.c | 26 ++++++++++++++++++++++++++ window.c | 2 ++ window.h | 2 ++ 7 files changed, 100 insertions(+) --- a/ansi.c +++ b/ansi.c @@ -194,6 +194,8 @@ p->w_origin = 0; p->w_insert = 0; p->w_revvid = 0; + p->w_bracketed = 0; + p->w_cursorstyle = 0; p->w_mouse = 0; p->w_curinv = 0; p->w_curvvis = 0; @@ -1346,6 +1348,12 @@ 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++) { @@ -1477,6 +1485,10 @@ LExtMouseMode(&curr->w_layer, curr->w_extmouse); break; /* case 1015: UXRVT mouse mode rejected */ + case 2004: /* bracketed paste mode */ + curr->w_bracketed = i ? 1 : 0; + LBracketedPasteMode(&curr->w_layer, curr->w_bracketed); + break; } } break; --- a/display.c +++ b/display.c @@ -131,6 +131,8 @@ int defobuflimit = OBUF_MAX; int defnonblock = -1; int defmousetrack = 0; +int defbracketed = 0; +int defcursorstyle = 0; #ifdef AUTO_NUKE int defautonuke = 0; #endif @@ -193,6 +195,8 @@ 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); } @@ -324,6 +328,8 @@ D_user = *u; D_processinput = ProcessInput; D_mousetrack = defmousetrack; + D_bracketed = defbracketed; + D_cursorstyle = defcursorstyle; return display; } @@ -498,6 +504,8 @@ D_mousetrack = 0; MouseMode(0); ExtMouseMode(0); + BracketedPasteMode(0); + CursorStyle(0); SetRendition(&mchar_null); SetFlow(FLOW_NOW); #ifdef MAPKEYS @@ -872,6 +880,42 @@ } } +void BracketedPasteMode(int mode) +{ + if (!display) + return; + + if (D_bracketed != mode) { + if (!D_CXT) + return; + if (D_bracketed) { + AddStr("\033[?2004l"); + } + if (mode) { + AddStr("\033[?2004h"); + } + D_bracketed = mode; + } +} + +void CursorStyle(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 */ @@ -1298,6 +1342,8 @@ CursorVisibility(0); MouseMode(0); ExtMouseMode(0); + BracketedPasteMode(0); + CursorStyle(0); SetRendition(&mchar_null); SetFlow(FLOW_NOW); @@ -3199,6 +3245,8 @@ int oldcurvis = D_curvis; int oldmouse = D_mouse; int oldextmouse = D_extmouse; + int oldbracketed = D_bracketed; + int oldcursorstyle = D_cursorstyle; oldrend = D_rend; len = D_obufp - D_obuf; @@ -3262,6 +3310,8 @@ CursorVisibility(oldcurvis); MouseMode(oldmouse); ExtMouseMode(oldextmouse); + BracketedPasteMode(oldbracketed); + CursorStyle(oldcursorstyle); if (D_CWS) { debug("ResizeDisplay: using WS\n"); --- a/display.h +++ b/display.h @@ -111,6 +111,8 @@ struct mouse_parse d_mouse_parse; /* state of mouse code parsing */ 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[5]; /* osc used */ #endif @@ -198,6 +200,8 @@ #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) --- a/extern.h +++ b/extern.h @@ -291,6 +291,8 @@ extern void CursorVisibility __P((int)); extern void MouseMode __P((int)); extern void ExtMouseMode __P((int)); +extern void BracketedPasteMode (int); +extern void CursorStyle (int); extern void SetFont __P((int)); extern void SetAttr __P((int)); extern void SetColor __P((int, int)); @@ -454,6 +456,8 @@ extern void LCursorkeysMode __P((struct layer *, int)); extern void LMouseMode __P((struct layer *, int)); extern void LExtMouseMode __P((struct layer *, int)); +extern void LBracketedPasteMode __P((struct layer *, int)); +extern void LCursorStyle __P((struct layer *, int)); #if defined(USEVARARGS) extern void LMsg __P((int, const char *, ...)) __attribute__((format(printf, 2, 3))); #else --- a/layer.c +++ b/layer.c @@ -840,6 +840,32 @@ } } +void LBracketedPasteMode(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(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(struct layer *l, int uself) { LClearArea(l, 0, 0, l->l_width - 1, l->l_height - 1, 0, uself); --- a/window.c +++ b/window.c @@ -509,6 +509,8 @@ CursorVisibility(fore->w_curinv ? -1 : fore->w_curvvis); MouseMode(fore->w_mouse); ExtMouseMode(fore->w_extmouse); + BracketedPasteMode(fore->w_bracketed); + CursorStyle(fore->w_cursorstyle); } } --- a/window.h +++ b/window.h @@ -241,6 +241,8 @@ #endif int w_mouse; /* mouse mode 0,9,1000 */ int w_extmouse; /* extended mouse mode 0,1006 */ + 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