patch 8.2.3666: libvterm is outdated

Problem:    Libvterm is outdated.
Solution:   Include patches from revision 769 to revision 789.
This commit is contained in:
Bram Moolenaar
2021-11-24 19:30:55 +00:00
parent 19916a8c89
commit 7da341560e
18 changed files with 953 additions and 238 deletions

View File

@ -377,6 +377,7 @@ SRC_ALL = \
src/libvterm/t/30state_pen.test \
src/libvterm/t/31state_rep.test \
src/libvterm/t/32state_flow.test \
src/libvterm/t/40state_selection.test \
src/libvterm/t/60screen_ascii.test \
src/libvterm/t/61screen_unicode.test \
src/libvterm/t/62screen_damage.test \

View File

@ -37,7 +37,7 @@ INCFILES=$(TBLFILES:.tbl=.inc)
HFILES_INT=$(sort $(wildcard src/*.h)) $(HFILES)
VERSION_MAJOR=0
VERSION_MINOR=1
VERSION_MINOR=2
VERSION_CURRENT=0
VERSION_REVISION=0
@ -97,7 +97,7 @@ install-inc:
install -d $(DESTDIR)$(INCDIR)
install -m644 $(HFILES) $(DESTDIR)$(INCDIR)
install -d $(DESTDIR)$(LIBDIR)/pkgconfig
sed -e "s,@PREFIX@,$(PREFIX)," -e "s,@LIBDIR@,$(LIBDIR)," -e "s,@VERSION@,$(VERSION)," <vterm.pc.in >$(DESTDIR)$(LIBDIR)/pkgconfig/vterm.pc
sed -e "s,@INCDIR@,$(INCDIR)," -e "s,@LIBDIR@,$(LIBDIR)," -e "s,@VERSION@,$(VERSION)," <vterm.pc.in >$(DESTDIR)$(LIBDIR)/pkgconfig/vterm.pc
install-lib: $(LIBRARY)
install -d $(DESTDIR)$(LIBDIR)

View File

@ -4,228 +4,275 @@ between states.
1 = VT100
2 = VT220
3 = VT320
x = xterm
C0 controls
C0 controls
123 0x00 = NUL
123 0x07 = BEL
123 0x08 = BS
123 0x09 = HT
123 0x0A = LF
123 0x0B = VT
123 0x0C = FF
123 0x0D = CR
123 0x0E = LS1
123 0x0F = LS0
(0x18 = CAN)
(0x1A = SUB)
(0x1B = ESC)
123 0x00 = NUL
123x 0x07 = BEL
123x 0x08 = BS
123x 0x09 = HT
123x 0x0A = LF
123x 0x0B = VT
123x 0x0C = FF
123x 0x0D = CR
123x 0x0E = LS1
123x 0x0F = LS0
(0x18 = CAN)
(0x1A = SUB)
(0x1B = ESC)
123 0x7f = DEL (ignored)
123 0x7f = DEL (ignored)
C1 controls
C1 controls
123 0x84 = IND
123 0x85 = NEL
123 0x88 = HTS
123 0x8D = RI
23 0x8e = SS2
23 0x8f = SS3
(0x90 = DCS)
(0x9B = CSI)
(0x9C = ST)
(0x9D = OSC)
123x 0x84 = IND
123x 0x85 = NEL
123x 0x88 = HTS
123x 0x8D = RI
23x 0x8E = SS2
23x 0x8F = SS3
(0x90 = DCS)
(0x98 = SOS)
(0x9B = CSI)
(0x9C = ST)
(0x9D = OSC)
(0x9E = PM)
(0x9F = APC)
Escape sequences
- excluding sequences that are C1 aliases
Escape sequences
- excluding sequences that are C1 aliases
123 ESC () = SCS, select character set (G0, G1)
23 ESC *+ = SCS, select character set (G2, G3)
123 ESC 7 = DECSC - save cursor
123 ESC 8 = DECRC - restore cursor
123 ESC # 3 = DECDHL, double-height line (top half)
123 ESC # 4 = DECDHL, double-height line (bottom half)
123 ESC # 5 = DECSWL, single-width single-height line
123 ESC # 6 = DECDWL, double-width single-height line
123 ESC # 8 = DECALN
123 ESC < = Ignored (used by VT100 to exit VT52 mode)
123 ESC = = DECKPAM, keypad application mode
123 ESC > = DECKPNM, keypad numeric mode
23 ESC Sp F = S7C1T
23 ESC Sp G = S8C1T
(ESC P = DCS)
(ESC [ = CSI)
(ESC \ = ST)
(ESC ] = OSC)
123 ESC c = RIS, reset initial state
3 ESC n = LS2
3 ESC o = LS3
3 ESC ~ = LS1R
3 ESC } = LS2R
3 ESC | = LS3R
123x ESC ( = SCS, select character set G0
123x ESC ) = SCS, select character set G1
23x ESC * = SCS, select character set G2
23x ESC + = SCS, select character set G3
123x ESC 7 = DECSC - save cursor
123x ESC 8 = DECRC - restore cursor
123x ESC # 3 = DECDHL, double-height line (top half)
123x ESC # 4 = DECDHL, double-height line (bottom half)
123x ESC # 5 = DECSWL, single-width single-height line
123x ESC # 6 = DECDWL, double-width single-height line
123x ESC # 8 = DECALN
123 ESC < = Ignored (used by VT100 to exit VT52 mode)
123x ESC = = DECKPAM, keypad application mode
123x ESC > = DECKPNM, keypad numeric mode
23x ESC Sp F = S7C1T
23x ESC Sp G = S8C1T
(ESC P = DCS)
(ESC X = SOS)
(ESC [ = CSI)
(ESC \ = ST)
(ESC ] = OSC)
(ESC ^ = PM)
(ESC _ = APC)
123x ESC c = RIS, reset initial state
3x ESC n = LS2
3x ESC o = LS3
3x ESC | = LS3R
3x ESC } = LS2R
3x ESC ~ = LS1R
DCSes
DCSes
3 DCS $ q ST = DECRQSS
3 m = Request SGR
Sp q = Request DECSCUSR
3 " q = Request DECSCA
3 r = Request DECSTBM
s = Request DECSLRM
3x DCS $ q ST = DECRQSS
3x m = Request SGR
x Sp q = Request DECSCUSR
3x " q = Request DECSCA
3x r = Request DECSTBM
x s = Request DECSLRM
CSIs
23 CSI @ = ICH
123 CSI A = CUU
123 CSI B = CUD
123 CSI C = CUF
123 CSI D = CUB
CSI E = CNL
CSI F = CPL
CSI G = CHA
123 CSI H = CUP
CSI I = CHT
123 CSI J = ED
23 CSI ? J = DECSED, selective erase in display
123 CSI K = EL
23 CSI ? K = DECSEL, selective erase in line
23 CSI L = IL
23 CSI M = DL
23 CSI P = DCH
CSI S = SU
CSI T = SD
23 CSI X = ECH
CSI Z = CBT
CSI ` = HPA
CSI a = HPR
CSI b = REP
123 CSI c = DA, device attributes
123 0 = DA
23 CSI > c = DECSDA
23 0 = SDA
CSI d = VPA
CSI e = VPR
123 CSI f = HVP
123 CSI g = TBC
123 CSI h = SM, Set mode
123 CSI ? h = DECSM, DEC set mode
CSI j = HPB
CSI k = VPB
123 CSI l = RM, Reset mode
123 CSI ? l = DECRM, DEC reset mode
123 CSI m = SGR, Set Graphic Rendition
123 CSI n = DSR, Device Status Report
23 5 = operating status
23 6 = CPR = cursor position
23 CSI ? n = DECDSR; behaves as DSR but uses CSI ? instead of CSI to respond
23 CSI ! p = DECSTR, soft terminal reset
3 CSI ? $ p = DECRQM, request mode
CSI Sp q = DECSCUSR (odd numbers blink, even numbers solid)
1 or 2 = block
3 or 4 = underline
5 or 6 = I-beam to left
23 CSI " q = DECSCA, select character attributes
123 CSI r = DECSTBM
CSI s = DECSLRM
CSI ' } = DECIC
CSI ' ~ = DECDC
CSIs
23x CSI @ = ICH
123x CSI A = CUU
123x CSI B = CUD
123x CSI C = CUF
123x CSI D = CUB
x CSI E = CNL
x CSI F = CPL
x CSI G = CHA
123x CSI H = CUP
x CSI I = CHT
123x CSI J = ED
23x CSI ? J = DECSED, selective erase in display
123x CSI K = EL
23x CSI ? K = DECSEL, selective erase in line
23x CSI L = IL
23x CSI M = DL
23x CSI P = DCH
x CSI S = SU
x CSI T = SD
23x CSI X = ECH
x CSI Z = CBT
x CSI ` = HPA
x CSI a = HPR
x CSI b = REP
123x CSI c = DA, device attributes
123 0 = DA
23x CSI > c = DECSDA
23 0 = SDA
x CSI d = VPA
x CSI e = VPR
123x CSI f = HVP
123x CSI g = TBC
123x CSI h = SM, Set mode
123x CSI ? h = DECSM, DEC set mode
CSI j = HPB
CSI k = VPB
123x CSI l = RM, Reset mode
123x CSI ? l = DECRM, DEC reset mode
123x CSI m = SGR, Set Graphic Rendition
123x CSI n = DSR, Device Status Report
23x 5 = operating status
23x 6 = CPR = cursor position
23x CSI ? n = DECDSR; behaves as DSR but uses CSI ? instead of CSI to respond
23x CSI ! p = DECSTR, soft terminal reset
3x CSI ? $ p = DECRQM, request private mode
x CSI Sp q = DECSCUSR (odd numbers blink, even numbers solid)
1 or 2 = block
3 or 4 = underline
5 or 6 = I-beam to left
23x CSI " q = DECSCA, select character attributes
123x CSI r = DECSTBM
x CSI s = DECSLRM
x CSI ' } = DECIC
x CSI ' ~ = DECDC
OSCs
OSCs
OSC 0; = Set icon name and title
OSC 1; = Set icon name
OSC 2; = Set title
x OSC 0; = Set icon name and title
x OSC 1; = Set icon name
x OSC 2; = Set title
x OSC 52; = Selection management
Standard modes
Standard modes
23 SM 4 = IRM
123 SM 20 = NLM, linefeed/newline
23x SM 4 = IRM
123x SM 20 = NLM, linefeed/newline
DEC modes
DEC modes
123 DECSM 1 = DECCKM, cursor keys
123 DECSM 5 = DECSCNM, screen
123 DECSM 6 = DECOM, origin
123 DECSM 7 = DECAWM, autowrap
DECSM 12 = Cursor blink
23 DECSM 25 = DECTCEM, text cursor enable
DECSM 69 = DECVSSM, vertical screen split
DECSM 1000 = Mouse click/release tracking
DECSM 1002 = Mouse click/release/drag tracking
DECSM 1003 = Mouse all movements tracking
DECSM 1004 = Focus in/out reporting
DECSM 1005 = Mouse protocol extended (UTF-8) - not recommended
DECSM 1006 = Mouse protocol SGR
DECSM 1015 = Mouse protocol rxvt
DECSM 1047 = Altscreen
DECSM 1048 = Save cursor
DECSM 1049 = 1047 + 1048
DECSM 2004 = Bracketed paste
123x DECSM 1 = DECCKM, cursor keys
123x DECSM 5 = DECSCNM, screen
123x DECSM 6 = DECOM, origin
123x DECSM 7 = DECAWM, autowrap
x DECSM 12 = Cursor blink
23x DECSM 25 = DECTCEM, text cursor enable
x DECSM 69 = DECVSSM, vertical screen split
x DECSM 1000 = Mouse click/release tracking
x DECSM 1002 = Mouse click/release/drag tracking
x DECSM 1003 = Mouse all movements tracking
x DECSM 1004 = Focus in/out reporting
x DECSM 1005 = Mouse protocol extended (UTF-8) - not recommended
x DECSM 1006 = Mouse protocol SGR
x DECSM 1015 = Mouse protocol rxvt
x DECSM 1047 = Altscreen
x DECSM 1048 = Save cursor
x DECSM 1049 = 1047 + 1048
x DECSM 2004 = Bracketed paste
Graphic Renditions
Graphic Renditions
123 SGR 0 = Reset
123 SGR 1 = Bold on
SGR 3 = Italic on
123 SGR 4 = Underline single
SGR 4:x = Underline style
123 SGR 5 = Blink on
123 SGR 7 = Reverse on
SGR 8 = Conceal on
SGR 9 = Strikethrough on
SGR 10-19 = Select font
SGR 21 = Underline double
23 SGR 22 = Bold off
SGR 23 = Italic off
23 SGR 24 = Underline off
23 SGR 25 = Blink off
23 SGR 27 = Reverse off
SGR 28 = Conceal off
SGR 29 = Strikethrough off
SGR 30-37 = Foreground ANSI
SGR 38 = Foreground alternative palette
SGR 39 = Foreground default
SGR 40-47 = Background ANSI
SGR 48 = Background alternative palette
SGR 49 = Background default
SGR 90-97 = Foreground ANSI high-intensity
SGR 100-107 = Background ANSI high-intensity
123x SGR 0 = Reset
123x SGR 1 = Bold on
x SGR 3 = Italic on
123x SGR 4 = Underline single
SGR 4:x = Underline style
123x SGR 5 = Blink on
123x SGR 7 = Reverse on
x SGR 8 = Conceal on
x SGR 9 = Strikethrough on
SGR 10-19 = Select font
x SGR 21 = Underline double
23x SGR 22 = Bold off
x SGR 23 = Italic off
23x SGR 24 = Underline off
23x SGR 25 = Blink off
23x SGR 27 = Reverse off
x SGR 28 = Conceal off
x SGR 29 = Strikethrough off
x SGR 30-37 = Foreground ANSI
x SGR 38 = Foreground alternative palette
x SGR 39 = Foreground default
x SGR 40-47 = Background ANSI
x SGR 48 = Background alternative palette
x SGR 49 = Background default
x SGR 90-97 = Foreground ANSI high-intensity
x SGR 100-107 = Background ANSI high-intensity
The state storage used by ESC 7 and DECSM 1048/1049 is shared.
Unimplemented sequences:
Unimplemented sequences:
The following sequences are not recognised by libvterm.
123 0x05 = ENQ
3 0x11 = DC1 (XON)
3 0x13 = DC3 (XOFF)
12 ESC Z = DECID, identify terminal
DCS $ q = [DECRQSS]
3 " p = Request DECSCL
3 $ } = Request DECSASD
3 $ ~ = Request DECSSDT
23 DCS { = DECDLD, down-line-loadable character set
23 DCS | = DECUDK, user-defined key
23 CSI i = DEC printer control
23 CSI " p = DECSCL, set compatibility level
1 CSI q = DECLL, load LEDs
3 CSI $ u = DECRQTSR, request terminal state report
3 1 = terminal state report
3 CSI & u = DECRQUPSS, request user-preferred supplemental set
3 CSI $ w = DECRQPSR, request presentation state report
3 1 = cursor information report
3 2 = tab stop report
1 CSI x = DECREQTPARM, request terminal parameters
123 CSI y = DECTST, invoke confidence test
3 CSI $ } = DECSASD, select active status display
3 CSI $ ~ = DECSSDT, select status line type
23 SM 2 = KAM, keyboard action
123 SM 12 = SRM, send/receive
123 DECSM 2 = DECANM, ANSI/VT52
123 DECSM 3 = DECCOLM, 132 column
123 DECSM 4 = DECSCLM, scrolling
123 DECSM 8 = DECARM, auto-repeat
12 DECSM 9 = DECINLM, interlace
23 DECSM 18 = DECPFF, print form feed
23 DECSM 19 = DECPEX, print extent
23 DECSM 42 = DECNRCM, national/multinational character
123x 0x05 = ENQ
3 0x11 = DC1 (XON)
3 0x13 = DC3 (XOFF)
x ESC % @ = Select default character set
x ESC % G = Select UTF-8 character set
x ESC 6 = DECBI, Back Index
12 ESC Z = DECID, identify terminal
x DCS + Q = XTGETXRES, Request resource values
DCS $ q = [DECRQSS]
3x " p = Request DECSCL
x t = Request DECSLPP
x $ | = Request DECSCPP
x * | = Request DECSLNS
3 $ } = Request DECSASD
3 $ ~ = Request DECSSDT
x DCS + p = XTSETTCAP, set termcap/terminfo data
x DCS + q = XTGETTCAP, request termcap/terminfo
23 DCS { = DECDLD, down-line-loadable character set
23x DCS | = DECUDK, user-defined key
x CSI Sp @ = Shift left columns
x CSI Sp A = Shift right columns
x CSI # P = XTPUSHCOLORS, push current dynamic colours to stack
x CSI # Q = XTPOPCOLORS, pop dynamic colours from stack
x CSI # R = XTREPORTCOLORS, report current entry on palette stack
x CSI ? S = XTSMGRAPHICS, set/request graphics attribute
x CSI > T = XTRMTITLE, reset title mode features
23x CSI i = DEC printer control
x CSI > m = XTMODKEYS, set key modifier options
x CSI > n = (XTMODKEYS), reset key modifier options
x CSI $ p = DECRQM, request ANSI mode
23x CSI " p = DECSCL, set compatibility level
x CSI > p = XTSMPOINTER, set resource value pointer mode
1 x CSI q = DECLL, load LEDs
x CSI ? r = XTRESTORE, restore DEC private mode values
x CSI $ r = DECCARA, change attributes in rectangular area
x CSI > s = XTSHIFTESCAPE, set/reset shift-escape options
x CSI ? s = XTSAVE, save DEC private mode values
x CSI t = XTWINOPS, window operations
x CSI > t = XTSMTITLE, set title mode features
x CSI $ t = DECRARA, reset attributes in rectangular area
3 CSI $ u = DECRQTSR, request terminal state report
3 1 = terminal state report
3 CSI & u = DECRQUPSS, request user-preferred supplemental set
x CSI $ v = DECCRA, copy rectangular area
3x CSI $ w = DECRQPSR, request presentation state report
3x 1 = cursor information report
3x 2 = tab stop report
x CSI ' w = DECEFR, enable filter rectangle
1 x CSI x = DECREQTPARM, request terminal parameters
x CSI * x = DECSACE, select attribute change extent
x CSI $ x = DECFRA, fill rectangular area
123 CSI y = DECTST, invoke confidence test
x CSI $ z = DECERA, erase rectangular area
x CSI # { = XTPUSHSGR, push video attributes onto stack
x CSI $ { = DECSERA, selective erase in rectangular area
x CSI # | = XTREPORTSGR, report selected graphic rendition
x CSI $ | = DECSCPP, select columns per page
x CSI # } = XTPOPSGR, pop video attributes from stack
3 CSI $ } = DECSASD, select active status display
3 CSI $ ~ = DECSSDT, select status line type
23 SM 2 = KAM, keyboard action
123 SM 12 = SRM, send/receive
123 DECSM 2 = DECANM, ANSI/VT52
123 DECSM 3 = DECCOLM, 132 column
123 DECSM 4 = DECSCLM, scrolling
123 DECSM 8 = DECARM, auto-repeat
12 DECSM 9 = DECINLM, interlace
23 DECSM 18 = DECPFF, print form feed
23 DECSM 19 = DECPEX, print extent
23 DECSM 42 = DECNRCM, national/multinational character

View File

@ -17,10 +17,11 @@ extern "C" {
// from stdint.h
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#define VTERM_VERSION_MAJOR 0
#define VTERM_VERSION_MINOR 1
#define VTERM_VERSION_MINOR 2
#define VTERM_CHECK_VERSION \
vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR)
@ -267,6 +268,14 @@ enum {
VTERM_N_PROP_MOUSES
};
typedef enum {
VTERM_SELECTION_CLIPBOARD = (1<<0),
VTERM_SELECTION_PRIMARY = (1<<1),
VTERM_SELECTION_SECONDARY = (1<<2),
VTERM_SELECTION_SELECT = (1<<3),
VTERM_SELECTION_CUT0 = (1<<4), /* also CUT1 .. CUT7 by bitshifting */
} VTermSelectionMask;
typedef struct {
const uint32_t *chars;
int width;
@ -375,6 +384,9 @@ typedef struct {
int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
int (*osc)(int command, VTermStringFragment frag, void *user);
int (*dcs)(const char *command, size_t commandlen, VTermStringFragment frag, void *user);
int (*apc)(VTermStringFragment frag, void *user);
int (*pm)(VTermStringFragment frag, void *user);
int (*sos)(VTermStringFragment frag, void *user);
int (*resize)(int rows, int cols, void *user);
} VTermParserCallbacks;
@ -419,8 +431,16 @@ typedef struct {
int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
int (*osc)(int command, VTermStringFragment frag, void *user);
int (*dcs)(const char *command, size_t commandlen, VTermStringFragment frag, void *user);
int (*apc)(VTermStringFragment frag, void *user);
int (*pm)(VTermStringFragment frag, void *user);
int (*sos)(VTermStringFragment frag, void *user);
} VTermStateFallbacks;
typedef struct {
int (*set)(VTermSelectionMask mask, VTermStringFragment frag, void *user);
int (*query)(VTermSelectionMask mask, void *user);
} VTermSelectionCallbacks;
VTermState *vterm_obtain_state(VTerm *vt);
void vterm_state_set_callbacks(VTermState *state, const VTermStateCallbacks *callbacks, void *user);
@ -457,6 +477,11 @@ const VTermLineInfo *vterm_state_get_lineinfo(const VTermState *state, int row);
*/
void vterm_state_convert_color_to_rgb(const VTermState *state, VTermColor *col);
void vterm_state_set_selection_callbacks(VTermState *state, const VTermSelectionCallbacks *callbacks, void *user,
char *buffer, size_t buflen);
void vterm_state_send_selection(VTermState *state, VTermSelectionMask mask, VTermStringFragment frag);
// ------------
// Screen layer
// ------------

View File

@ -89,6 +89,9 @@ void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod)
if (!(state->mouse_flags & MOUSE_WANT_CLICK))
return;
if(!state->mouse_flags)
return;
if(button < 4) {
output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row);
}

View File

@ -77,10 +77,25 @@ static void string_fragment(VTerm *vt, const char *str, size_t len, int final)
break;
case DCS:
if(len && vt->parser.callbacks && vt->parser.callbacks->dcs)
if(vt->parser.callbacks && vt->parser.callbacks->dcs)
(*vt->parser.callbacks->dcs)(vt->parser.v.dcs.command, vt->parser.v.dcs.commandlen, frag, vt->parser.cbdata);
break;
case APC:
if(vt->parser.callbacks && vt->parser.callbacks->apc)
(*vt->parser.callbacks->apc)(frag, vt->parser.cbdata);
break;
case PM:
if(vt->parser.callbacks && vt->parser.callbacks->pm)
(*vt->parser.callbacks->pm)(frag, vt->parser.cbdata);
break;
case SOS:
if(vt->parser.callbacks && vt->parser.callbacks->sos)
(*vt->parser.callbacks->sos)(frag, vt->parser.cbdata);
break;
case NORMAL:
case CSI_LEADER:
case CSI_ARGS:
@ -112,6 +127,9 @@ size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
break;
case OSC:
case DCS:
case APC:
case PM:
case SOS:
string_start = bytes;
break;
}
@ -150,6 +168,9 @@ size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
// fallthrough
}
else if(c < 0x20) { // other C0
if(vt->parser.state == SOS)
continue; // All other C0s permitted in SOS
if(vterm_get_special_pty_type() == 2) {
if(c == 0x08) // BS
// Set the trick for BS output after a sequence, to delay backspace
@ -176,7 +197,8 @@ size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
((!IS_STRING_STATE() || c == 0x5c))) {
c += 0x40;
c1_allowed = TRUE;
string_len -= 1;
if(string_len)
string_len -= 1;
vt->parser.in_esc = FALSE;
}
else {
@ -279,6 +301,9 @@ size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
string_state:
case OSC:
case DCS:
case APC:
case PM:
case SOS:
if(c == 0x07 || (c1_allowed && c == 0x9c)) {
string_fragment(vt, string_start, string_len, TRUE);
ENTER_NORMAL_STATE();
@ -308,6 +333,12 @@ string_state:
vt->parser.v.dcs.commandlen = 0;
ENTER_STATE(DCS_COMMAND);
break;
case 0x98: // SOS
vt->parser.string_initial = TRUE;
ENTER_STATE(SOS);
string_start = bytes + pos + 1;
string_len = 0;
break;
case 0x9b: // CSI
vt->parser.v.csi.leaderlen = 0;
ENTER_STATE(CSI_LEADER);
@ -318,6 +349,18 @@ string_state:
string_start = bytes + pos + 1;
ENTER_STATE(OSC_COMMAND);
break;
case 0x9e: // PM
vt->parser.string_initial = TRUE;
ENTER_STATE(PM);
string_start = bytes + pos + 1;
string_len = 0;
break;
case 0x9f: // APC
vt->parser.string_initial = TRUE;
ENTER_STATE(APC);
string_start = bytes + pos + 1;
string_len = 0;
break;
default:
do_control(vt, c);
break;
@ -340,8 +383,12 @@ string_state:
}
}
if(string_start)
string_fragment(vt, string_start, bytes + pos - string_start, FALSE);
if(string_start) {
size_t string_len = bytes + pos - string_start;
if(vt->parser.in_esc)
string_len -= 1;
string_fragment(vt, string_start, string_len, FALSE);
}
return len;
}

View File

@ -79,6 +79,10 @@ static VTermState *vterm_state_new(VTerm *vt)
state->callbacks = NULL;
state->cbdata = NULL;
state->selection.callbacks = NULL;
state->selection.user = NULL;
state->selection.buffer = NULL;
vterm_state_newpen(state);
state->bold_is_highbright = 0;
@ -1615,6 +1619,174 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
return 1;
}
static char base64_one(uint8_t b)
{
if(b < 26)
return 'A' + b;
else if(b < 52)
return 'a' + b - 26;
else if(b < 62)
return '0' + b - 52;
else if(b == 62)
return '+';
else if(b == 63)
return '/';
return 0;
}
static uint8_t unbase64one(char c)
{
if(c >= 'A' && c <= 'Z')
return c - 'A';
else if(c >= 'a' && c <= 'z')
return c - 'a' + 26;
else if(c >= '0' && c <= '9')
return c - '0' + 52;
else if(c == '+')
return 62;
else if(c == '/')
return 63;
return 0xFF;
}
static void osc_selection(VTermState *state, VTermStringFragment frag)
{
if(frag.initial) {
state->tmp.selection.mask = 0;
state->tmp.selection.state = SELECTION_INITIAL;
}
while(!state->tmp.selection.state && frag.len) {
/* Parse selection parameter */
switch(frag.str[0]) {
case 'c':
state->tmp.selection.mask |= VTERM_SELECTION_CLIPBOARD;
break;
case 'p':
state->tmp.selection.mask |= VTERM_SELECTION_PRIMARY;
break;
case 'q':
state->tmp.selection.mask |= VTERM_SELECTION_SECONDARY;
break;
case 's':
state->tmp.selection.mask |= VTERM_SELECTION_SELECT;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
state->tmp.selection.mask |= (VTERM_SELECTION_CUT0 << (frag.str[0] - '0'));
break;
case ';':
state->tmp.selection.state = SELECTION_SELECTED;
if(!state->tmp.selection.mask)
state->tmp.selection.mask = VTERM_SELECTION_SELECT|VTERM_SELECTION_CUT0;
break;
}
frag.str++;
frag.len--;
}
if(!frag.len)
return;
if(state->tmp.selection.state == SELECTION_SELECTED) {
if(frag.str[0] == '?') {
state->tmp.selection.state = SELECTION_QUERY;
}
else {
state->tmp.selection.state = SELECTION_SET_INITIAL;
state->tmp.selection.recvpartial = 0;
}
}
if(state->tmp.selection.state == SELECTION_QUERY) {
if(state->selection.callbacks->query)
(*state->selection.callbacks->query)(state->tmp.selection.mask, state->selection.user);
return;
}
if(state->selection.callbacks->set) {
size_t bufcur = 0;
char *buffer = state->selection.buffer;
uint32_t x = 0; /* Current decoding value */
int n = 0; /* Number of sextets consumed */
if(state->tmp.selection.recvpartial) {
n = state->tmp.selection.recvpartial >> 24;
x = state->tmp.selection.recvpartial & 0x03FFFF; /* could be up to 18 bits of state in here */
state->tmp.selection.recvpartial = 0;
}
while((state->selection.buflen - bufcur) >= 3 && frag.len) {
if(frag.str[0] == '=') {
if(n == 2) {
buffer[0] = (x >> 4) & 0xFF;
buffer += 1, bufcur += 1;
}
if(n == 3) {
buffer[0] = (x >> 10) & 0xFF;
buffer[1] = (x >> 2) & 0xFF;
buffer += 2, bufcur += 2;
}
while(frag.len && frag.str[0] == '=')
frag.str++, frag.len--;
n = 0;
}
else {
uint8_t b = unbase64one(frag.str[0]);
if(b == 0xFF) {
DEBUG_LOG1("base64decode bad input %02X\n", (uint8_t)frag.str[0]);
}
else {
x = (x << 6) | b;
n++;
}
frag.str++, frag.len--;
if(n == 4) {
buffer[0] = (x >> 16) & 0xFF;
buffer[1] = (x >> 8) & 0xFF;
buffer[2] = (x >> 0) & 0xFF;
buffer += 3, bufcur += 3;
x = 0;
n = 0;
}
}
if(!frag.len || (state->selection.buflen - bufcur) < 3) {
if(bufcur) {
(*state->selection.callbacks->set)(state->tmp.selection.mask, (VTermStringFragment){
.str = state->selection.buffer,
.len = bufcur,
.initial = state->tmp.selection.state == SELECTION_SET_INITIAL,
.final = frag.final,
}, state->selection.user);
state->tmp.selection.state = SELECTION_SET;
}
buffer = state->selection.buffer;
bufcur = 0;
}
}
if(n)
state->tmp.selection.recvpartial = (n << 24) | x;
}
}
static int on_osc(int command, VTermStringFragment frag, void *user)
{
VTermState *state = user;
@ -1656,6 +1828,12 @@ static int on_osc(int command, VTermStringFragment frag, void *user)
settermprop_string(state, VTERM_PROP_CURSORCOLOR, frag);
return 1;
case 52:
if(state->selection.callbacks)
osc_selection(state, frag);
return 1;
default:
if(state->fallbacks && state->fallbacks->osc)
if((*state->fallbacks->osc)(command, frag, state->fbdata))
@ -1718,12 +1896,14 @@ static void request_status_string(VTermState *state, VTermStringFragment frag)
case 'r':
// Query DECSTBM
vterm_push_output_sprintf_dcs(vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state));
vterm_push_output_sprintf_str(vt, C1_DCS, TRUE,
"1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state));
return;
case 's':
// Query DECSLRM
vterm_push_output_sprintf_dcs(vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state));
vterm_push_output_sprintf_str(vt, C1_DCS, TRUE,
"1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state));
return;
case ' '|('q'<<8): {
@ -1736,17 +1916,19 @@ static void request_status_string(VTermState *state, VTermStringFragment frag)
}
if(state->mode.cursor_blink)
reply--;
vterm_push_output_sprintf_dcs(vt, "1$r%d q", reply);
vterm_push_output_sprintf_str(vt, C1_DCS, TRUE,
"1$r%d q", reply);
return;
}
case '\"'|('q'<<8):
// Query DECSCA
vterm_push_output_sprintf_dcs(vt, "1$r%d\"q", state->protected_cell ? 1 : 2);
vterm_push_output_sprintf_str(vt, C1_DCS, TRUE,
"1$r%d\"q", state->protected_cell ? 1 : 2);
return;
}
vterm_push_output_sprintf_dcs(state->vt, "0$r%s", tmp);
vterm_push_output_sprintf_str(state->vt, C1_DCS, TRUE, "0$r%s", tmp);
}
static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
@ -1765,6 +1947,42 @@ static int on_dcs(const char *command, size_t commandlen, VTermStringFragment fr
return 0;
}
static int on_apc(VTermStringFragment frag, void *user)
{
VTermState *state = user;
if(state->fallbacks && state->fallbacks->apc)
if((*state->fallbacks->apc)(frag, state->fbdata))
return 1;
/* No DEBUG_LOG because all APCs are unhandled */
return 0;
}
static int on_pm(VTermStringFragment frag, void *user)
{
VTermState *state = user;
if(state->fallbacks && state->fallbacks->pm)
if((*state->fallbacks->pm)(frag, state->fbdata))
return 1;
/* No DEBUG_LOG because all PMs are unhandled */
return 0;
}
static int on_sos(VTermStringFragment frag, void *user)
{
VTermState *state = user;
if(state->fallbacks && state->fallbacks->sos)
if((*state->fallbacks->sos)(frag, state->fbdata))
return 1;
/* No DEBUG_LOG because all SOSs are unhandled */
return 0;
}
static int on_resize(int rows, int cols, void *user)
{
VTermState *state = user;
@ -1866,6 +2084,9 @@ static const VTermParserCallbacks parser_callbacks = {
on_csi, // csi
on_osc, // osc
on_dcs, // dcs
on_apc, // apc
on_pm, // pm
on_sos, // sos
on_resize // resize
};
@ -1909,6 +2130,8 @@ void vterm_state_reset(VTermState *state, int hard)
state->mode.bracketpaste = 0;
state->mode.report_focus = 0;
state->mouse_flags = 0;
state->vt->mode.ctrl8bit = 0;
{
@ -2087,3 +2310,96 @@ const VTermLineInfo *vterm_state_get_lineinfo(const VTermState *state, int row)
{
return state->lineinfo + row;
}
void vterm_state_set_selection_callbacks(VTermState *state, const VTermSelectionCallbacks *callbacks, void *user,
char *buffer, size_t buflen)
{
if(buflen && !buffer)
buffer = vterm_allocator_malloc(state->vt, buflen);
state->selection.callbacks = callbacks;
state->selection.user = user;
state->selection.buffer = buffer;
state->selection.buflen = buflen;
}
void vterm_state_send_selection(VTermState *state, VTermSelectionMask mask, VTermStringFragment frag)
{
VTerm *vt = state->vt;
if(frag.initial) {
/* TODO: support sending more than one mask bit */
static char selection_chars[] = "cpqs";
int idx;
for(idx = 0; idx < 4; idx++)
if(mask & (1 << idx))
break;
vterm_push_output_sprintf_str(vt, C1_OSC, FALSE, "52;%c;", selection_chars[idx]);
state->tmp.selection.sendpartial = 0;
}
if(frag.len) {
size_t bufcur = 0;
char *buffer = state->selection.buffer;
uint32_t x = 0;
int n = 0;
if(state->tmp.selection.sendpartial) {
n = state->tmp.selection.sendpartial >> 24;
x = state->tmp.selection.sendpartial & 0xFFFFFF;
state->tmp.selection.sendpartial = 0;
}
while((state->selection.buflen - bufcur) >= 4 && frag.len) {
x = (x << 8) | frag.str[0];
n++;
frag.str++, frag.len--;
if(n == 3) {
buffer[0] = base64_one((x >> 18) & 0x3F);
buffer[1] = base64_one((x >> 12) & 0x3F);
buffer[2] = base64_one((x >> 6) & 0x3F);
buffer[3] = base64_one((x >> 0) & 0x3F);
buffer += 4, bufcur += 4;
x = 0;
n = 0;
}
if(!frag.len || (state->selection.buflen - bufcur) < 4) {
if(bufcur)
vterm_push_output_bytes(vt, state->selection.buffer, bufcur);
buffer = state->selection.buffer;
bufcur = 0;
}
}
if(n)
state->tmp.selection.sendpartial = (n << 24) | x;
}
if(frag.final) {
if(state->tmp.selection.sendpartial) {
int n = state->tmp.selection.sendpartial >> 24;
uint32_t x = state->tmp.selection.sendpartial & 0xFFFFFF;
char *buffer = state->selection.buffer;
/* n is either 1 or 2 now */
x <<= (n == 1) ? 16 : 8;
buffer[0] = base64_one((x >> 18) & 0x3F);
buffer[1] = base64_one((x >> 12) & 0x3F);
buffer[2] = (n == 1) ? '=' : base64_one((x >> 6) & 0x3F);
buffer[3] = '=';
vterm_push_output_sprintf_str(vt, 0, TRUE, "%.*s", 4, buffer);
}
else
vterm_push_output_sprintf_str(vt, 0, TRUE, "");
}
}

View File

@ -200,27 +200,35 @@ INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, cons
va_end(args);
}
INTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...)
INTERNAL void vterm_push_output_sprintf_str(VTerm *vt, unsigned char ctrl, int term, const char *fmt, ...)
{
size_t cur;
va_list args;
cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len,
vt->mode.ctrl8bit ? "\x90" : ESC_S "P"); // DCS
if(ctrl) {
if(ctrl >= 0x80 && !vt->mode.ctrl8bit)
cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len,
ESC_S "%c", ctrl - 0x40);
else
cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len,
"%c", ctrl);
if(cur >= vt->tmpbuffer_len)
return;
vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
if(cur >= vt->tmpbuffer_len)
return;
vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
}
va_start(args, fmt);
vterm_push_output_vsprintf(vt, fmt, args);
va_end(args);
cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len,
vt->mode.ctrl8bit ? "\x9C" : ESC_S "\\"); // ST
if(cur >= vt->tmpbuffer_len)
return;
vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
if(term) {
cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len,
vt->mode.ctrl8bit ? "\x9C" : ESC_S "\\"); // ST
if(cur >= vt->tmpbuffer_len)
return;
vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
}
}
size_t vterm_output_get_buffer_size(const VTerm *vt)

View File

@ -154,7 +154,26 @@ struct VTermState
/* Temporary state for DECRQSS parsing */
union {
char decrqss[4];
struct {
uint16_t mask;
enum {
SELECTION_INITIAL,
SELECTION_SELECTED,
SELECTION_QUERY,
SELECTION_SET_INITIAL,
SELECTION_SET,
} state : 8;
uint32_t recvpartial;
uint32_t sendpartial;
} selection;
} tmp;
struct {
const VTermSelectionCallbacks *callbacks;
void *user;
char *buffer;
size_t buflen;
} selection;
};
struct VTerm
@ -181,6 +200,9 @@ struct VTerm
OSC_COMMAND,
OSC,
DCS,
APC,
PM,
SOS,
} state;
unsigned int in_esc : 1;
@ -248,7 +270,7 @@ void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len);
void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args);
void vterm_push_output_sprintf(VTerm *vt, const char *format, ...);
void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...);
void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...);
void vterm_push_output_sprintf_str(VTerm *vt, unsigned char ctrl, int term, const char *fmt, ...);
void vterm_state_free(VTermState *state);

View File

@ -17,15 +17,15 @@ PUSH "\x1f"
PUSH "\x83"
control 0x83
PUSH "\x9f"
control 0x9f
PUSH "\x99"
control 0x99
!C1 7bit
PUSH "\e\x43"
control 0x83
PUSH "\e\x5f"
control 0x9f
PUSH "\e\x59"
control 0x99
!High bytes
PUSH "\xa0\xcc\xfe"
@ -184,6 +184,12 @@ PUSH "\ePHello\e\\"
PUSH "\x{90}Hello\x9c"
dcs ["Hello"]
!Split write of 7bit ST
PUSH "\ePABC\e"
dcs ["ABC"
PUSH "\\"
dcs ]
!Escape cancels DCS, starts Escape
PUSH "\ePSomething\e9"
escape "9"
@ -198,6 +204,48 @@ PUSH "\ePBy\ne\x07"
control 10
dcs "e"]
!APC BEL
PUSH "\e_Hello\x07"
apc ["Hello"]
!APC ST (7bit)
PUSH "\e_Hello\e\\"
apc ["Hello"]
!APC ST (8bit)
PUSH "\x{9f}Hello\x9c"
apc ["Hello"]
!PM BEL
PUSH "\e^Hello\x07"
pm ["Hello"]
!PM ST (7bit)
PUSH "\e^Hello\e\\"
pm ["Hello"]
!PM ST (8bit)
PUSH "\x{9e}Hello\x9c"
pm ["Hello"]
!SOS BEL
PUSH "\eXHello\x07"
sos ["Hello"]
!SOS ST (7bit)
PUSH "\eXHello\e\\"
sos ["Hello"]
!SOS ST (8bit)
PUSH "\x{98}Hello\x9c"
sos ["Hello"]
!SOS can contain any C0 or C1 code
PUSH "\eXABC\x01DEF\e\\"
sos ["ABC\x01DEF"]
PUSH "\eXABC\x99DEF\e\\"
sos ["ABC\x{99}DEF"]
!NUL ignored
PUSH "\x{00}"

View File

@ -170,3 +170,12 @@ PUSH "\e[?1006\$p"
output "\e[?1006;2\$y"
PUSH "\e[?1015\$p"
output "\e[?1015;1\$y"
!Mouse disabled reports nothing
RESET
settermprop 1 true
settermprop 2 true
settermprop 7 1
MOUSEMOVE 0,0 0
MOUSEBTN d 1 0
MOUSEBTN u 1 0

View File

@ -17,3 +17,15 @@ PUSH "\e]27;Something\e\\"
!Unrecognised DCS
PUSH "\ePz123\e\\"
dcs ["z123"]
!Unrecognised APC
PUSH "\e_z123\e\\"
apc ["z123"]
!Unrecognised PM
PUSH "\e^z123\e\\"
pm ["z123"]
!Unrecognised SOS
PUSH "\eXz123\e\\"
sos ["z123"]

View File

@ -0,0 +1,55 @@
INIT
UTF8 1
WANTSTATE
!Set clipboard; final chunk len 4
PUSH "\e]52;c;SGVsbG8s\e\\"
selection-set mask=0001 ["Hello,"]
!Set clipboard; final chunk len 3
PUSH "\e]52;c;SGVsbG8sIHc=\e\\"
selection-set mask=0001 ["Hello, w"]
!Set clipboard; final chunk len 2
PUSH "\e]52;c;SGVsbG8sIHdvcmxkCg==\e\\"
selection-set mask=0001 ["Hello, world\n"]
!Set clipboard; split between chunks
PUSH "\e]52;c;SGVs"
selection-set mask=0001 ["Hel"
PUSH "bG8s\e\\"
selection-set mask=0001 "lo,"]
!Set clipboard; split within chunk
PUSH "\e]52;c;SGVsbG"
selection-set mask=0001 ["Hel"
PUSH "8s\e\\"
selection-set mask=0001 "lo,"]
!Query clipboard
PUSH "\e]52;c;?\e\\"
selection-query mask=0001
!Send clipboard; final chunk len 4
SELECTION 1 ["Hello,"]
output "\e]52;c;SGVsbG8s\e\\"
!Send clipboard; final chunk len 3
SELECTION 1 ["Hello, w"]
output "\e]52;c;SGVsbG8sIHc=\e\\"
!Send clipboard; final chunk len 2
SELECTION 1 ["Hello, world\n"]
output "\e]52;c;SGVsbG8sIHdvcmxkCg==\e\\"
!Send clipboard; split between chunks
SELECTION 1 ["Hel"
output "\e]52;c;SGVs"
SELECTION 1 "lo,"]
output "bG8s\e\\"
!Send clipboard; split within chunk
SELECTION 1 ["Hello"
output "\e]52;c;SGVs"
SELECTION 1 ","]
output "bG8s\e\\"

View File

@ -13,7 +13,8 @@ static size_t inplace_hex2bytes(char *s)
while(*inpos) {
unsigned int ch;
sscanf(inpos, "%2x", &ch);
if(sscanf(inpos, "%2x", &ch) < 1)
break;
*outpos = ch;
outpos += 1; inpos += 2;
}
@ -98,7 +99,7 @@ static void term_output(const char *s, size_t len, void *user UNUSED)
static void printhex(const char *s, size_t len)
{
while(len--)
printf("%02x", (s++)[0]);
printf("%02x", (uint8_t)(s++)[0]);
}
static int parser_text(const char bytes[], size_t len, void *user UNUSED)
@ -216,6 +217,57 @@ static int parser_dcs(const char *command, size_t commandlen, VTermStringFragmen
return 1;
}
static int parser_apc(VTermStringFragment frag, void *user UNUSED)
{
printf("apc ");
if(frag.initial)
printf("[");
printhex(frag.str, frag.len);
if(frag.final)
printf("]");
printf("\n");
return 1;
}
static int parser_pm(VTermStringFragment frag, void *user UNUSED)
{
printf("pm ");
if(frag.initial)
printf("[");
printhex(frag.str, frag.len);
if(frag.final)
printf("]");
printf("\n");
return 1;
}
static int parser_sos(VTermStringFragment frag, void *user UNUSED)
{
printf("sos ");
if(frag.initial)
printf("[");
printhex(frag.str, frag.len);
if(frag.final)
printf("]");
printf("\n");
return 1;
}
static VTermParserCallbacks parser_cbs = {
parser_text, // text
parser_control, // control
@ -223,6 +275,9 @@ static VTermParserCallbacks parser_cbs = {
parser_csi, // csi
parser_osc, // osc
parser_dcs, // dcs
parser_apc, // apc
parser_pm, // pm
parser_sos, // sos
NULL // resize
};
@ -230,7 +285,10 @@ static VTermStateFallbacks fallbacks = {
parser_control, // control
parser_csi, // csi
parser_osc, // osc
parser_dcs // dcs
parser_dcs, // dcs
parser_apc, // dcs
parser_pm, // pm
parser_sos // sos
};
/* These callbacks are shared by State and Screen */
@ -414,6 +472,31 @@ VTermStateCallbacks state_cbs = {
state_setlineinfo, // setlineinfo
};
static int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user UNUSED)
{
printf("selection-set mask=%04X ", mask);
if(frag.initial)
printf("[");
printhex(frag.str, frag.len);
if(frag.final)
printf("]");
printf("\n");
return 1;
}
static int selection_query(VTermSelectionMask mask, void *user UNUSED)
{
printf("selection-query mask=%04X\n", mask);
return 1;
}
VTermSelectionCallbacks selection_cbs = {
.set = selection_set,
.query = selection_query,
};
static int want_screen_damage = 0;
static int want_screen_damage_cells = 0;
static int screen_damage(VTermRect rect, void *user UNUSED)
@ -555,6 +638,7 @@ int main(int argc UNUSED, char **argv UNUSED)
if(!state) {
state = vterm_obtain_state(vt);
vterm_state_set_callbacks(state, &state_cbs, NULL);
vterm_state_set_selection_callbacks(state, &selection_cbs, NULL, NULL, 1024);
vterm_state_set_bold_highbright(state, 1);
vterm_state_reset(state, 1);
}
@ -768,6 +852,32 @@ int main(int argc UNUSED, char **argv UNUSED)
vterm_mouse_button(vt, button, (press == 'd' || press == 'D'), mod);
}
else if(strstartswith(line, "SELECTION ")) {
char *linep = line + 10;
unsigned int mask;
int len;
VTermStringFragment frag = { 0 };
sscanf(linep, "%x%n", &mask, &len);
linep += len;
while(linep[0] == ' ')
linep++;
if(linep[0] == '[') {
frag.initial = TRUE;
linep++;
while(linep[0] == ' ')
linep++;
}
frag.len = inplace_hex2bytes(linep);
frag.str = linep;
linep += frag.len * 2;
while(linep[0] == ' ')
linep++;
if(linep[0] == ']') {
frag.final = TRUE;
}
vterm_state_send_selection(state, mask, frag);
}
else if(strstartswith(line, "DAMAGEMERGE ")) {
char *linep = line + 12;
while(linep[0] == ' ')

View File

@ -85,6 +85,11 @@ sub do_line
my $string = eval($2);
$line = "$1 " . unpack "H*", $string;
}
elsif( $line =~ m/^(SELECTION \d+) +(\[?)(.*?)(\]?)$/ ) {
# we're evil
my $string = eval($3);
$line = "$1 $2 " . unpack( "H*", $string ) . " $4";
}
do_onetest if defined $command;
@ -113,15 +118,18 @@ sub do_line
$line = "$cmd $initial" . join( "", map sprintf("%02x", $_), unpack "C*", length $data ? eval($data) : "" ) . "$final";
}
elsif( $line =~ m/^(escape|dcs) (\[?)(.*?)(\]?)$/ ) {
$line = "$1 $2" . join( "", map sprintf("%02x", $_), unpack "C*", eval($3) ) . "$4";
elsif( $line =~ m/^(escape|dcs|apc|pm|sos) (\[?)(.*?)(\]?)$/ ) {
$line = "$1 $2" . join( "", map sprintf("%02x", $_), unpack "C*", length $3 ? eval($3) : "" ) . "$4";
}
elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) {
$line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2";
}
elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc) / ) {
elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc|selection-query) / ) {
# no conversion
}
elsif( $line =~ m/^(selection-set) (.*?) (\[?)(.*?)(\]?)$/ ) {
$line = "$1 $2 $3" . join( "", map sprintf("%02x", $_), unpack "C*", eval($4) ) . "$5";
}
else {
warn "Unrecognised test expectation '$line'\n";
}

View File

@ -1,6 +1,5 @@
prefix=@PREFIX@
libdir=@LIBDIR@
includedir=${prefix}/include
includedir=@INCDIR@
Name: vterm
Description: Abstract VT220/Xterm/ECMA-48 emulation library

View File

@ -4526,7 +4526,10 @@ static VTermStateFallbacks state_fallbacks = {
NULL, // control
parse_csi, // csi
parse_osc, // osc
NULL // dcs
NULL, // dcs
NULL, // apc
NULL, // pm
NULL // sos
};
/*

View File

@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3666,
/**/
3665,
/**/