curses and screen colors

Stacey Campbell staceyc at sco.COM
Wed Oct 31 14:03:30 AEST 1990


In article <385 at sherpa.UUCP> rac at sherpa.UUCP (Roger Cornelius) writes:
>Under SCO UNIX:
>
>Whenever I build a program which uses terminfo curses on SCO UNIX, the
>program always restores the screen to white characters on a black
>background when it exits, regardless of what colors the screen was set
>to when the program started.

Unfortunately, there is no consistent portable method that allows
curses to determine what fg/bg color pair is active when the program
does a start_color().  The best curses can do is reset the terminal
to the color pair defined by op (original_pair).  Your terminfo entry
sets this to white foreground and black background.

>If I run an old XENIX binary of the same
>program, the screen is left with the original colors when the program
>exits.

The Xenix curses library does not support color attributes, so it
never diddles with the defined color pair, i.e. it never has to
attempt to reset the color pair.

>My question is how do I prevent curses from changing my screen colors
>when the program exits?  This should be automatic I think.

Since curses outputs op on endwin(), you can change op to be whatever
color pair you wish.  If you have different screen colors defined for
other multiscreens, then you will have to write some sort of wrapper
around either the program or before and after the initscr()/start_color()
and endwin() calls.  Naturally this wrapper would have to deal with $TERM.
Note that the console setcolor utility obviously knows how to reset
colors.

If $TERM is a SCO ansi console then the following little program will work;

/*
 * Gets/sets console colors that would otherwise be reset to
 * black and white by a curses color application.
 */


#include <stdio.h>
#include <signal.h>

#define GIO_ATTR  ('a' << 8) | 0	/* Ioctl call for current attribute */

static void SetColor();

int main(argc,argv)

int argc;
char *argv[];

{
	int cur_attr;

	(void)signal(SIGINT, SIG_IGN);
	(void)signal(SIGQUIT, SIG_IGN);
	if (argc == 1)
	{
		cur_attr = ioctl(0, GIO_ATTR, 0);
		if (cur_attr == -1)
			printf("not console\n");
		else
			printf("%x\n", cur_attr);
	}
	else
	{
		if (sscanf(argv[1], "%x", &cur_attr) != 1)
			exit(1);
		SetColor(cur_attr & 0x0F, (cur_attr >> 4) & 0x0F);
		exit(0);
	}

	return 0;
}

static void SetColor(forecolor, backcolor)

int forecolor, backcolor;

{
	printf("\033[=%dF", forecolor);
	printf("\033[=%dG", backcolor);
	printf("\033[0m");
	fflush(stdout);
}

If the program is called without parameters it outputs the current
color attributes.  If it is called with one parameter it sets the
color attributes to that parameter.  Usage would be;

:
saved_colors="not console"
if [ "$TERM" = "ansi" ]
then
    saved_colors=`conscolor`
fi
run_application
if [ "$saved_colors" != "not console" ]
then
	conscolor "$saved_colors"
fi

Note that the above will not work across an rlogin session to another
host, and that the above probably will not work for non-SCO console
drivers.  Also note that similar interrogation programs can be written
for assorted color terminals on the market; using write, select and read
instead of an ioctl().
-- 
Stacey Campbell       staceyc at sco.com
{uunet,decwrl,ucscc,att,sq,altos,lotus,phoenix,sun,microsoft,xbs}!sco!staceyc



More information about the Comp.unix.xenix.sco mailing list