Linux

NCURSES SW 在 lxterminal 中執行,但不在本機 Linux 終端中執行

  • May 20, 2020

ncurses我使用該庫編寫了一個“複雜”的 C 程序。它“正確地”在一個lxterminalgnome-terminal會話中執行;但不會在沒有啟動 X 的“本機 Linux 終端”會話中執行(在沒有 X的**情況下重新啟動 PC 或使用Ctrl-終端)。Alt``F3

問題是在“本機 Linux 會話”中,程序不顯示任何視窗,它只顯示第三個生成視窗中列印的文本之一。

  • 我看到在 gnome-terminalTERM環境變數設置為xterm-256color. 相比之下,本機 Linux 終端已TERM設置為linux.
  • 然後我TERM在本機 Linux 終端中使用:
export TERM=xterm-256color

當我設置TERMxterm-256color程序執行得更好並顯示一個可用的界面,但所有構造框的字元都被其他字元替換時,垂直線字元被字元替換x

  • 但我認為xterm是針對 X 終端部分,然後我嘗試了ansi
export TERM=ansi

使用最後一個設置,程序幾乎不顯示任何內容,就像在本機設置的情況下一樣。

  • 使用vt100
export TERM=vt100

程序執行得更好,但以黑白顯示。

與 ncurses 庫一起發布的範例也會發生相同的行為。

你有什麼解釋嗎?

如何以可以正確啟動 ncurses 程序的方式設置終端功能?

有可能我沒有在程式碼中設置與終端(或與 ncurses 相關)相關的內容嗎?

例子

#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);
}

筆記:

  • 核心
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

我變了

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

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

程序開始按預期工作。

出現問題是因為您使用Linux 虛擬終端不支持的背景顏色(按wbkgd功能) 。它僅支持 8 種背景顏色和 8 種前景顏色 -關於 ncurses 顏色

看:

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);

輸出

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

編輯

1.

根據init_pair 簽名

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

第二個參數用於前景,第三個用於背景,因此在您的範例中,顏色對中唯一的第三個參數3應從簡單更改COLOR_BLACK | 8為簡單COLOR_BLACK

因此,這在 Linux 控制台中是合法的:

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

TERM=xterm-256color這是回答為什麼在控制台中設置時看不到太多顏色變化的原因。因為只有COLOR_BLACK | 8不支持,其他都很好。並且COLOR_BLACK | 8沒有按預期工作 - 表格的主體是純黑色的,不像gnome-terminal,它是灰色的。因此,正如您在評論中所寫,顏色並不完全正確。

2. 為什麼在 gnome-terminal 中的行為不同?

因為gnome-terminalLinux 控制台是兩個終端仿真器,它們使用不同的轉義序列集。將它們視為來自不同供應商的兩個不同硬體終端。

  • xterm 是 X Window 系統的標準終端仿真器。
  • gnome-terminalxterm兼容的終端仿真器。
  • Linux 控制台是駐留在核心中的VT102仿真器。不是嚴格的,例如VT102沒有顏色。

這就是為什麼ncurses需要庫 - 編寫獨立於終端的應用程序。每個終端仿真器功能的集合都儲存在terminfo數據庫中。Linux 控制台有自己的入口,還有gnome-terminalncurses使用來自該數據庫的資訊來管理終端仿真器。

您可以通過此命令比較條目:

infocmp -c linux xterm-256color

因此,當您在 Linux 控制台中將TERM變數 from更改為linuxto時,您會說使用一組外部轉義序列與終端進行通信,而不是真實的(正確的)。儘管如此,有些程式碼還是可以理解的,因為它們有相似之處,但不是全部。xterm-256color``ncurses

相關連結:

引用自:https://unix.stackexchange.com/questions/587829