如何使用 ncurses 获得明亮的白色背景颜色?

How do I get a bright white background color with ncurses?

如何在 ncurses 中获得带有黑色文本的明亮白色背景,类似于 nano 中的 title-bar?尽管遵循 the advice in another question(这与在黑色背景上获得明亮的白色文本有关,与我想要实现的相反),但我似乎能实现的是一个丑陋的 beige-colored 背景。

图片:

GNU nano的标题栏,我想要的

我从下面的程序中得到了什么。 (使用 gcc -lncursesw -I/usr/include minimal_example.c 构建)

#include <locale.h>
#include <ncurses.h>

int main() {
    setlocale(LC_ALL, "");
    // Initialize curses library
    initscr();
    // Enable colors
    start_color();
    // Attempt recommendation in  and other places on the web
    use_default_colors();
    // Make the COLOR_PAIR 0xFF refer to a white foreground, black background window.
    // Using -1 will not work in my case, because I want the opposite of the default (black text  on white bg), not the default (white text on black bg).
    init_pair(0xFF, COLOR_BLACK, COLOR_WHITE);
    refresh();
    // Get our term height and width.
    int x;
    int y;
    // & not required because this is a macro
    getmaxyx(stdscr, y, x); 
    // Create a new window.
    // TODO: Resize the window when the term resizes.
    WINDOW *window = newwin(y,x,0,0);
    // Try some other attributes recommended online, no dice. Putting this after the call to wbkgd() just makes the text look strange, does not change the background.
    wattron(window,A_BOLD|A_STANDOUT);
    // Set window color.
    wbkgd(window, COLOR_PAIR(0xff));
    // Draw a nice box around the window.
    box(window, 0, 0); 
    // Write some text.
    mvwprintw(window, 1, 1, "背景:不白");
    wrefresh(window);

    // Wait for keypress to exit.
    getch(); 
    // De-initialize ncurses.
    endwin();
    return 0;
}

我认为我的终端配置可能有问题 (termite),但我能够在 xfce4-terminalxterm 中重现该问题,两者都使用默认设置配置。解决这个问题的唯一方法是将我的 color7color15 设置为与 foreground 相同的颜色,显然我不想这样做,因为那是 non-standard 并且我想要分发使用此代码的大型应用程序。

(xfce4-terminal 有 bug)

终端仿真器中的颜色有点乱。您的问题是根据您的终端,灰色背景确实是“白色”!在 Wikipedia. See how gray-looking the "White" row is across all the different terminal emulators? What you really want is "bright white", which is beyond the 8 initial colors. The problem is that, according to curses 上查看此 table:

Some terminals support more than the eight (8) “ANSI” colors. There are no standard names for those additional colors.

所以你只需要按数字使用它们,并希望每个人的终端都符合维基百科上的 tables(我想大多数人都这样做)。

init_pair(0xFF, COLOR_BLACK, COLORS > 15 ? 15 : COLOR_WHITE);

这就是您所需要的,因此您可以摆脱所有其他 use_default_colorsA_BOLD 东西。


旧答案:

curs_color 手册说

Note that setting an implicit background color via a color pair affects only character cells that a character write operation explicitly touches.

...

The A_BLINK attribute should in theory cause the background to go bright.

的确,如果你只是改变

wbkgd(window, COLOR_PAIR(0xff) | A_BLINK);

您会得到明亮的白色背景,但仅限于绘制文本的区域(包括 window 边框)。我不确定如何在整个 window 背景上获得相同的效果,但希望这可以帮助您入门。

此更改(假设 TERM=xterm-256color)执行要求的操作:

> diff -u foo.c foo2.c
--- foo.c       2017-10-06 15:59:56.000000000 -0400
+++ foo2.c      2017-10-06 16:10:11.893529758 -0400
@@ -7,10 +7,9 @@
     initscr();
     // Enable colors
     start_color();
-    // Attempt recommendation in  and other places on the web
-    use_default_colors();
-    // Make the COLOR_PAIR 0xFF refer to a white foreground, black background window.
-    // Using -1 will not work in my case, because I want the opposite of the default (black text  on white bg), not the default (white text on black bg).
+    // redefine colors, using the initc capability in TERM=xterm-256color
+    init_color(COLOR_BLACK, 0, 0, 0);
+    init_color(COLOR_WHITE, 999, 999, 999);
     init_pair(0xFF, COLOR_BLACK, COLOR_WHITE);
     refresh();
     // Get our term height and width.

但是 nano 不会那样做。您可能会发现阅读它的 source-code 很有帮助,您会发现它通过使用终端的默认颜色解决了问题。

如果至少有 16 种颜色并且 can_change_color() returns 为真,我的建议是定义明亮的颜色(9 到 15)。否则退回到非亮色:

#include <stdlib.h>
#include <locale.h>
#include <ncurses.h>

#define PAIR_BW       1
#define BRIGHT_WHITE  15

int main(void) {
    int rows, cols;

    setlocale(LC_ALL, "");
    initscr();

    start_color();
    use_default_colors();
    if (can_change_color() && COLORS >= 16)
        init_color(BRIGHT_WHITE, 1000,1000,1000);

    if (COLORS >= 16) {
        init_pair(PAIR_BW, COLOR_BLACK, BRIGHT_WHITE);
    } else {
        init_pair(PAIR_BW, COLOR_BLACK, COLOR_WHITE);
    }

    refresh();
    getmaxyx(stdscr, rows, cols); 
    WINDOW *window = newwin(rows,cols,0,0);
    wbkgd(window, COLOR_PAIR(PAIR_BW));
    box(window, 0, 0); 
    mvwprintw(window, 1, 1, "背景:不白");
    wrefresh(window);

    getch(); 
    endwin();
    return EXIT_SUCCESS;
}

这已经过测试,可以在 Gnome Terminal 3.18.3 和 XTerm 322 中使用,如果使用 ncursesw,它应该可以在所有支持颜色的终端中使用(尽管在一些奇怪的终端上,您可能仍然会得到非亮白色背景).