# HG changeset patch # User Bram Moolenaar # Date 1589745604 -7200 # Node ID c15dd3da4f47f456d944a1883cb56d0de75eddfc # Parent 8d6f1cfef895be95cc64e5b65fb70948d5c74b89 patch 8.2.0784: libvterm code lags behind the upstream version Commit: https://github.com/vim/vim/commit/94d729cbe8f0f788d9d7539f733cff395e73b228 Author: Bram Moolenaar Date: Sun May 17 21:50:16 2020 +0200 patch 8.2.0784: libvterm code lags behind the upstream version Problem: Libvterm code lags behind the upstream version. Solution: Include revisions 730 - 733. diff --git a/src/libvterm/include/vterm.h b/src/libvterm/include/vterm.h --- a/src/libvterm/include/vterm.h +++ b/src/libvterm/include/vterm.h @@ -194,10 +194,17 @@ void vterm_set_utf8(VTerm *vt, int is_ut size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len); +/* Setting output callback will override the buffer logic */ +typedef void VTermOutputCallback(const char *s, size_t len, void *user); +void vterm_output_set_callback(VTerm *vt, VTermOutputCallback *func, void *user); + +/* These buffer functions only work if output callback is NOT set + * These are deprecated and will be removed in a later version */ size_t vterm_output_get_buffer_size(const VTerm *vt); size_t vterm_output_get_buffer_current(const VTerm *vt); size_t vterm_output_get_buffer_remaining(const VTerm *vt); +/* This too */ size_t vterm_output_read(VTerm *vt, char *buffer, size_t len); int vterm_is_modify_other_keys(VTerm *vt); diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c --- a/src/libvterm/src/state.c +++ b/src/libvterm/src/state.c @@ -1617,6 +1617,8 @@ static int on_osc(const char *command, s static void request_status_string(VTermState *state, const char *command, size_t cmdlen) { + VTerm *vt = state->vt; + if(cmdlen == 1) switch(command[0]) { case 'm': // Query SGR @@ -1624,22 +1626,37 @@ static void request_status_string(VTermS long args[20]; int argc = vterm_state_getpen(state, args, sizeof(args)/sizeof(args[0])); int argi; - vterm_push_output_sprintf_ctrl(state->vt, C1_DCS, "1$r"); - for(argi = 0; argi < argc; argi++) - vterm_push_output_sprintf(state->vt, - argi == argc - 1 ? "%d" : - CSI_ARG_HAS_MORE(args[argi]) ? "%d:" : - "%d;", - CSI_ARG(args[argi])); - vterm_push_output_sprintf(state->vt, "m"); - vterm_push_output_sprintf_ctrl(state->vt, C1_ST, ""); + size_t cur = 0; + + cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, + vt->mode.ctrl8bit ? "\x90" "1$r" : ESC_S "P" "1$r"); // DCS 1$r ... + if(cur >= vt->tmpbuffer_len) + return; + + for(argi = 0; argi < argc; argi++) { + cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, + argi == argc - 1 ? "%ld" : + CSI_ARG_HAS_MORE(args[argi]) ? "%ld:" : + "%ld;", + CSI_ARG(args[argi])); + + if(cur >= vt->tmpbuffer_len) + return; + } + + cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur, + vt->mode.ctrl8bit ? "m" "\x9C" : "m" ESC_S "\\"); // ... m ST + if(cur >= vt->tmpbuffer_len) + return; + + vterm_push_output_bytes(vt, vt->tmpbuffer, cur); } return; case 'r': // Query DECSTBM - vterm_push_output_sprintf_dcs(state->vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state)); + vterm_push_output_sprintf_dcs(vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state)); return; case 's': // Query DECSLRM - vterm_push_output_sprintf_dcs(state->vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state)); + vterm_push_output_sprintf_dcs(vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state)); return; } @@ -1653,11 +1670,11 @@ static void request_status_string(VTermS } if(state->mode.cursor_blink) reply--; - vterm_push_output_sprintf_dcs(state->vt, "1$r%d q", reply); + vterm_push_output_sprintf_dcs(vt, "1$r%d q", reply); return; } else if(strneq(command, "\"q", 2)) { - vterm_push_output_sprintf_dcs(state->vt, "1$r%d\"q", state->protected_cell ? 1 : 2); + vterm_push_output_sprintf_dcs(vt, "1$r%d\"q", state->protected_cell ? 1 : 2); return; } } diff --git a/src/libvterm/src/vterm.c b/src/libvterm/src/vterm.c --- a/src/libvterm/src/vterm.c +++ b/src/libvterm/src/vterm.c @@ -64,6 +64,9 @@ VTerm *vterm_new_with_allocator(int rows return NULL; } + vt->outfunc = NULL; + vt->outdata = NULL; + vt->outbuffer_len = 200; vt->outbuffer_cur = 0; vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len); @@ -135,8 +138,19 @@ void vterm_set_utf8(VTerm *vt, int is_ut vt->mode.utf8 = is_utf8; } +void vterm_output_set_callback(VTerm *vt, VTermOutputCallback *func, void *user) +{ + vt->outfunc = func; + vt->outdata = user; +} + INTERNAL void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len) { + if(vt->outfunc) { + (vt->outfunc)(bytes, len, vt->outdata); + return; + } + if(len > vt->outbuffer_len - vt->outbuffer_cur) { DEBUG_LOG("vterm_push_output_bytes(): buffer overflow; dropping output\n"); return; @@ -146,24 +160,6 @@ INTERNAL void vterm_push_output_bytes(VT vt->outbuffer_cur += len; } -#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) \ - || defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE) -# undef VSNPRINTF -# define VSNPRINTF vsnprintf -# undef SNPRINTF -# define SNPRINTF snprintf -#else -# ifdef VSNPRINTF -// Use a provided vsnprintf() function. -int VSNPRINTF(char *str, size_t str_m, const char *fmt, va_list ap); -# endif -# ifdef SNPRINTF -// Use a provided snprintf() function. -int SNPRINTF(char *str, size_t str_m, const char *fmt, ...); -# endif -#endif - - INTERNAL void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args) { size_t len; @@ -214,12 +210,9 @@ INTERNAL void vterm_push_output_sprintf_ size_t cur; va_list args; - if(!vt->mode.ctrl8bit) - cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, - ESC_S "%c", C1_DCS - 0x40); - else - cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, - "%c", C1_DCS); + cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, + vt->mode.ctrl8bit ? "\x90" : ESC_S "P"); // DCS + if(cur >= vt->tmpbuffer_len) return; vterm_push_output_bytes(vt, vt->tmpbuffer, cur); @@ -228,12 +221,8 @@ INTERNAL void vterm_push_output_sprintf_ vterm_push_output_vsprintf(vt, fmt, args); va_end(args); - if(!vt->mode.ctrl8bit) - cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, - ESC_S "%c", C1_ST - 0x40); - else - cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, - "%c", C1_ST); + 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); diff --git a/src/libvterm/src/vterm_internal.h b/src/libvterm/src/vterm_internal.h --- a/src/libvterm/src/vterm_internal.h +++ b/src/libvterm/src/vterm_internal.h @@ -207,6 +207,9 @@ struct VTerm // len == malloc()ed size; cur == number of valid bytes + VTermOutputCallback *outfunc; + void *outdata; + char *outbuffer; size_t outbuffer_len; size_t outbuffer_cur; @@ -268,4 +271,24 @@ int vterm_unicode_is_combining(uint32_t int vterm_unicode_is_ambiguous(uint32_t codepoint); int vterm_get_special_pty_type(void); +#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) \ + || defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE) +# undef VSNPRINTF +# define VSNPRINTF vsnprintf +# undef SNPRINTF +#else +# ifdef VSNPRINTF +// Use a provided vsnprintf() function. +int VSNPRINTF(char *str, size_t str_m, const char *fmt, va_list ap); +# endif +# ifdef SNPRINTF +// Use a provided snprintf() function. +int SNPRINTF(char *str, size_t str_m, const char *fmt, ...); +# endif #endif +#ifndef SNPRINTF +# define SNPRINTF snprintf +#endif + + +#endif diff --git a/src/libvterm/t/harness.c b/src/libvterm/t/harness.c --- a/src/libvterm/t/harness.c +++ b/src/libvterm/t/harness.c @@ -483,6 +483,9 @@ int main(int argc UNUSED, char **argv UN if(streq(line, "INIT")) { if(!vt) vt = vterm_new(25, 80); + + // Somehow this makes tests fail + // vterm_output_set_callback(vt, term_output, NULL); } else if(streq(line, "WANTPARSER")) { diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 784, +/**/ 783, /**/ 782,