From 866c123c1cf161bf9046a0ab8209902ac994e273 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Wed, 23 Mar 2022 17:46:49 -0400 Subject: Support software flow control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new `-p` / `--preserve` flag to textadept-curses. When specified, don’t grab the XON and XOFF control characters from the TTY driver. This allows textadept-curses to run effectively on serial terminals that use XON/XOFF flow control. The `-p` flag was chosen to align with nano, where it has the same behavior. --- src/termkey.patch | 58 +++++++++++++++++++++++++++++++++++++------------------ src/textadept.c | 16 ++++++++++++++- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/termkey.patch b/src/termkey.patch index 40276ec1..07849e53 100644 --- a/src/termkey.patch +++ b/src/termkey.patch @@ -162,7 +162,7 @@ diff -r 49c8684413c0 termkey-internal.h #endif diff -r 49c8684413c0 termkey.c --- a/termkey.c Tue Dec 23 10:36:54 2014 -0500 -+++ b/termkey.c Tue Dec 23 13:31:50 2014 -0500 ++++ b/termkey.c Wed Mar 23 17:11:16 2022 -0400 @@ -3,8 +3,14 @@ #include @@ -176,9 +176,9 @@ diff -r 49c8684413c0 termkey.c +#define strcasecmp strcmp +#endif #include + #include - #include -@@ -27,8 +31,12 @@ +@@ -30,8 +36,12 @@ } static struct TermKeyDriver *drivers[] = { @@ -191,7 +191,7 @@ diff -r 49c8684413c0 termkey.c NULL, }; -@@ -263,7 +271,7 @@ +@@ -272,7 +282,7 @@ /* Default all the object fields but don't allocate anything */ @@ -200,7 +200,7 @@ diff -r 49c8684413c0 termkey.c tk->flags = 0; tk->canonflags = 0; -@@ -373,7 +381,7 @@ +@@ -384,7 +394,7 @@ return 0; } @@ -209,7 +209,7 @@ diff -r 49c8684413c0 termkey.c { TermKey *tk = termkey_alloc(); if(!tk) -@@ -414,7 +422,7 @@ +@@ -429,7 +439,7 @@ if(!tk) return NULL; @@ -218,7 +218,7 @@ diff -r 49c8684413c0 termkey.c termkey_set_flags(tk, flags); -@@ -457,6 +465,7 @@ +@@ -483,13 +493,16 @@ if(tk->is_started) return 1; @@ -226,7 +226,17 @@ diff -r 49c8684413c0 termkey.c if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) { struct termios termios; if(tcgetattr(tk->fd, &termios) == 0) { -@@ -472,9 +481,9 @@ + tk->restore_termios = termios; + tk->restore_termios_valid = 1; + +- termios.c_iflag &= ~(IXON|INLCR|ICRNL); ++ termios.c_iflag &= ~(INLCR|ICRNL); ++ if (!(tk->flags & TERMKEY_FLAG_FLOWCONTROL)) ++ termios.c_iflag &= ~IXON; + termios.c_lflag &= ~(ICANON|ECHO + #ifdef IEXTEN + | IEXTEN +@@ -502,9 +515,9 @@ /* want no signal keys at all, so just disable ISIG */ termios.c_lflag &= ~ISIG; else { @@ -238,7 +248,7 @@ diff -r 49c8684413c0 termkey.c /* Some OSes have Ctrl-Y==VDSUSP */ #ifdef VDSUSP termios.c_cc[VDSUSP] = _POSIX_VDISABLE; -@@ -487,6 +496,7 @@ +@@ -517,6 +530,7 @@ tcsetattr(tk->fd, TCSANOW, &termios); } } @@ -246,7 +256,7 @@ diff -r 49c8684413c0 termkey.c struct TermKeyDriverNode *p; for(p = tk->drivers; p; p = p->next) -@@ -512,8 +522,10 @@ +@@ -542,8 +556,10 @@ if(p->driver->stop_driver) (*p->driver->stop_driver)(tk, p->info); @@ -257,7 +267,7 @@ diff -r 49c8684413c0 termkey.c tk->is_started = 0; -@@ -525,11 +537,18 @@ +@@ -555,11 +571,18 @@ return tk->is_started; } @@ -277,7 +287,7 @@ diff -r 49c8684413c0 termkey.c int termkey_get_flags(TermKey *tk) { return tk->flags; -@@ -1012,7 +1031,7 @@ +@@ -1048,7 +1071,7 @@ TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key) { @@ -286,7 +296,7 @@ diff -r 49c8684413c0 termkey.c errno = EBADF; return TERMKEY_RES_ERROR; } -@@ -1026,6 +1045,7 @@ +@@ -1062,6 +1085,7 @@ case TERMKEY_RES_ERROR: return ret; @@ -294,7 +304,7 @@ diff -r 49c8684413c0 termkey.c case TERMKEY_RES_NONE: ret = termkey_advisereadable(tk); if(ret == TERMKEY_RES_ERROR) -@@ -1064,6 +1084,7 @@ +@@ -1100,6 +1124,7 @@ return termkey_getkey_force(tk, key); } break; @@ -302,7 +312,7 @@ diff -r 49c8684413c0 termkey.c } } -@@ -1072,6 +1093,7 @@ +@@ -1108,6 +1133,7 @@ TermKeyResult termkey_advisereadable(TermKey *tk) { @@ -310,7 +320,7 @@ diff -r 49c8684413c0 termkey.c ssize_t len; if(tk->fd == -1) { -@@ -1109,6 +1131,9 @@ +@@ -1145,6 +1171,9 @@ tk->buffcount += len; return TERMKEY_RES_AGAIN; } @@ -322,7 +332,7 @@ diff -r 49c8684413c0 termkey.c size_t termkey_push_bytes(TermKey *tk, const char *bytes, size_t len) diff -r 49c8684413c0 termkey.h --- a/termkey.h Tue Dec 23 10:36:54 2014 -0500 -+++ b/termkey.h Tue Dec 23 13:31:50 2014 -0500 ++++ b/termkey.h Wed Mar 23 17:09:43 2022 -0400 @@ -14,6 +14,14 @@ #define TERMKEY_CHECK_VERSION \ termkey_check_version(TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR) @@ -338,7 +348,17 @@ diff -r 49c8684413c0 termkey.h typedef enum { TERMKEY_SYM_UNKNOWN = -1, TERMKEY_SYM_NONE = 0, -@@ -161,7 +169,7 @@ +@@ -154,7 +162,8 @@ + TERMKEY_FLAG_SPACESYMBOL = 1 << 5, /* Sets TERMKEY_CANON_SPACESYMBOL */ + TERMKEY_FLAG_CTRLC = 1 << 6, /* Allow Ctrl-C to be read as normal, disabling SIGINT */ + TERMKEY_FLAG_EINTR = 1 << 7, /* Return ERROR on signal (EINTR) rather than retry */ +- TERMKEY_FLAG_NOSTART = 1 << 8 /* Do not call termkey_start() in constructor */ ++ TERMKEY_FLAG_NOSTART = 1 << 8, /* Do not call termkey_start() in constructor */ ++ TERMKEY_FLAG_FLOWCONTROL = 1 << 9 /* Do not capture Ctrl-S and Ctrl-Q from the TTY driver */ + }; + + enum { +@@ -164,7 +173,7 @@ void termkey_check_version(int major, int minor); @@ -347,7 +367,7 @@ diff -r 49c8684413c0 termkey.h TermKey *termkey_new_abstract(const char *term, int flags); void termkey_free(TermKey *tk); void termkey_destroy(TermKey *tk); -@@ -170,7 +178,10 @@ +@@ -177,7 +186,10 @@ int termkey_stop(TermKey *tk); int termkey_is_started(TermKey *tk); diff --git a/src/textadept.c b/src/textadept.c index a5e8ddbc..b34adc2a 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -2473,7 +2473,21 @@ int main(int argc, char **argv) { #if GTK gtk_init(&argc, &argv); #elif CURSES - ta_tk = termkey_new(0, 0); + int termkey_flags = 0; + for (int i = 0; i < argc; i++) { + if (strcmp("-p", argv[i]) == 0 || strcmp("--preserve", argv[i]) == 0) { + termkey_flags |= TERMKEY_FLAG_FLOWCONTROL; + + // Remove -p/--preserve from the argument list so it doesn't get interpreted as a session + // name. + memmove(argv + i, argv + i + 1, (argc - 1 - i) * sizeof(*argv)); + argc--; + + break; + } + } + + ta_tk = termkey_new(0, termkey_flags); setlocale(LC_CTYPE, ""); // for displaying UTF-8 characters properly initscr(); // raw()/cbreak() and noecho() are taken care of in libtermkey #if NCURSES_REENTRANT -- cgit v1.2.3