1

I wrote a "complex" C program using the ncurses library. It "correctly" runs in a lxterminal or gnome-terminal session; but doesn't run in a "native Linux terminal" session without X started (obtained both restarting the PC without X or using Ctrl-Alt-F3 terminal).

The problem is that in the "native Linux session" the program doesn't display any windows, it displays only one of the text printed in the third generated window.

  • I saw that in gnome-terminal the TERM environment variable is set as xterm-256color. In contrast, the native Linux terminal has TERM set as linux.

  • Then I set TERM in the native Linux terminal using:

    export TERM=xterm-256color
    

    When I set TERM as xterm-256color the program runs better and displays an usable interface, but all the chars to construct boxes are substituted by other chars, the vertical line char is substituted by the xchar.

  • But I thought xterm is for X terminal section then I tried ansi:

    export TERM=ansi
    

    With this last setting, the program displays almost nothing as in the case of the native setting.

  • Using vt100:

    export TERM=vt100
    

    The programs runs better, but is displayed in B/W.

The same behaviour happens also with the examples released with the ncurses library.

Have you some explanation?

How do I set the terminal capability in a way I may correctly start my ncurses program?

It's possible that I've not set something relevant to terminal (or relevan to ncurses) in the code?

Example

#include <ncurses.h>

static void initGeneralScreen(void);

int main()
{
    WINDOW * deskW, * msgW, * otherW;

    initGeneralScreen();

    deskW = newwin(21,80,0,0);
    wbkgd(deskW, COLOR_PAIR(3));
    box(deskW, 0, 0 ); // sets default borders for the window
    wrefresh( deskW ); // update the terminal screen

    msgW = newwin(3, 80, 21, 0);
    wbkgd(msgW, COLOR_PAIR(1));
    box(msgW, 0, 0 ); // sets default borders for the window
    wrefresh(msgW ); // update the terminal screen

    otherW = newwin(1,78,0,1);
    wbkgd(otherW, COLOR_PAIR(1));
    wrefresh(otherW ); // update the terminal screen

    mvwprintw(msgW,1,1,"Test ... <Hit a key to exit>");
    wrefresh(msgW ); // update the terminal screen

    mvwprintw(otherW,0,0,"Test1");
    wrefresh(otherW ); // update the terminal screen

    wgetch(deskW);

    delwin( otherW );
    delwin( msgW );
    delwin( deskW );
    endwin();

    return 0;
}

void initGeneralScreen(void)
{
    initscr();  // initialize Ncurses
    noecho();   // disable echoing of characters on the screen
    raw();      //
    keypad(stdscr,TRUE);

    start_color();

    init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE);
    init_pair(2,COLOR_YELLOW, COLOR_BLUE);
    init_pair(3,COLOR_WHITE | 8, COLOR_BLACK | 8);
}

Notes:

  • Kernel
    Linux 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
    
  • libncurses.so.5.9
Sir Jo Black
  • 240
  • 1
  • 9
  • 2
    I'd like who down-votes the question give some explanations, too. It's not clear and not useful a down-votes without explanations. – Sir Jo Black May 20 '20 at 08:23
  • 1
    Although that is true, please note that [cross-posting](https://stackoverflow.com/questions/61896568/ncurses-sw-runs-in-lxterminal-but-doesnt-run-in-a-native-linux-terminal) is strongly discouraged, and that you should decide for either of the sites for posting your question, deleting the duplicate(s) on the other one(s). – AdminBee May 20 '20 at 10:03
  • 1
    Can you create some minimal example, which will show the problem? May be a little program that draws a window and works in a pseudo-terminal and doesn't work in the virtual terminal (`tty`). In other words, you should shrink your complex program until you find out the cause of the problem. Then add the relevant code into the question. – MiniMax May 20 '20 at 13:09
  • @MiniMax ... Example done! – Sir Jo Black May 20 '20 at 13:38

1 Answers1

2

I changed

init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE);
init_pair(2,COLOR_YELLOW, COLOR_BLUE);
init_pair(3,COLOR_WHITE | 8, COLOR_BLACK | 8);

to

init_pair(1,COLOR_YELLOW, COLOR_BLUE);
init_pair(2,COLOR_YELLOW, COLOR_BLUE);
init_pair(3,COLOR_WHITE, COLOR_BLACK);

and program began to work as expected.

The problem has appeared because you use colors for background (by wbkgd function), which Linux virtual terminal is not supporting. It supports only 8 colors for background and 8 for foreground - About ncurses Colors .

See:

printf("COLOR_YELLOW\t\t%d\n", COLOR_YELLOW);
printf("COLOR_BLUE\t\t%d\n", COLOR_BLUE);
printf("COLOR_BLACK\t\t%d\n", COLOR_BLACK);
printf("COLOR_WHITE\t\t%d\n", COLOR_WHITE);
puts("");
printf("COLOR_YELLOW | 8\t%d\n", COLOR_YELLOW | 8);
printf("COLOR_BLACK | 8\t\t%d\n", COLOR_BLACK | 8);
printf("COLOR_WHITE | 8\t\t%d\n", COLOR_WHITE | 8);

Output

COLOR_YELLOW        3
COLOR_BLUE          4
COLOR_BLACK         0
COLOR_WHITE         7

COLOR_YELLOW | 8    11    // not allowed for background
COLOR_BLACK | 8     8     // not allowed for background
COLOR_WHITE | 8     15    // not allowed for background

EDIT

1.

According to init_pair signature:

int init_pair(short pair, short f, short b);

the second argument is for foreground, the third is for background, so the only third argument in the color pair 3 should be changed from COLOR_BLACK | 8 to simple COLOR_BLACK in your example.

Thus, this is legitimate in the Linux console:

init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE);
init_pair(2,COLOR_YELLOW, COLOR_BLUE);
init_pair(3,COLOR_WHITE | 8, COLOR_BLACK);

This is answering why you don't see much color changes when set TERM=xterm-256color in the console. Because only COLOR_BLACK | 8 isn't supported, others are fine. And COLOR_BLACK | 8 isn't working as expected - the body of table is in plain black, unlike of gnome-terminal, where it is colored by grey. So, the colors are not completely correct, as you wrote in the comment.

2. Why in gnome-terminal the behaviour is different?

Because gnome-terminal and Linux console are two terminal emulators, which use different sets of escape sequences. Think about them as two different hardware terminals from different vendors.

  • xterm is the standard terminal emulator for the X Window System.

  • gnome-terminal is the xterm compliant terminal emulator.

  • Linux console is VT102 emulator resided in the kernel. Not a strict one, for example VT102 didn't have colors.

It is why ncurses library is needed - to write terminal independent applications. The set of each terminal emulator capabilities are stored in the terminfo database. Linux console has own entry, as well as gnome-terminal. ncurses uses information from this database to manage terminal emulators.

You can compare entries by this command:

infocmp -c linux xterm-256color

So, when you change the TERM variable from linux to xterm-256color in the Linux console, you say ncurses to use foreign set of escape sequences for communication with terminal instead of authentic (right) one. Some codes can be understandable despite of this, because they have similarities, but not all.

Related links:

MiniMax
  • 4,025
  • 1
  • 17
  • 32
  • 1
    Why in gnome-terminal the behaviour is different (it's graphic, I know)? but ... Why is the characters output wrong if I set TERM=xterm-256color, but the color are correct? How I may set the correct charset and terminal type to obtain my expected result? – Sir Jo Black May 20 '20 at 15:51
  • 1
    @SirJoBlack See edit. – MiniMax May 20 '20 at 18:57
  • I'm trying to manipulate term configuration ... I'd like to find a solution to use all color ... Using ansi code I've all color I want ... then I think that manipulating I may obtain the same behaviour. – Sir Jo Black May 21 '20 at 08:24