Цветовые пары в ncurses не используют правильные цвета

Я пытаюсь использовать ncursew6.1 (связанный с PicoLisp). Насколько я знаю, PicoLisp напрямую передает значения таким образом, что тот факт, что я вызываю ncurses через язык, отличный от C, не должен быть фактором[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?

P.S. Мне искренне жаль, если тот факт, что я использую Лисп, усложняет задачу, я знаю, что это не общий язык. В то время это казалось хорошей идеей, и до сих пор все было хорошо ...

Редактировать: я перекомпилировал 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.


person Christopher Dumas    schedule 24.12.2018    source источник
comment
Я бы проверил это, создав свои собственные общие библиотеки ncurses с включенной трассировкой и используя путь LD_PRELOAD или LD_LIBRARY, чтобы увидеть, что библиотека делает с параметрами. Для быстрой проверки ltrace может помочь отобразить звонки.   -  person Thomas Dickey    schedule 24.12.2018
comment
К сожалению, PicoLisp полностью интерпретируется, поэтому ltrace не работает в моей программе. Какую именно информацию я могу ожидать от сборки ncurses с включенной трассировкой?   -  person Christopher Dumas    schedule 24.12.2018
comment
Отладочная трассировка (например, установка NCURSES_TRACE на 0x224) показывает вызовы, их параметры и возвращаемые значения. Учитывая это, вы можете проверить, правильно ли код лиспа попадает в/из библиотеки.   -  person Thomas Dickey    schedule 24.12.2018
comment
Хорошо, я попробую, спасибо! Я отправлю результаты на этот вопрос, когда они у меня будут.   -  person Christopher Dumas    schedule 24.12.2018
comment
Как включить трассировку отладки? Я попытался просмотреть исходный код ncurses (6.1, загруженный с домашней страницы), чтобы увидеть, была ли это константа, и это не так. Согласно документации GNU, это переменная среды, но ncurses не использует ее, когда я ее export, нужно ли ее устанавливать при компиляции ncurses?   -  person Christopher Dumas    schedule 24.12.2018
comment
Функция трассировки отладки компилируется в библиотеку при ее настройке с помощью --with-trace и включается с помощью переменной среды. Навскидку я бы использовал --enable-trace, --enable-widec (для ncursesw). На странице руководства упоминается NCURSES_TRACE.   -  person Thomas Dickey    schedule 24.12.2018
comment
Спасибо, я так и думал. Я скомпилирую пользовательскую версию ncurses и буду использовать ее, я просто не знал, какой вариант компилирует ее с поддержкой трассировки. Да, по какой-то причине man-страница не показалась мне очень понятной, когда я ее читал.   -  person Christopher Dumas    schedule 24.12.2018
comment
Хорошо, я разместил отладочную информацию. Это действительно крутая штука, иметь возможность отлаживать такие ncurses. Никогда бы не нашел! (:   -  person Christopher Dumas    schedule 24.12.2018
comment
Давайте продолжим обсуждение в чате.   -  person Thomas Dickey    schedule 24.12.2018


Ответы (1)


По словам @christopher-dumas, проблема заключалась в ошибке в PicoLisp:

Итак, я понял, в чем проблема,
пары цветов были реализованы неправильно, потому что в Picolisp есть только операция сдвига вправо, а порядок операндов противоположен тому, что используется в C. Судя по всему, источник, откуда я взял оригинальную реализацию цветовых пар, был неверным. Для новой реализации я скопировал ее из lib_gen.c в исходном коде ncurses. Новая реализация:

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

В ncurses значение цветовой пары представляет собой 8-битное поле в chtype или attr_t, определенное в файле 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)
person Thomas Dickey    schedule 04.05.2020