Attributes

NCURSES Programming HOWTO
Prev |  | Next

# 8. Attributes

We have seen an example of how attributes can be used to print characters with some special effects. Attributes, when set prudently, can present information in an easy, understandable manner. The following program takes a C file as input and prints the file with comments in bold. Scan through the code.

Example 5. A Simple Attributes example

    /* pager functionality by Joseph Spainhour" <spainhou@bellsouth.net> */
    #include <ncurses.h>
    #include <stdlib.h>

    int main(int argc, char *argv[])
    {
      int ch, prev, row, col;
      prev = EOF;
      FILE *fp;
      int y, x;

      if(argc != 2)
      {
        printf("Usage: %s <a c file name>\n", argv[0]);
        exit(1);
      }
      fp = fopen(argv[1], "r");
      if(fp == NULL)
      {
        perror("Cannot open input file");
        exit(1);
      }
      initscr();				/* Start curses mode */
      getmaxyx(stdscr, row, col);		/* find the boundaries of the screeen */
      while((ch = fgetc(fp)) != EOF)	/* read the file till we reach the end */
      {
        getyx(stdscr, y, x);		/* get the current curser position */
        if(y == (row - 1))			/* are we are at the end of the screen */
        {
          printw("<-Press Any Key->");	/* tell the user to press a key */
          getch();
          clear();				/* clear the screen */
          move(0, 0);			/* start at the beginning of the screen */
        }
        if(prev == '/' && ch == '*')    	/* If it is / and * then only
                                         	 * switch bold on */
        {
          attron(A_BOLD);			/* cut bold on */
          getyx(stdscr, y, x);		/* get the current curser position */
          move(y, x - 1);			/* back up one space */
          printw("%c%c", '/', ch); 		/* The actual printing is done here */
        }
        else
          printw("%c", ch);
        refresh();
        if(prev == '*' && ch == '/')
          attroff(A_BOLD);        		/* Switch it off once we got *
                                     	 * and then / */
        prev = ch;
      }
      endwin();                       	/* End curses mode */
      fclose(fp);
      return 0;
    }

Don't worry about all those initialization and other crap. Concentrate on the while loop. It reads each character in the file and searches for the pattern /*. Once it spots the pattern, it switches the BOLD attribute on with `attron()` . When we get the pattern */ it is switched off by `attroff()` .

The above program also introduces us to two useful functions `getyx()` and `move()`. The first function gets the co-ordinates of the present cursor into the variables y, x. Since getyx() is a macro we don't have to pass pointers to variables. The function `move()` moves the cursor to the co-ordinates given to it.

The above program is really a simple one which doesn't do much. On these lines one could write a more useful program which reads a C file, parses it and prints it in different colors. One could even extend it to other languages as well.

## 8.1. The details

Let's get into more details of attributes. The functions `attron(), attroff(), attrset()` , and their sister functions `attr_get()` etc.. can be used to switch attributes on/off , get attributes and produce a colorful display.

The functions attron and attroff take a bit-mask of attributes and switch them on or off, respectively. The following video attributes, which are defined in <curses.h> can be passed to these functions.

        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_CHARTEXT      Bit-mask to extract a character
        COLOR_PAIR(n)   Color-pair number n

The last one is the most colorful one :-) Colors are explained in the next sections.

We can OR(|) any number of above attributes to get a combined effect. If you wanted reverse video with blinking characters you can use

        attron(A_REVERSE | A_BLINK);

## 8.2. attron() vs attrset()

Then what is the difference between attron() and attrset()? attrset sets the attributes of window whereas attron just switches on the attribute given to it. So attrset() fully overrides whatever attributes the window previously had and sets it to the new attribute(s). Similarly attroff() just switches off the attribute(s) given to it as an argument. This gives us the flexibility of managing attributes easily.But if you use them carelessly you may loose track of what attributes the window has and garble the display. This is especially true while managing menus with colors and highlighting. So decide on a consistent policy and stick to it. You can always use `standend()` which is equivalent to `attrset(A_NORMAL)` which turns off all attributes and brings you to normal mode.

## 8.3. attr_get()

The function attr_get() gets the current attributes and color pair of the window. Though we might not use this as often as the above functions, this is useful in scanning areas of screen. Say we wanted to do some complex update on screen and we are not sure what attribute each character is associated with. Then this function can be used with either attrset or attron to produce the desired effect.

## 8.4. attr_ functions

There are series of functions like attr_set(), attr_on etc.. These are similar to above functions except that they take parameters of type `attr_t`.

## 8.5. wattr functions

For each of the above functions we have a corresponding function with 'w' which operates on a particular window. The above functions operate on stdscr.

## 8.6. chgat() functions

The function chgat() is listed in the end of the man page curs_attr. It actually is a useful one. This function can be used to set attributes for a group of characters without moving. I mean it !!! without moving the cursor :-) It changes the attributes of a given number of characters starting at the current cursor location.

We can give -1 as the character count to update till end of line. If you want to change attributes of characters from current position to end of line, just use this.

        chgat(-1, A_REVERSE, 0, NULL);

This function is useful when changing attributes for characters that are already on the screen. Move to the character from which you want to change and change the attribute.

Other functions wchgat(), mvchgat(), wchgat() behave similarly except that the w functions operate on the particular window. The mv functions first move the cursor then perform the work given to them. Actually chgat is a macro which is replaced by a wchgat() with stdscr as the window. Most of the "w-less" functions are macros.

Example 6. Chgat() Usage example

    #include <ncurses.h>

    int main(int argc, char *argv[])
    {	initscr();			/* Start curses mode 		*/
    	start_color();			/* Start color functionality	*/

    	init_pair(1, COLOR_CYAN, COLOR_BLACK);
    	printw("A Big string which i didn't care to type fully ");
    	mvchgat(0, 0, -1, A_BLINK, 1, NULL);
    	/*
    	 * First two parameters specify the position at which to start
    	 * Third parameter number of characters to update. -1 means till
    	 * end of line
    	 * Forth parameter is the normal attribute you wanted to give
    	 * to the charcter
    	 * Fifth is the color index. It is the index given during init_pair()
    	 * use 0 if you didn't want color
    	 * Sixth one is always NULL
    	 */
    	refresh();
        	getch();
    	endwin();			/* End curses mode		  */
    	return 0;
    }

This example also introduces us to the color world of curses. Colors will be explained in detail later. Use 0 for no color.

Prev | Home | Next
Input functions |  | Windows