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
/* File path: basics/simple_attr.c */
#include <ncurses.h>
int main(int argc, char *argv[])
{ int ch, prev;
FILE *fp;
int goto_prev = FALSE, 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 */
prev = EOF;
while((ch = fgetc(fp)) != EOF)
{ if(prev == '/' && ch == '*')
/* If it is / and * then only switch bold on */
{ attron(A_BOLD);
goto_prev = TRUE; /* Go to previous char / and print it in BOLD */
}
if(goto_prev == TRUE)
{ getyx(stdscr, y, x);
move(y, x - 1);
printw("%c%c", '/', ch); /* The actual printing is done here */
goto_prev = FALSE; /* Set it to FALSE or every thing from
* here will be / */
}
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 */
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.
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
/* File path: basics/with_chgat.c */
#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 character
* Fifth is the color index. It is the index given during init_pair()
* use 0 if you don't want color.
* Sixth one is always NULL
*/
refresh();
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.