14

I'm learning to program in C and want to be able to type characters into the terminal while my code is running without pressing return. My program works, however when I call initscr(), the screen is cleared - even after calling filter(). The documentation for filter suggests it should disable clearing - however this is not the case for me.

#include <stdio.h>
#include <curses.h>
#include <term.h>

int main(void) {

    int ch;

    filter();
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    while((ch = getch()) != EOF);

    endwin();

    return 0;
}

Why does the above code still clearr the screen, and what could be done to fix it?

I'm using Debian Lenny (stable) and gnome-terminal if that helps.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Chris R
  • 187
  • 1
  • 1
  • 7
  • For PDCurses you can set the environment variables PDC_PRESERVE_SCREEN or PDC_RESTORE_SCREEN to any value: from the file HISTORY: – Brandin Aug 03 '13 at 15:47
  • PDC_PRESERVE_SCREEN If this environment variable is set, PDCurses will not clear the screen to the default white on black on startup. This allows you to overlay a window over the top of the existing screen background. PDC_RESTORE_SCREEN If this environment variable is set, PDCurses will take a copy of the contents of the screen at the time that PDCurses is started; initscr(), and when endwin() is called, the screen will be restored. – Brandin Aug 03 '13 at 15:48

4 Answers4

3

You would see your screen cleared in a curses application for one of these reasons:

  • your program calls initscr (which clears the screen) or newterm without first calling filter, or
  • the terminal initialization clears the screen (or makes it appear to clear, by switching to the alternate screen).

In the latter case, you can suppress the alternate screen feature in ncurses by resetting the enter_ca_mode and exit_ca_mode pointers to NULL as done in dialog. Better yet, choose a terminal description which does what you want.

Further reading:

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
2

Extending the answer by mike.dld, this works for me on MacOS X 10.6.6 (GCC 4.5.2) with the system curses library - without clearing the screen. I added the ability to record the characters typed (logged to a file "x"), and the ability to type CONTROL-D and stop the program rather than forcing the user to interrupt.

#include <stdio.h>
#include <curses.h>
#include <term.h>

#define CONTROL(x)  ((x) & 0x1F)

int main(void)
{
    FILE *fp = fopen("x", "w");
    if (fp == 0)
        return(-1);
    SCREEN *s = newterm(NULL, stdin, stdout);
    if (s == 0)
        return(-1);
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    int ch;
    while ((ch = getch()) != EOF && ch != CONTROL('d'))
        fprintf(fp, "%d\n", ch);

    endwin();

    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

Basically, curses is designed to take over the screen (or window, in the case of a windowed terminal). You can't really mix curses with stdio, and you can't really use curses to just input or output something without messing with the rest of the screen. There are partial workarounds, but you're never really going to be able to make it work the way that it sounds like you want to. Sorry.

I'd suggest either rewriting your program to use curses throughout, or investigating alternatives like readline.

William McBrine
  • 2,166
  • 11
  • 7
0

Use newterm() instead of initscr(), you should be fine then. And don't forget about delscreen() if you follow this advice.

mike.dld
  • 2,929
  • 20
  • 21
  • Hi, thanks for response, I have tried what you said and the functionality is the same - the screen was cleared again. In place of `initscr()` I have `FILE *fild_id = fopen("/dev/tty", "r+"); SCREEN *termref = newterm(NULL, file_id, file_id);` and instead of `endwin()` I have `delscreen(termref)`. – Chris R Jan 23 '11 at 03:49
  • Strange but it doesn't clear my screen when I use it instead of `initscr()`. I call it as `newterm(NULL, stdin, stdout)` though. – mike.dld Jan 23 '11 at 04:00
  • 7
    The only reason it's not clearing your screen, Mike, is that you reversed the arguments to newterm(). It takes stdout, stdin, not stdin, stdout. I bet after your test program runs, your input is messed up? Doesn't echo, perhaps? If you use the correct argument order for newterm() it does indeed clear the screen. Your answer is just wrong. – nick black Jun 17 '12 at 10:34
  • 1
    Why not delete this answer? – Ted Lyngmo Jan 30 '20 at 22:45
  • 1
    I'm all for it but I cannot seem to delete the answer while it's accepted @TedLyngmo. Any assistance on it is welcome. – mike.dld Feb 10 '20 at 19:09
  • @mike.dld I see. I now remember that happening to me too. Well, that answers that question. :-) – Ted Lyngmo Feb 10 '20 at 19:10