man attron
Each character can have one or more attributes associated with it, these include:
Name Description A_NORMAL Normal display (no highlight) A_STANDOUT Best highlighting mode of the terminal. A_UNDERLINE Underlining A_REVERSE Reverse video A_BLINK Blinking A_DIM Half bright A_BOLD Extra bright or bold A_PROTECT Protected mode A_INVIS Invisible or blank mode A_ALTCHARSET Alternate character set A_ITALIC Italics
A_NORMAL
A_STANDOUT
A_UNDERLINE
A_REVERSE
A_BLINK
A_DIM
A_BOLD
A_PROTECT
A_INVIS
A_ALTCHARSET
A_ITALIC
Attributes can be turned on or off using:
int attron(int attrs);
int attroff(int attrs);
int attrset(int attrs);
Set attributes to attrs explicitly.
Example: Turn on bold and underlining
attrset(A_BOLD | A_UNDERLINE); printw("Highlighted and underlined"); // Back to normal: attrset(A_NORMAL);
Attributes can be applied directly to a character when using addch() or mvaddch(), ex:
// Adds an x to the screen that is both bold and underlined. addch('x' | A_BOLD | A_UNDERLINE);
The Binary OR operator or single vertical bar (|) logically ORs all the binary bits both the left and right operands together, the result being where each bit in the result is a 1 (i.e. set) if the same bit in either the left or right operand has the same bit set to a 1 and will be 0 (zero) if neither the left or right operand has that bit set.
|
1
0
Example:
153 | 77 == 221 (decimal) 10011001 (153 in binary) | 01001101 ( 77 in binary) ────────── 11011101 (221 in binary)
For the purposes of curses programming (and in many other C programming circumstances,) it is enough to think of the binary OR operator as being addition (in fact, + is sometimes used as the OR operation in Boolean algebra,) and often addition could be used in lieu of binary OR. In our case we want to add one or more attributes to a character, so we use the binary OR operator when doing so.
man addch
In curses we can use some semi-graphical characters, known as the Alternate Character Set (ACS) characters. Such characters can only be added to the screen using the *addch() functions or by setting the A_ALTCHARSET attribute before . The characters are referred to by their ACS name, a table of which is shown here.
addch()
// This: move(0,0); addch(ACS_ULCORNER); addch(ACS_HLINE); addch(ACS_TTEE); addch(ACS_HLINE); addch(ACS_URCORNER); move(1,0); addch(ACS_VLINE); addch(' '); addch(ACS_VLINE); addch(' '); addch(ACS_VLINE); move(2,0); addch(ACS_LTEE); addch(ACS_HLINE); addch(ACS_PLUS); addch(ACS_HLINE); addch(ACS_RTEE); move(3,0); addch(ACS_VLINE); addch(' '); addch(ACS_VLINE); addch(' '); addch(ACS_VLINE); move(4,0); addch(ACS_LLCORNER); addch(ACS_HLINE); addch(ACS_BTEE); addch(ACS_HLINE); addch(ACS_LRCORNER); // Would render this: ┌─┬─┐ │ │ │ ├─┼─┤ │ │ │ └─┴─┘
To use colors on your terminal, your terminal type must be set to a terminal type that can support colors. Typically 'xterm' is the preferred terminal type. This is done by setting your 'term' shell variable:
set term=xterm
To make this permanent, edit your ~/.cshrc file to either add or edit the term variable to make it xterm. (this should already be the case for your CS256 accounts.)
In curses a color has two components, the foreground or text color and the background color. These colors cannot be set individually, they are set in what is called a color pair.
To tell curses to enable colors, use:
int start_color(void);
The default colors available are:
COLOR_BLACK
COLOR_RED
COLOR_GREEN
COLOR_YELLOW
COLOR_BLUE
COLOR_MAGENTA
COLOR_CYAN
COLOR_WHITE
To produce a color pair, we use the function:
int init_pair(short pair, short f, short b);
pair The number for this particular combination of colors. f The foreground (text) color b The background color
pair
f
b
example:
init_pair(1, COLOR_RED, COLOR_WHITE); // Makes color pair #1 red on white
Note: color pair #0 is a special pair that defaults to the terminals normal foreground and background color.
The following loop will initialize all 8 x 8 combinations of colors
for(int fg=0; fg < 8; fg++) for(int bg=0; bg < 8; bg++) init_pair( (fg*8 + bg), fg, bg );
To apply a color pair to a character or characters it must be applied as an attribute, which can be done with the attron, attroff and attrset functions or directly on a character via the addch functions. However it must fist be converted to an attribute form, which is done with the COLOR_PAIR() macro function:
attron
attroff
attrset
addch
COLOR_PAIR()
COLOR_PAIR(int n);
The COLOR_PAIR() function takes a color pair number and returns that color as an attribute which can be given to functions that take attributes.
Examples:
// Apply color pair 5 to the character 'x': addch('x' | COLOR_PAIR(5));
// Make red on black the current color for all characters that follow: // This assumes we setup our color pairs using the fg/bg loop above: attron(COLOR_PAIR(COLOR_RED*8 + COLOR_BLACK));
#include <curses.h> #include <string.h> int main(void) { int fg, bg; initscr(); start_color(); // Define all the foreground and background combinations: for(fg=0; fg < 8; fg++) for(bg=0; bg < 8; bg++) init_pair( (fg*8 + bg), fg, bg ); clear(); move(2, 20); // Draw the background color numbers across the top: for(bg=0; bg < 8; bg++) { printw("%3d", bg); } move(3, 19); // Draws a line under the top numbers: addch(ACS_ULCORNER); for(bg=0; bg < 8; bg++) { addch(ACS_HLINE); addch(ACS_HLINE); addch(ACS_HLINE); } // For every foreground color (one each row): for(fg=0; fg < 8; fg++) { attrset(A_NORMAL); mvprintw(4+fg,16, "%2d ", fg); addch(ACS_VLINE); // All the background colors for each foreground color (columns): for(bg=0; bg < 8; bg++) { attrset(COLOR_PAIR(fg*8 + bg)); addch('x'|A_DIM); addch('x'); addch('x'|A_BOLD); } } attrset(A_NORMAL); getch(); endwin(); return 0; }
int curs_set(int visibility);
where visibility is on of:
visibility 0 Invisible 1 Normal visibility 2 Very visible
We can read back a character that is on the screen using the inch() or mvinch() functions. Since these functions return encoded data about a character, which includes the character, it's attributes and color, we need to use the Binary AND (&, not to be confused with the address of operator) operator to separate out just the information we want from the function, examples of this are shown below:
inch()
mvinch()
&
chtype inch();
chtype mvinch(int y, int x);
Moves cursor to x,y then returns character at that position.
// Gets the character at 10,10: char ch = mvinch(10,10) & A_CHARTEXT; // Gets the Attributes and colors in use at the current cursor position: char attr = inch() & A_ATTRIBUTES; char color = inch() & A_COLOR;