Ncurses colors

I am using ncurses to develop a user interface. Perhaps I should be using something else, but I am reasonably comfortable with ncurses and don't really want to climb another learning curve at this time.

One problem I have dealt with for many years is ncurses' colors. I have simply been unable to affect the standard colors that are inherent to the code. Specifically, at least a couple of the standard colors look like they have been washed in mud!

COLOR_WHITE, when used as a background, is a light grey. Using a color_pair of COLOR_BLACK, COLOR_WHITE results in dark grey letters on a light grey background.

OTOH, COLOR_WHITE,COLOR_RED has nice bright white letters on a nice red background.

The standard COLOR_YELLOW looks like mustard, not a bright yellow like I would desire.

init_color doesn't seem to have any effect at all.

I have collected sample of what ncurses gives me in the attachment. To illustrate my dislike of the ncurses colors, I have embedded the samples in a background of the same colors as GIMP supplies. The black text labeling each piece was supplied via GIMP.

Suggestions?

Hi BillLee...

I am not familiar with ncurses but to get an extended range to the colours in the shell the __bold__ attribute has be on...

I assume that there is a BOLD attribute for ncurses...

This is an example, note the second loop might not work in some terminals...

#!/bin/bash
# colours.sh
n=0
for fg in {30..37}
do
	for bg in {40..47}
	do
		for bold in 0 1
		do
			# 1 = bold ON.
			printf "\x1B["$bold";"$bg";"$fg"m Line $n, bold = $bold, background = $bg, foreground = $fg...\x1B[0m\n"
			n=$((n+1))
		done
	done
done
for fg in {90..97}
do
	for bg in {100..107}
	do
		for bold in 0 1
		do
			# 1 = bold ON.
			printf "\x1B["$bold";"$bg";"$fg"m Line $n, bold = $bold, background = $bg, foreground = $fg...\x1B[0m\n"
			n=$((n+1))
		done
	done
done
2 Likes

Thanks for the reply.

I failed to note that all of the ncurses text in my example was in bold font.

That are alot of lines...
Mine's not that esay share-able :expressionless:
But imho much more overseeable. :wink:

The script will not run without TUI.

#!/bin/bash
# myColors
# Description:	a little color demonstration
# ------------------------------------------------------
#
#	Variables
#
	R=$(tui-conf-get /etc/tui/colors.conf TUI_COLOR_RESET)
	R=${R/^ /}
	TC=TUI_COLOR_
	TF=TUI_FONT_
	colors="BLACK BLUE CYAN GREEN GREY PURPLE RED WHITE YELLOW"
	styles="BOLD  UNDERSCORE STROKE " #  INVERT
#
#	Functions
#
	be_color() { # STRING_NAME
	# Returns the value of STRING_NAME
	# Expects strings like: TUI_COLOR_[BF]G_<NAME> or TUI_FONT_<STYLE>
		tui-conf-get /etc/tui/colors.conf $1
	}
#
#	Display & Action
#
	tui-title "Color demonstation using tui color names"
	for font in $colors;do
	# This is the font color, and shall be used for the whole line
		F="$(be_color ${TC}FG_${font})"
		for sty in $styles;do
			S="$(be_color ${TF}${sty})"
			for col in $colors;do
				# This is the back color, used for the column
				B="$(be_color ${TC}BG_${col})"
				C="${R}${F}${B}" # Closer
				a="${TC}FG_${font} \t${TF}${sty}"
				# Regular output
				printf "${C}a${S}style"
			done
			printf "$R -- $a \n"
		done
	done

Again, thanks for the response, but I don't see how this addresses my original question: what do I need to do to make ncurses display reasonable colors?

And, supporting wisecracker's suggestion, from the curs_color(3X) man page on OS X:

       Several caveats apply on  386  and  486  machines  with  VGA-compatible
       graphics:

       -    COLOR_YELLOW  is  actually brown.  To get yellow, use COLOR_YELLOW
            combined with the A_BOLD attribute.
       ... ... ...

Hello BillLee
This is some code from a long time ago. Dont use C much anymore. If you're not using C this might not help. I hope it does though.

int
StartColors ()
{
  start_color ();

  init_pair (0, COLOR_WHITE, COLOR_BLACK);
  init_pair (1, COLOR_CYAN, COLOR_BLACK);
  init_pair (2, COLOR_WHITE, COLOR_BLUE);
  init_pair (3, COLOR_WHITE, COLOR_BLACK);
  init_pair (4, COLOR_WHITE, COLOR_RED);
  init_pair (5, COLOR_BLACK, COLOR_GREEN);
  /*
  init_pair (0, COLOR_WHITE, COLOR_BLACK);
  init_pair (DIR_NORM, COLOR_CYAN, COLOR_BLACK);
  init_pair (DIR_HI, COLOR_BLUE, COLOR_WHITE);
  init_pair (FIL_NORM, COLOR_WHITE, COLOR_BLACK);
  init_pair (FIL_HI, COLOR_RED, COLOR_WHITE);
  init_pair (5, COLOR_BLACK, COLOR_GREEN);
  init_pair (6, COLOR_MAGENTA, COLOR_BLACK);
  init_pair (7, COLOR_BLUE, COLOR_CYAN);
  init_pair (8, COLOR_RED, COLOR_BLACK);
  init_pair (9, COLOR_BLUE, COLOR_CYAN);
  init_pair (10, COLOR_GREEN, COLOR_BLACK);
  init_pair (12, COLOR_CYAN, COLOR_BLACK);
  init_pair (13, COLOR_BLUE, COLOR_WHITE);
  init_pair (14, COLOR_YELLOW, COLOR_CYAN);
  init_pair (15, COLOR_WHITE, COLOR_BLUE);
  init_pair (16, COLOR_YELLOW, COLOR_CYAN);
  init_pair (17, COLOR_BLUE, COLOR_WHITE);
  init_pair (18, COLOR_YELLOW, COLOR_RED);
  init_pair (19, COLOR_YELLOW, COLOR_BLACK);
  */

  return (0);
}



int
WbkgdSet (WINDOW * w, chtype c)
{
  if (has_colors ())
    {
      wbkgdset (w, c);
    }
  else
    {
      c &= ~A_BOLD;
      if (c == COLOR_PAIR (1) ||
      c == COLOR_PAIR (2) ||
      c == COLOR_PAIR (3) || c == COLOR_PAIR (4) || c == COLOR_PAIR (5))
    {

      wattrset (w, A_REVERSE);
    }
      else
    {
      wattrset (w, 0);
    }
    }
}

I have to agree with the man page: the yellow is quite brown! :slight_smile: But I disagree that it becomes anything else when combined with the A_BOLD attribute since all of my code uses A_BOLD everywhere.

It seems interesting that when I use YELLOW as a foreground color, it renders as a bright yellow, but when used as a background (even including the A_BOLD attribute), it renders as a muddy brown.

The same goes for COLOR_WHITE: it renders differently in foreground vs. background.

Seems like a pattern (i.e., foreground o.k., background muddy) until you look at COLOR_BLACK which renders as a medium grey in foreground, but a true dark black as background.

Those foreground/background colours are a limited set of eight colours each; foreground can be set to bold or bright to give another eight. That's it.
What you can do on a capable terminal is the "set palette" ESC- sequence to assign other colour codes to those FG/BG colours: Try echo -e "\033]P7ffffff" ; this should set your grey background to shining white.

RudiC, can you give me some pointers to an ncurses description of "bright"? I can see the bold definition (A_BOLD) in the ncurses man pages, but haven't seen anything like "bright".

BTW:
On my system (Linux/Fedora20), I did a bit of checking. Ncurses says I have 256 colors and 256 color_pairs. I dumped the first 20 colors and got what you can see in the attachment below.

I was also able to get a bright white background by using color #15, but all attempts at getting a dark black for eth foreground failed and I am using color #19, a dark-ish blue. See the other attachment below.

Have you tried setting the inverse video attribute?
A_REVERSE along with a combination of the other video attributes.
Just an idea...

EDIT:
Another suggestion...

How about writing a simple piece of code to display the colours available like I did for the shell one which I might add did not show two other loops to __cross__pollinate__ low number foreground and high number background and vice versa...

Please take a look. I think these screen shots are pretty self-explanatory. Also illustrative of what I am experiencing: black foreground with any background is washed out completely, all of the standard colors as background are muddy, and seem to worsen when a black foreground is used.

Before going any further have you tried seeing if your terminal can create a bright white background along with black foreground, bold or normal?
An example using extended colours in some terminals.

#!/bin/bash
printf "\x1B[0;107m\x1B[2J\x1B[H"
printf "\x1B[30m           Print some text here...\n"

On OSX 10.7.5, default bash terminal this gives normal black on bright white background.

Yes, that works as expected. black fg and white bg.

What is the result of my proposed ESC- sequence on your linux system's virtual consoles? And, what terminal emulator do you use?
On my consoles, above gives a brilliant white while my lxterminal doesn't accept the command.

Hi RudiC...
It doesn't work on OSX 10.7.5, default bash terminal...

Last login: Sat Dec 13 22:08:44 on ttys000
AMIGA:barrywalker~> bash -version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
AMIGA:barrywalker~> echo -e "\033]P7ffffff"
7ffffff
AMIGA:barrywalker~> _

Rudi, it does nothing on my Linux system. Tried the "Konsole" as well as an xterm.

My system is a KDE build, and the default terminal emulator is "konsole".

Too bad. Sorry.

Btw, I was not talking of the KDE- "Konsole", but of the virtual consoles that you can switch to with the <Alt>-Fn keys (evtl. <Ctrl><Alt>Fn).

Perhaps there is something to be had using virtual consoles, but the application I am developing will always want to be run in a user's default environment. Making ncurses work as I wish in that environment is the purpose of this thread.

Sadly it looks as though ncurses has a limitation and having never coded fo it then I(/we) are probably not going to be able to find a solution at this point.

I will pursue a little further but I don't envisage a solution any time soon.

If you do find one please upload your findings for the greater good...

Humble apologies...