diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-12-22 20:41:31 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-12-22 20:52:28 +0100 |
commit | 3706112c6bff358f1467afced9ff29d8a3246eb2 (patch) | |
tree | 1c4b9f751534caf251f39f5cfe6318ed148f1c06 /src/interface-curses/interface.c | |
parent | 3614e5877818a3f3e187b43f8247cabaf842c39f (diff) | |
download | sciteco-3706112c6bff358f1467afced9ff29d8a3246eb2.tar.gz |
Curses: added teco_interface_is_interrupted() fallback and standardized how to detect interactive/batch mode
* Adds support for CTRL+C interruptions on Curses variants like PDCurses/GUI and XCurses.
This also affects the current Win32 nightly builds which should now support CTRL+C interruptions.
* The fallback is of course less efficient than the existing platform optimizations (existing for
UNIX and Win32 console builds) and slows down parsing in interactive mode.
* Use teco_interface.cmdline_window consistently to detect interactive mode.
This may theoretically speed up SciTECO code execution slightly on shutdown.
Diffstat (limited to 'src/interface-curses/interface.c')
-rw-r--r-- | src/interface-curses/interface.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 4351379..55e0626 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -591,7 +591,7 @@ teco_interface_init_screen(void) Xinitscr(1, (char **)argv); } -#else +#else /* !CURSES_TTY && !XCURSES */ static void teco_interface_init_screen(void) @@ -672,6 +672,7 @@ teco_interface_init_interactive(GError **error) cbreak(); noecho(); + nodelay(teco_interface.cmdline_window, TRUE); /* Scintilla draws its own cursor */ curs_set(0); @@ -756,12 +757,11 @@ teco_interface_restore_batch(void) #endif /* - * See teco_interface_vmsg(): It looks at msg_window to determine - * whether we're in batch mode. + * cmdline_window determines whether we're in batch mode. */ - if (teco_interface.msg_window) { - delwin(teco_interface.msg_window); - teco_interface.msg_window = NULL; + if (teco_interface.cmdline_window) { + delwin(teco_interface.cmdline_window); + teco_interface.cmdline_window = NULL; } } @@ -789,7 +789,7 @@ teco_interface_resize_all_windows(void) void teco_interface_vmsg(teco_msg_t type, const gchar *fmt, va_list ap) { - if (!teco_interface.msg_window) { /* batch mode */ + if (!teco_interface.cmdline_window) { /* batch mode */ teco_interface_stdio_vmsg(type, fmt, ap); return; } @@ -835,7 +835,7 @@ teco_interface_vmsg(teco_msg_t type, const gchar *fmt, va_list ap) void teco_interface_msg_clear(void) { - if (!teco_interface.msg_window) /* batch mode */ + if (!teco_interface.cmdline_window) /* batch mode */ return; short fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); @@ -1442,12 +1442,47 @@ teco_interface_popup_clear(void) teco_curses_info_popup_init(&teco_interface.popup); } +#if defined(CURSES_TTY) || defined(PDCURSES_WINCON) || defined(NCURSES_WIN32) + +/* + * For UNIX Curses we can rely on signal handlers to detect interruptions via CTRL+C. + * On Win32 console builds, there is teco_console_ctrl_handler(). + */ +gboolean +teco_interface_is_interrupted(void) +{ + return teco_sigint_occurred != FALSE; +} + +#else /* !CURSES_TTY && !PDCURSES_WINCON && !NCURSES_WIN32 */ + +/* + * This function is called repeatedly, so we can poll the keyboard input queue, + * filtering out CTRL+C. + * This is naturally very inefficient. + * It's currently necessary as a fallback e.g. for PDCURSES_GUI or XCurses. + */ gboolean teco_interface_is_interrupted(void) { + if (teco_interface.cmdline_window) { /* interactive mode */ + int key; + + /* + * NOTE: getch() is configured to be nonblocking. + */ + while ((key = wgetch(teco_interface.cmdline_window)) != ERR) + if (G_UNLIKELY(key == TECO_CTL_KEY('C'))) + teco_sigint_occurred |= TRUE; + else + ungetch(key); + } + return teco_sigint_occurred != FALSE; } +#endif + /** * One iteration of the event loop. * @@ -1493,6 +1528,7 @@ teco_interface_event_loop_iter(void) /* no special <CTRL/C> handling */ raw(); + nodelay(teco_interface.cmdline_window, FALSE); #ifdef PDCURSES_WINCON SetConsoleMode(console_hnd, console_mode & ~ENABLE_PROCESSED_INPUT); #endif @@ -1505,15 +1541,17 @@ teco_interface_event_loop_iter(void) teco_memory_start_limiting(); /* allow asynchronous interruptions on <CTRL/C> */ teco_sigint_occurred = FALSE; + nodelay(teco_interface.cmdline_window, TRUE); noraw(); /* FIXME: necessary because of NCURSES_WIN32 bug */ cbreak(); #ifdef PDCURSES_WINCON SetConsoleMode(console_hnd, console_mode | ENABLE_PROCESSED_INPUT); #endif - if (key == ERR) - return; switch (key) { + case ERR: + /* shouldn't really happen */ + return; #ifdef KEY_RESIZE case KEY_RESIZE: #ifdef __PDCURSES__ |