Programming xtrem-256color ncurses in C: setting color pairs

Hello, I'm new to this site and seeking help.

I'm writing an ncurses program in C, hoping to be able to make full use of the xterm-256color terminal by creating as many color pairs as I can to show the full spectrum of colors. ncurses reports that I can use up to 256 colors (COLORS) and 65536 color pairs (COLOR_PAIRS.) So to combine every possible pair, I should need to use exactly all of them ((256 * 256) - 1.) (- 1 because I can't change pair 0.)

However, when looping through, init_pair() fails, returning 1 when it reaches pair 32767 and for any higher numbers. What gives? Is COLOR_PAIRS lying? It is only half-way through.

Any ideas? Thanks in advance for your help.

Richard

@rellwood , welcome we hope you can find the forum educational and helpful.

  • have you tried anything yourself ? - show that?
  • have you searched online for examples ?
  • please provide the code + error thrown/encountered
    you recognised the affinity between (256256),and32767 * 2

Thanks for your reply. Here is my code that initializes ncurses and attempts to create as complete an RGB palette as possible.

int color256depth;
float color256multiplier;

void term_init() {
  
  setlocale(LC_CTYPE, "");
  initscr();
  if(has_colors())
  {
    if(start_color() != 0) {
      // TODO: Handle this
      term_exit();
      printf("ERROR: unable to start color mode\n");
      exit(EXIT_FAILURE);
    }
    if(can_change_color())
    {
      // There can be at most COLORS possible colors.  So to define them we
      // need to find what depth of red, green, and blue we can use.  Take
      // the cube root and round down.
      color256depth = floor(cbrt(COLORS));

      // Initializing each color requires a value of 0 - 1000 for each red,
      // green, and blue.  So we need to find the multiplier for the
      // color256depth to bring it up to 1000 for the highest value
      color256multiplier = 1000.00f / ((float) color256depth);

      short int ref_r, ref_g, ref_b;
      int color_count = COLOR256_START_INDEX;
      for(int r = 0; r < color256depth; r++) {
        for(int g = 0; g < color256depth; g++) {
          for(int b = 0; b < color256depth; b++) {
            if(init_color(color_count, r * color256multiplier,
                                       g * color256multiplier,
                                       b * color256multiplier) != 0) {
              term_exit();
              // TODO: handle this
              printf("ERROR: error returned on init_color\n");
              exit(EXIT_FAILURE);
            }
            // Check that the color has been correctly set as expected.
            color_content(color_count, &ref_r, &ref_g, &ref_b);
            if(   (int) (r * color256multiplier) != ref_r
               || (int) (g * color256multiplier) != ref_g
               || (int) (b * color256multiplier) != ref_b) {
              // TODO: Handle this
              term_exit();
              printf("ERROR: set color attempt failed\n");
              exit(EXIT_FAILURE);
            }
            color_count++;
          }
        }
      }

      // Next we make all possible color pairs.  Do we have enough slots for
      // every combination?
      if((color_count * color_count) + COLOR256_PAIR_START_INDEX > COLOR_PAIRS) {
        // TODO: Handle this
        term_exit();
        printf("ERROR: not enough color pairs avaliable\n");
        exit(EXIT_FAILURE);
      }
      int pair_index = COLOR256_PAIR_START_INDEX;
      for(int foreground = COLOR256_START_INDEX; foreground < color_count;
          foreground++) {
        for(int background = COLOR256_START_INDEX; background < color_count;
            background++) {
          if(init_pair(pair_index, foreground, background) != 0) {
             // TODO: Handle this
             term_exit();
             printf("ERROR: unable to set color pair #%d\n", pair_index);
             exit(EXIT_FAILURE);
          }
          pair_index++;
        }
      }
    }
  }
}

The program exits with
ERROR: unable to set color pair #32767

you recognised the affinity between (256256),and32767 * 2

Yes. I wonder if I have a signed/unsigned mismatch, and there are in fact only 32767 available color pairs. Any ideas?

Thank you, Richard

@rellwood , thks, will take a look through when I've got some time .
can you give OS - name and version, and the compiler (+ version) and the command line used to build

also , check the function signatures ... , believe most use short int as parameters for arguments (whilst they return an int wrt success/failure) , also a print of the values of the constants COLOR.... may be of use

(on mac ... )

man init_pairs
curs_color(3X)                                                                                                                                                    curs_color(3X)

NAME
       start_color, init_pair, init_color, has_colors, can_change_color, color_content, pair_content, COLOR_PAIR - curses color manipulation routines

SYNOPSIS
       # include <curses.h>
       int start_color(void);
       int init_pair(short pair, short f, short b);
       int init_color(short color, short r, short g, short b);
       bool has_colors(void);
       bool can_change_color(void);
       int color_content(short color, short *r, short *g, short *b);
       int pair_content(short pair, short *f, short *b);
....

tks