From f740ad3774c1adc7844451dd561c7de143766635 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Mon, 11 Aug 2025 08:56:46 +0000 Subject: 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. --- INSTALL | 7 ++++++- README | 2 +- TODO | 6 ++++++ contrib/scintilla | 2 +- src/interface-curses/interface.c | 45 ++++++++++++++++++++++++++++++++++------ src/memory.c | 4 ++++ 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/INSTALL b/INSTALL index 2d3eb36..84fa787 100644 --- a/INSTALL +++ b/INSTALL @@ -67,9 +67,14 @@ The same on Fedora: And on FreeBSD: - $ sudo pkg install git gmake pkgconfig autoconf automake libtool \ + $ sudo pkg install git gmake pkgconf autoconf automake libtool \ glib gtk3 groff doxygen +On NetBSD: + + $ sudo pkgin install git gmake pkg-config autoconf automake libtool-base \ + glib2 gtk3+ doxygen + Building from Source Tar Ball or Repository =========================================== diff --git a/README b/README index 86c3a79..bc90898 100644 --- a/README +++ b/README @@ -29,7 +29,7 @@ The Curses frontend is verified to work with [ncurses](https://www.gnu.org/softw All X/Open-compatible libraries should be supported. SVr4 curses without enhanced definitions is **not** supported. -Linux, FreeBSD, [Mac OS X](https://github.com/rhaberkorn/sciteco/wiki/Mac-OS-Support), +Linux, FreeBSD, NetBSD, [Mac OS X](https://github.com/rhaberkorn/sciteco/wiki/Mac-OS-Support), Windows (MinGW 32/64) ~~and [Haiku](https://www.haiku-os.org/) (gcc4)~~ are tested and supported. SciTECO compiles with both GCC and Clang. SciTECO should compile just fine on other UNIX-compatible platforms. diff --git a/TODO b/TODO index 9ac25ca..9bd1d32 100644 --- a/TODO +++ b/TODO @@ -52,6 +52,12 @@ Known Bugs: https://github.com/Bill-Gray/PDCursesMod/issues/335 We're waiting for an MSYS package upgrade. It could also be worked around by using wget_wch() instead of wgetch(). + * PDCurses/Win32: Crashes sometimes without any error message. + * NetBSD Curses: scrolling apparently uses hardware idl capabilities + resulting in graphical glitches on slow terminals. + idlok(FALSE) is apparently ignored. + * NetBSD: Very slow, even the redrawing. + This does not happen with ncurses on NetBSD. * dlmalloc's malloc_trim() does not seem to free any resident memory after hitting the OOM limit, eg. after <%a>. Apparently an effect of HAVE_MORECORE (sbrk()) - some allocation is diff --git a/contrib/scintilla b/contrib/scintilla index 26df8de..7ccb740 160000 --- a/contrib/scintilla +++ b/contrib/scintilla @@ -1 +1 @@ -Subproject commit 26df8def5e3ad506c514a42262d98584011d5446 +Subproject commit 7ccb74055fd37f22de83e4fbe42c146b6dd5656d 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) { -- cgit v1.2.3