diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-08-11 08:56:46 +0000 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-08-21 23:48:24 +0000 |
commit | f740ad3774c1adc7844451dd561c7de143766635 (patch) | |
tree | 9a3fca50cbcac9b78a4be880cadac30ff6b5d174 /src | |
parent | e3af05db9554662a5a8f3b15ebbe1dc5697643f8 (diff) | |
download | sciteco-f740ad3774c1adc7844451dd561c7de143766635.tar.gz |
fully support NetBSD with its native libcurses
* It requires a forced refresh on startup (even though that should be the
default). Otherwise, it wouldn't print the info line correctly.
* Redirect stdin and pass it to newterm() to fix key queuing.
Probably necessary for supporting ncurses on NetBSD as well.
* Avoid doupdate() if screen is too small: fixes crashes for very
small windows.
* Updated Scintilla: There were some implicit typing assumptions,
that are broken by this platform.
Diffstat (limited to 'src')
-rw-r--r-- | src/interface-curses/interface.c | 45 | ||||
-rw-r--r-- | src/memory.c | 4 |
2 files changed, 43 insertions, 6 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index b135c5c..62a6e64 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -355,7 +355,7 @@ static struct { gshort r, g, b; } orig_color_table[16]; - int stdout_orig, stderr_orig; + int stdin_orig, stdout_orig, stderr_orig; SCREEN *screen; FILE *screen_tty; @@ -412,7 +412,7 @@ teco_interface_init(void) for (guint i = 0; i < G_N_ELEMENTS(teco_interface.orig_color_table); i++) teco_interface.orig_color_table[i].r = -1; - teco_interface.stdout_orig = teco_interface.stderr_orig = -1; + teco_interface.stdin_orig = teco_interface.stdout_orig = teco_interface.stderr_orig = -1; teco_curses_info_popup_init(&teco_interface.popup); @@ -581,17 +581,33 @@ teco_interface_init_color(guint color, guint32 rgb) static void teco_interface_init_screen(void) { - teco_interface.screen_tty = g_fopen("/dev/tty", "r+"); + teco_interface.screen_tty = g_fopen("/dev/tty", "a"); /* should never fail */ g_assert(teco_interface.screen_tty != NULL); - teco_interface.screen = newterm(NULL, teco_interface.screen_tty, teco_interface.screen_tty); + /* + * At least on NetBSD we loose keypresses when passing in a + * handle for /dev/tty. + * We therefore redirect stdin in interactive mode. + * This works always if stdin was already redirected or not (isatty(0)) + * since we are guaranteed not to read from stdin outside of curses. + * When returning to batch mode, we can restore the original stdin. + */ + teco_interface.stdin_orig = dup(0); + g_assert(teco_interface.stdin_orig >= 0); + G_GNUC_UNUSED FILE *stdin_new = g_freopen("/dev/tty", "r", stdin); + g_assert(stdin_new != NULL); + + teco_interface.screen = newterm(NULL, teco_interface.screen_tty, stdin); if (G_UNLIKELY(!teco_interface.screen)) { g_fprintf(stderr, "Error initializing interactive mode. " "$TERM may be incorrect.\n"); exit(EXIT_FAILURE); } + /* initscr() does that in ncurses */ + def_prog_mode(); + /* * If stdout or stderr would go to the terminal, * redirect it. Otherwise, they are already redirected @@ -824,10 +840,14 @@ teco_interface_restore_batch(void) teco_interface_restore_colors(); /* - * Restore stdout and stderr, so output goes to + * Restore stdin, stdout and stderr, so output goes to * the terminal again in case we "muted" them. */ #ifdef CURSES_TTY + if (teco_interface.stdin_orig >= 0) { + G_GNUC_UNUSED int fd = dup2(teco_interface.stdin_orig, 0); + g_assert(fd == 0); + } if (teco_interface.stdout_orig >= 0) { G_GNUC_UNUSED int fd = dup2(teco_interface.stdout_orig, 1); g_assert(fd == 1); @@ -1862,6 +1882,14 @@ teco_interface_refresh(gboolean force) /* batch mode */ return; +#ifdef NETBSD_CURSES + /* works around crashes in doupdate() */ + gint y, x; + getmaxyx(stdscr, y, x); + if (G_UNLIKELY(x <= 1 || y <= 1)) + return; +#endif + if (G_UNLIKELY(force)) clearok(curscr, TRUE); @@ -2213,7 +2241,12 @@ teco_interface_event_loop(GError **error) teco_interface_cmdline_update(&empty_cmdline); teco_interface_msg_clear(); teco_interface_ssm(SCI_SCROLLCARET, 0, 0); - teco_interface_refresh(FALSE); + /* + * NetBSD's Curses needs the hard refresh as it would + * otherwise draw the info window in the wrong row. + * Shouldn't cause any slowdown on ncurses. + */ + teco_interface_refresh(TRUE); #ifdef EMCURSES PDC_emscripten_set_handler(teco_interface_event_loop_iter, TRUE); diff --git a/src/memory.c b/src/memory.c index 90a5dd8..264c235 100644 --- a/src/memory.c +++ b/src/memory.c @@ -304,6 +304,10 @@ static guint teco_memory_usage = 0; */ #ifdef REPLACE_MALLOC +#ifndef G_ATOMIC_LOCK_FREE +#warning "malloc() replacement will be very slow!" +#endif + void * __attribute__((used)) malloc(size_t size) { |