ncurses中的颜色对未使用正确的颜色

5

我正在尝试使用ncursesw6.1(与PicoLisp链接)。据我所知,PicoLisp直接以这种方式传递值,因此我通过非C语言调用ncurses的事实不应该是一个因素[1]。然而,当我尝试使用颜色对(像这样定义)时:

(curses "init_pair" NIL 1 *COLOR-SCHEME-TEXT *COLOR-SCHEME-BACKGROUND-DARK)
(curses "init_pair" NIL 2 *COLOR-SCHEME-COMMENT *COLOR-SCHEME-BACKGROUND-DARK)
(curses "init_pair" NIL 3 *COLOR-SCHEME-FUNCTION *COLOR-SCHEME-BACKGROUND-DARK)
(curses "init_pair" NIL 4 *COLOR-SCHEME-VALUE *COLOR-SCHEME-BACKGROUND-DARK)
(curses "init_pair" NIL 5 *COLOR-SCHEME-BACKGROUND-DARK *COLOR-SCHEME-COMMENT)
(curses "init_pair" NIL 6 *COLOR-SCHEME-BACKGROUND-DARK *COLOR-SCHEME-FUNCTION)
(curses "init_pair" NIL 7 *COLOR-SCHEME-BACKGROUND-DARK *COLOR-SCHEME-VALUE)

它不起作用。相反,颜色对1、2和3都显示为相同的颜色对。然后4和6显示为* COLOR-SCHEME-COMMENT 覆盖在* COLOR-SCHEME-BACKGROUND-DARK 之上,而5和7则显示为4和6的反转。这似乎与我输入的内容毫无逻辑关系。更奇怪的是,当我使用非自定义颜色(颜色0-7)时也不起作用,因此通过init_color定义这些颜色方案颜色与此无关。
我已经单独测试了颜色与颜色对1,所以我知道颜色被正确初始化了。 init_pair到底是怎么回事?
附言:如果我使用Lisp使这更难,我真的很抱歉,我知道这不是一种常见的语言。那时候似乎是个好主意,到目前为止还好...
编辑:我已经重新编译了libncursesw6.1,并启用了--with-trace,这是跟踪文件中的相关信息:
called {init_pair(0x1d74d00,1,10,8)
+ return }0
+ called {init_pair(0x1d74d00,2,12,8)
+ return }0
+ called {init_pair(0x1d74d00,3,11,8)
+ return }0
+ called {init_pair(0x1d74d00,4,13,8)
+ return }0
+ called {init_pair(0x1d74d00,5,8,12)
+ return }0
+ called {init_pair(0x1d74d00,6,8,11)
+ return }0
+ called {init_pair(0x1d74d00,7,8,13)
+ return }0

这些确实是正确的值,因此正确的值被传递给了init_pair。尽管自定义颜色不是问题,但对于那些想知道的人,这是trace文件中关于*COLOR-SCHEME颜色的信息:
started color: COLORS = 256, COLOR_PAIRS = 65536
+ return }0
+ called {init_color(0x1d74d00,8,216,228,252)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 8, 216, 228, 252)
+ + return }"\e]4;8;rgb:37/3A/40\e\\"
+ return }0
+ called {init_color(0x1d74d00,9,908,956,896)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 9, 908, 956, 896)
+ + return }"\e]4;9;rgb:E7/F3/E4\e\\"
+ return }0
+ called {init_color(0x1d74d00,10,968,968,968)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 10, 968, 968, 968)
+ + return }"\e]4;10;rgb:F6/F6/F6\e\\"
+ return }0
+ called {init_color(0x1d74d00,11,612,748,1000)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 11, 612, 748, 1000)
+ + return }"\e]4;11;rgb:9C/BE/FF\e\\"
+ return }0
+ called {init_color(0x1d74d00,12,508,252,340)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 12, 508, 252, 340)
+ + return }"\e]4;12;rgb:81/40/56\e\\"
+ return }0
+ called {init_color(0x1d74d00,13,612,136,272)
+ + called {tparm("\e]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\e\\", 13, 612, 136, 272)
+ + return }"\e]4;13;rgb:9C/22/45\e\\"
+ return }0

此外,尽管我将 wborder 函数设置为使用颜色对 7,根据调试信息应该是颜色 8 覆盖颜色 13(与我的代码匹配),但 trace 文件显示它实际上使用的是颜色对五,在我的代码中没有使用过。
+ called {wborder(0x1da6cd0,{' ' = 040},{' ' = 040},{' ' = 040},{' ' = 040},{' ' = 040},{' ' = 040},{' ' = 040},{' ' = 040})
using {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}, {' ' = 040 | {A_BOLD|A_COLOR{5 = {color8, color12}}}}
+ return }0

所以,我上面的猜测就是发生了。颜色对5和7被显示为相同,尽管颜色和对已经正确传递给ncurses。

我会通过构建启用跟踪的自己的ncurses共享库,并使用LD_PRELOAD或LD_LIBRARY路径来查看库对参数的处理情况。为了快速检查,ltrace可能有助于显示调用。 - Thomas Dickey
不幸的是,PicoLisp 是纯解释型语言,因此 ltrace 无法在我的程序上工作。启用跟踪功能构建 ncurses 可以提供哪些信息? - Alexis Dumas
好的,我会尝试一下,谢谢!当我有结果时,我会在这个问题中发布它们。 - Alexis Dumas
当使用--with-trace配置库时,调试跟踪功能将编译到库中,并通过环境变量打开。 我会使用--enable-trace--enable-widec(用于ncursesw)。手册提到了NCURSES_TRACE - Thomas Dickey
好的,我已经发布了调试信息。能够像这样调试ncurses真是太酷了。我从来没有想到过!(: - Alexis Dumas
显示剩余4条评论
1个回答

1

根据@christopher-dumas的说法,问题出在PicoLisp上的error:

好吧,我弄清楚了问题所在。color-pairs的实现有误,因为Picolisp只有右移操作,并且操作数顺序与C使用的相反。显然,我从原始的color-pairs实现中获取的源代码是错误的。对于新的实现,我从ncurses源代码的lib_gen.c文件中进行了复制。 新实现如下:

   (de color-pair (n)
       (& (>> -8 n) (>> -8 (- (>> -8 1) 1))))

在ncurses中,颜色对值是chtypeattr_t中的8位字段,定义在curses.h头文件中。以下是模板中的一句话(@cf_cv_1UL@被替换以处理不允许数字后缀UL的非常旧的编译器):
#define NCURSES_ATTR_SHIFT       8
#define NCURSES_BITS(mask,shift) (NCURSES_CAST(chtype,(mask)) << ((shift) + NCURSES_ATTR_SHIFT))
...
#define A_COLOR     NCURSES_BITS(((@cf_cv_1UL@) << 8) - @cf_cv_1UL@,0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接