【问题标题】:NCurses: Why does init_color return OK but still not set the color?NCurses:为什么 init_color 返回 OK 但仍未设置颜色?
【发布时间】:2012-06-04 06:41:33
【问题描述】:

我正在尝试通过将值 COLOR_BLUE 设置为以下 rgb 值来将文本块的背景设置为红色:(1000, 0, 0)。如果我使用 Gnome 的“终端”应用程序,背景是正确的(红色),但如果我使用 KDE 的“Konsole”,背景是不正确的(蓝色)。为什么是这样?以下代码将在 Linux 上使用 compile 行编译:

g++ filename.cpp -lcurses

我通过以下方式将我的 TERM 类型设置为 xterm-256color:

export TERM=xterm-256color

代码如下:

#include <ncurses.h>
#include <cassert>
#include <csignal>

static bool stop = false;

void sigAbortHandler(int _sig)
{
    stop = true;
}

int main(int _argc, char **_argv)
{
    signal(SIGABRT, &sigAbortHandler);

    WINDOW *window = initscr();

    if (!has_colors())
    {
        delwin(window);
        endwin();
        perror("You must enable colors in your console");
    }

    if (!can_change_color())
    {
        delwin(window);
        endwin();
        perror("Error: unable to change colors, "
               "trying setting your TERM type to enable colors");
    }

    assert(start_color() == OK);
    keypad(stdscr, TRUE);
    cbreak();
    noecho();
    curs_set(0);
    nodelay(window, true);

    int background = COLOR_BLUE;
    assert(init_color(background, 1000, 0, 0) == OK);
    int foreground = 2;
    assert(init_color(foreground, 0, 0, 0) == OK);
    int pair = 1;
    assert(init_pair(pair, foreground, background) == OK);
    assert(wattron(window, COLOR_PAIR(pair)) == OK);

    short r, g, b;
    color_content(background, &r, &g, &b);
    assert(mvwprintw(window, 10, 10, "color content: %d, %d, %d", r, g, b) == OK);
    assert(wrefresh(window) == OK);
    assert(wattroff(window, COLOR_PAIR(pair)) == OK);

    while (!stop)
    {
    }

    delwin(window);
    endwin();

    return 0;
}

【问题讨论】:

  • 你有没有想过这个问题?我有类似的问题,但在 OS X 中.. init_color 声称成功,但颜色没有改变。
  • @BenL。我在 macOS Catalina 下没有问题。而且我也从来没有遇到过 KDE Konsole 的问题(尽管只有 init_pair)。奇怪的。但是如果你只想设置背景红色和前景蓝色,你只需要init_pair

标签: ncurses xterm


【解决方案1】:

您的意思是将背景设置为 COLOR_BLUE 吗?尽管检查了can_change_color,但似乎初始化颜色对 Konsole 没有影响,并且背景在 init_pair 处保持 COLOR_BLUE。

int background = COLOR_BLUE;
assert(init_color(background, 1000, 0, 0) == OK);
...
assert(init_pair(pair, foreground, background) == OK);
assert(wattron(window, COLOR_PAIR(pair)) == OK);

【讨论】:

    【解决方案2】:

    来自man init_color的看似相关的摘录:

    The init_color routine changes the definition of a color.  ... The first
    argument must be a legal color value; **default colors are not allowed here**.
    (See the section Colors for the default color index.)
    ...
    Colors
    ...
    In <curses.h> the following macros are defined.  These are the default colors.
    ...
                 COLOR_BLUE
    

    所以这些行正在做一些根据文档不应该工作的事情,但在某些终端中可能并且确实可以工作:

    int background = COLOR_BLUE;
    assert(init_color(background, 1000, 0, 0) == OK);
    int foreground = 2;
    assert(init_color(foreground, 0, 0, 0) == OK);
    

    应该有 16 个预定义的颜色对(如果我们计算粗体颜色),因此使用对 1617 而不是 COLOR_BLUE2 可能会起作用。

    (没有Konsole 来检查这个,但这可能是原因,或者至少值得指出。)

    【讨论】:

      【解决方案3】:

      问题是 Konsole 没有实现您期望的功能。 ncurses 只知道您配置的终端描述中的内容。没有通用的方法来检查它是否正确。 init_colorRETURN-VALUE 部分说

      init_color
      如果终端不支持则返回错误 此功能,例如,如果终端描述中缺少 initialize_color 功能。

      大概你有类似TERM=xterm-256color的东西。 ncurses 终端数据库有一个正确的konsole-256color,它(使用infocmpxterm-256color 比较)在很多方面都不同:

      comparing xterm-256color to konsole-256color.
          comparing booleans.
          ccc: T:F.
          km: T:F.
          mc5i: T:F.
          comparing numbers.
          comparing strings.
          bel: '^G', NULL.
          cbt: '\E[Z', NULL.
          cnorm: '\E[?12l\E[?25h', '\E[?25h'.
          cvvis: '\E[?12;25h', NULL.
          dim: '\E[2m', NULL.
          el1: '\E[1K', NULL.
          enacs: NULL, '\E)0'.
          ich: '\E[%p1%d@', NULL.
          initc: '\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\', NULL.
          invis: '\E[8m', NULL.
          is2: '\E[!p\E[?3;4l\E[4l\E>', '\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8'.
          kDC: '\E[3;2~', NULL.
          kEND: '\E[1;2F', NULL.
          kHOM: '\E[1;2H', NULL.
          kIC: '\E[2;2~', NULL.
          kLFT: '\E[1;2D', NULL.
          kNXT: '\E[6;2~', NULL.
          kPRV: '\E[5;2~', NULL.
          kRIT: '\E[1;2C', NULL.
          kb2: '\EOE', NULL.
          kent: '\EOM', NULL.
          kf13: '\E[1;2P', '\EO2P'.
          kf14: '\E[1;2Q', '\EO2Q'.
          kf15: '\E[1;2R', '\EO2R'.
          kf16: '\E[1;2S', '\EO2S'.
          kf25: '\E[1;5P', '\EO5P'.
          kf26: '\E[1;5Q', '\EO5Q'.
          kf27: '\E[1;5R', '\EO5R'.
          kf28: '\E[1;5S', '\EO5S'.
          kf37: '\E[1;6P', '\EO6P'.
          kf38: '\E[1;6Q', '\EO6Q'.
          kf39: '\E[1;6R', '\EO6R'.
          kf40: '\E[1;6S', '\EO6S'.
          kf49: '\E[1;3P', '\EO3P'.
          kf50: '\E[1;3Q', '\EO3Q'.
          kf51: '\E[1;3R', '\EO3R'.
          kf52: '\E[1;3S', '\EO3S'.
          kf61: '\E[1;4P', '\EO4P'.
          kf62: '\E[1;4Q', '\EO4Q'.
          kf63: '\E[1;4R', '\EO4R'.
          kind: '\E[1;2B', NULL.
          kri: '\E[1;2A', NULL.
          mc0: '\E[i', NULL.
          mc4: '\E[4i', NULL.
          mc5: '\E[5i', NULL.
          rmacs: '\E(B', '^O'.
          rmcup: '\E[?1049l', '\E[2J\E[?47l\E8'.
          rmm: '\E[?1034l', NULL.
          rs1: '\Ec', NULL.
          rs2: '\E[!p\E[?3;4l\E[4l\E>', '\E7\E[r\E8\E[m\E[?7h\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h'.
          sgr: '%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m', '\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;'.
          sgr0: '\E(B\E[m', '\E[0m\017'.
          smacs: '\E(0', '^N'.
          smcup: '\E[?1049h', '\E7\E[?47h'.
          smm: '\E[?1034h', NULL.
      

      在您看到NULL 的地方,Konsole 根本没有实现该功能。特别是,它对initc(您所询问的功能)没有任何作用。

      进一步阅读:

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 2021-12-07
        • 2019-09-02
        • 2020-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多