bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Is a "silent" ncurses initialization possible?


From: Robin Haberkorn
Subject: Is a "silent" ncurses initialization possible?
Date: Thu, 4 Jun 2015 15:24:00 +0200

Hello,

for my editor SciTECO which features a ncurses port, I need to
initialize ncurses (via initscr() or newterm())
without writing to stdout and if possible even without configuring the
tty-device.
Currently, I'm testing with ncurses 5.9.
Basically I want ncurses to operate in shell mode from the beginning
without any terminal interaction before
possibly activating prog mode on the actual terminal.
This is necessary in order to operate in batch mode like a regular
command-line program, supporting stdout
redirection, even though SciTECO already accesses ncurses data structures.
In case you wonder, I use the Scintilla editor component via Scinterm
which uses curses windows opaquely.

It may be possible to patch Scinterm to defer any curses operation
before curses has been properly
initialized - this would be nice since it could work with other curses
ports as well like PDCurses.
But for the time being I'd like to get it to work in the current form.

I came up with the following ncurses/Unix-specific "hack" (in
simplified pseudo-code):

// Batch-mode initialization:
screen_tty = fopen("/dev/null", "r+");
setvbuf(screen_tty, NULL, _IOFBF, 0);

screen = newterm(NULL, screen_tty, screen_tty);
// Not sure if this is necessary or even helpful:
def_shell_mode();

cbreak(); // we need ^C to be delivered as a signal by default
noecho();
// ...misc. initialization...
endwin();
// now we're in ncurses shell-mode, too

// ...do SciTECO batch-mode stuff...
// This includes Scinterm calls that access ncurses

// Initialize SciTECO's interactive mode:
freopen("/dev/tty", "r+", screen_tty);
// Not sure if this is necessary or even helpful:
def_shell_mode();

wrefresh(...);
// Now, we're in ncurses prog mode.
// This __mostly__ sets up the terminal correctly.

--------------------

To my surprise this "hack" works quite well. However, now raw() and
cbreak() no longer
work as expected.
It appears I'm in raw() mode permanently. ^C no longer delivers the
SIGINT signal.

My input loop looks as follows:

for (;;) {
        raw();
        // allow ^C to be returned as a key press
        key = wgetch(cmdline_window);
        cbreak();
        // A keypress can result in expensive operations that we would
        // like to interrupt with ^C.
        // ...process key...
}

Here's the complete curses port of SciTECO:
https://github.com/rhaberkorn/sciteco/blob/master/src/interface-curses.cpp

But with the hack described above, SIGINT is never delivered on ^C.
I suspect that the doupdate() in wrefresh() only incompletely sets up
the terminal.

Is there a proper way to do what I want without modifying Scintilla+Scinterm?

I would also like to avoid relying on SIGINT delivery for
interruptions by splitting
the input loop in two threads: One with a wgetch() or getch() loop and
the other one for executing
SciTECO macros and doing all the remaining Curses work.
Is it safe - with a non-threading ncurses build - to do that?
This is esp. important for PDCurses builds (as there is currently no
way to interrupt
a long-running process) but I'm aware that PDCurses may behave
completely different
with regard to threading.

Thanks in advance,
Robin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]