В результате возникла необычная проблема: при запуске программы я перебираю все поддерживаемые 256 цветов (здесь используются только значения по умолчанию) и создаю пару со всеми возможными перестановками - это приводит к 65535 парам того, что я ожидал быть любой комбинацией фг / бг. Я подтвердил, что эти пары соответствуют ожиданиям, печатая в stderr.
Просто чтобы проверить, мой терминал поддерживает 256 цветов, 64k пар и переназначение цвета / пары.
Здесь возникает проблема: при попытке напечатать произвольный цвет fg / bg через attrset (и проверить, что это, на самом деле, нужная пара, как указано выше), цвета переднего плана работают нормально, но цвет фона остается без изменений. Если я жестко закодирую все значения в один цвет bg, то это произойдет, как и ожидалось, и, аналогично, обеспечение того, чтобы каждая перестановка имела идентичные цвета fg / bg (т. Е. Ограничение числа различных пар fg / bg до 256), также работает как ожидалось, и если Я ограничиваю код генерации пары только для создания 256 разных пар, я вижу цвета фона, как и ожидалось.
По сути, это, кажется, своего рода ограничение на количество уникальных пар, которые могут быть созданы (256); если я использую все 64k пар цветов с bg = 0, я могу обратиться к любому заданному цвету по всем его 256 парам, и полученное окно будет таким же, как окно, в котором я установил все перестановки fg / bg (то есть, как если бы внутри ncurses использовал 0 для всех цветов bg.
Есть идеи, как бы я подошел к этому? Я не вижу проблем с памятью в valgrind, и из того, что я могу сказать, документация ncurses подразумевает, что мое использование поддерживается.
Спасибо!
Вот код для генерации пар:
for(unsigned int c2 = 0; c2 < 256; c2++) {
for(unsigned int c1 = 0; c1 < 256; c1++) {
int pi = (c2)*256 + c1;
init_extended_pair(pi, c1, c1);
std::cerr << "init " << pi << " : " << c1 << ", " << c2 << "\n";
}
}
Расчет идентификаторов цветов (я убедился, что это работает независимо - +16 сопоставляет его с цветом ncurses по умолчанию, поскольку имеется только 216 одинаково расположенных цветов)
unsigned int CursesObject::getColor(ColorRGBA col) {
short r, g, b, er, eg, eb;
r = int(col.r);
g = int(col.g);
b = int(col.b);
er = r * 5 / 255;
eg = g * 5 / 255;
eb = b * 5 / 255;
unsigned int colID = eb + eg*6 + er * 36;
return colID + 16;
}
Вычисление идентификаторов пар для заданного fg / bg в комплекте с отладочным кодом для получения значений цветов
void CursesObject::setColor(ColorRGBA fg, ColorRGBA bg) {
if(fg == cfg && bg == cbg) return;
else if(fg == bg) {
attron(COLOR_PAIR(0));
return;
}
//attrset(0x0);
cfg = fg;
cbg = bg;
int pairID = this->getColor(fg) + (this->getColor(bg))*256;//\\\ + 16;
//std::cout << "colorPair: " << pairID << " from cid = " << this->getColor(fg) << ", col = " << fg.toString() <<"\n";
static int uidbgOff = 25;
short dr, db, dg, bbr,bbb,bbg;
int cp1, cp2;
extended_pair_content(pairID, &cp1, &cp2);
color_content(cp1, &dr, &dg, &db);
color_content(cp2, &bbr, &bbg, &bbb);
std::stringstream ss;
ss << pairID << " : " << dr << ", " << dg << ", " << db << " | " << bbr << ", " << bbg << ", " << bbb << " reported, pair " << cp1 << ":" << cp2 <<", should be " << this->getColor(fg) << ":" << this->getColor(bg)<<"\n";
//sleep(5);
attrset(COLOR_PAIR(pairID));
this->write({10,uidbgOff}, ss.str());
uidbgOff++;
//this->update();
}
Интересно, что если исходить из диагностических функций, этот код не должен работать вообще , даже только с цветами fg. Например, вывод при попытке печати красного, оранжевого и бирюзового цветов выглядит примерно так (он выдает правильные цвета, несмотря на сообщение о том, что они равны нулю или совершенно неправильный: красный должен быть 1k, 0,0 в порядке RGB - не 0, 0,1k):
4804: 0, 0, 1000 | 0, 0, 1000 сообщается, пара 196: 18, должно быть 196: 18
51664: 0, 0, 0 | 0, 0, 0 сообщается, пара 0: 0, должна быть 208: 201
59168: 0, 0, 0 | 0, 0, 0 сообщается, пара 0: 0, должна быть 32: 231