I have compiled NCurses 6.3 with the --enable-ext-colors
and --enable-widec
flags.
I then iterate across all background colors, for each foreground color:
void initColorPairs()
{
for (int foregroundId = 0; foregroundId < 255; foregroundId++)
{
for (int backgroundId = 0; backgroundId < 255; backgroundId++)
{
init_extended_pair(
getColorPairId(foregroundId, backgroundId),
foregroundId,
backgroundId);
}
}
};
This sets the macro COLOR_PAIRS to 65536.
...
std::cout << "initialized color pairs: " << COLOR_PAIRS << std::endl; //displays `initialized color pairs: 65536`
...
This is working perfectly.
I have a unique id for every color pair defined by this function:
int getColorPairId(int foregroundId, int backgroundId)
{
return foregroundId + (backgroundId << 8);
};
This all appears to work perfectly. However, when trying to render each of these possible color pairs and printing them next to each other:
// visualize
std::string testText = "a";
for (int foregroundId = 0; foregroundId < 255; foregroundId++)
{
for (int backgroundId = 0; backgroundId < 255; backgroundId++)
{
attr_on(COLOR_PAIR(getColorPairId(foregroundId, backgroundId)), NULL);
mvprintw(foregroundId, backgroundId, testText.c_str());
}
}
Instead of ending up with a screen full of each foreground color against each background color I end up with this:
It should be changing the background color with each character, but it only seems to change the foreground.
Strangely, if the colorId construction is reversed (foreground shifted over 8 bits instead of background), the background iterates instead of the foreground!
int getColorPairId(int foregroundId, int backgroundId)
{
return backgroundId + (foregroundId << 8);
};
Without using the extended colors in the library interface, color pairs are limited to 32767 (signed 16-bit numbers).
That NULL
in
attr_on(COLOR_PAIR(getColorPairId(foregroundId, backgroundId)), NULL);
should be used to pass the value of an integer (more than 16-bits) for the color pair, as mentioned in the Extensions section of the manual page, eg,
- For functions which modify the color, eg,
wattr_set
, if opts is set it is treated as a pointer to int, and used to set the color pair instead of the short pair parameter.
But in expanding the answer, I see that these calls are overlooked (probably because the color-pair is not an explicit parameter to these, but is a derived value within the body of the function):
The remaining functions which have opts, but do not manipulate color, eg,
wattr_on
andwattr_off
are not used by this implementation except to check that they are NULL.
The ncurses-examples (demo and test-programs) include a few using attr_on
(see README
), but those calls aren't using this particular extension ( dots_xcurses
would be a good place to do that – optionally of course).
picsmap
uses the feature via setcchar
:
wattr_on
setcchar
, using the macro set_extended_pair
#define set_extended_pair(opts, color_pair) \ if ((opts) != NULL) { \ color_pair = *(const int*)(opts); \ }
That macro is used in other functions (to allow those to be conditionally compiled with/without the feature):
new_pair.h:71:#define set_extended_pair(opts, color_pair) \
new_pair.h:78:#define set_extended_pair(opts, color_pair) \
base/lib_chgat.c:64: set_extended_pair(opts, color_pair);
base/lib_colorset.c:54: set_extended_pair(opts, color_pair);
base/lib_slkatr_set.c:58: set_extended_pair(opts, color_pair);
widechar/lib_cchar.c:63: set_extended_pair(opts, color_pair);
widechar/lib_vid_attr.c:101: set_extended_pair(opts, color_pair);
For wattr_on.c
, the chunk
if_EXT_COLORS({
if (at & A_COLOR)
win->_color = PairNumber(at);
});
(which extracts a color pair from the attribute parameter) would look like
if_EXT_COLORS({
if (at & A_COLOR) {
win->_color = PairNumber(at);
set_extended_pair(opts, win->_color);
}
});
wattr_set
is handled properly:
#define wattr_set(win,a,p,opts) \
(NCURSES_OK_ADDR(win) \
? ((void)((win)->_attrs = ((a) & ~A_COLOR), \
(win)->_color = (opts) ? *(int *)(opts) : (p)), \
OK) \
: ERR)
(No change would be needed for wattr_off
, of course). X/Open Curses assumes that the attribute parameter at
of wattr_on
does not include bits for a color pair. ncurses does do this (because it uses the same layout for the attributes in narrow/wide libraries), so providing a use for the opts
parameter is consistent – for ncurses.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.