简体   繁体   中英

NCurses 65536 Color Pairs

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: 字母“A”的文本块,只有前景色随字符变化

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 and wattr_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 :

    #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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM