TITLE: COLOR WY-325 ASCII PROGRAMMING FOR UNIX DATE: 5/15/93 PRODUCT: WY-325 THE ISSUE: How to implement full color capability of the WY-325 in ASCII personalities - Color-associated attributes in UNIX. OVERVIEW: The WY-325, in the native and other ASCII personalities, is capable of generating 8 combinations of foreground and background colors. The following is a general guide to use for implementing the fullest possible capability of this terminal to take advantage of its color possibilities. Available from The WYSE Technology BBS (408-922-4400), is a fully annotated termcap for the WY-325, along with a "SETCOLOR" utility and a "CHECKCOLOR" demo which uses only termcap calls for color. These three files are invaluable in aiding develop- ment work with this terminal. They should help eliminate a lot of the guesswork in configuring colors. RESOLUTION: The best place to start, is to offer a definition of how the terminal generates colors. In the ASCII emulations of this terminal, colors are associated to display "ATTRIBUTES". An attribute is simply something done to certain text to make it "stand out" from the rest of the text (e.g. underlined, bolded, reversed, etc.). On monochrome terminals, attributes are commonly used in their literal sense: underline produced a line under the text, and so on. The WY-325 uses the same codes used to produce underscore, for example, to produce a unique combination of foreground and background colors. The WY325 terminal is designed to accommodate 32 different display attributes, but not all of the attribute commands produce colors. There are 8 colors available in the terminal, so only eight attributes were chosen to generate color combinations. Here are the colors available: 1) Black 2) Blue 3) Green 4) Cyan 5) Red 6) Magenta 7) Yellow 8) white These eight colors may be associated with the following chosen attributes: 1) Normal Text (Attributes Off) 2) Reverse (Blank*) Text 3) Dim Text 4) Dim & Reverse (Blank*) Text 5) Underline Text 6) Underline & Reverse (Blank*) Text 7) Underline & Dim Text 8) Underline & Dim & Reverse (Blank*) Text * Either "Reverse" OR "Blank" attribute may be selected, providing for some flexibility. This is a setup feature. The association command that puts the three items together is: Esc d y (Color) | (Attribute Association) ================================================================= 1 1 Black | 1 Normal 2 2 Blue | 2 Reverse (Blank) 3 3 Green | 3 Dim 4 4 Cyan | 4 Dim & Reverse (Blank) 5 5 Red | 5 Underline 6 6 Magenta | 6 Underline & Reverse (Blank) 7 7 Yellow | 7 Underline & Dim 8 8 White | 8 Underline & Dim & Reverse (Blank) ================================================================= (e.g. Esc d y 8 2 1 will give a White foreground on a Blue background, associated with "Normal". "Normal" will affect the whole screen. Note that there should be no in the command! Having identified and defined all eight color possibilities does not automatically bring color to life in the terminal (except "Normal" will take affect immediately). To get a color from any of the association attributes, one must do the following: 1) Call (send the Esc Sequence) the attribute (See following) 2) write out your text for the desired length of the color. 3) Turn off the attribute. The following are the Esc Sequences needed to activate the eight chosen attributes: 1) Esc G 0 Normal Text 2) Esc G 4 Reverse Text (Esc G 1) (Blank Text) 3) Esc G p Dim Text 4) Esc G t Dim & Reverse Text (Esc G q) (Dim & Blank) 5) Esc G 8 Underline Text 6) Esc G < Underline & Reverse Text (Esc G 9) (Underline & Blank) 7) Esc G x Underline & Dim Text 8) Esc G | Underline & Dim & Reverse Text (Esc G y) (Underline & Dim & Blank) Putting It All Together With UNIX/XENIX --------------------------------------- Unix and Xenix termcaps are provided so that any terminal device with any "personality" can produce the same or similar results on the screen from a single application. To put it another way, a programmer would only have to write ONE version of his/her program to accommodate different terminals, rather than writing one version for a certain terminal and other versions to accommodate other types of terminals. Termcaps are where the terminals capabilities are stored. Each terminal type should have a termcap definition detailing its unique capabilities. What all termcaps have in common, however are referred to as "labels". The "labels" are defined by an ANSI standard and should be consistent throughout the spectrum of terminals available on the system. As an example of these device independent "labels", let's take a simple example. A programmer wanted to write a program to clear the screen. A "c" program was composed which sent his WY-325 terminal the codes: Esc + . This is the command which will clear the screen, and works very well on this terminal. The programmer then found an old VT-100 terminal and wanted to do the same thing. The VT-100 command to clear the screen is actually different than the one he used in the program. When the program was run, it did not clear the screen. A second program had to be written to do this. A second version was created which contained the command: Esc [ 2 J , which is the correct command to clear the screen in VT-100 personality. It becomes apparent that there could be many different versions of the same program, and could be very confusing. Using termcaps, only one version of the program needs to be written. The clear screen commands are actually stored in each terminals termcap. This is how it's done: WY-325 Termcap VT-100 Termcap -------------- -------------- cl=\E+ cl=\E[2J Notice that the two commands to clear the screen are not the same, but these two definitions have one thing in common: the ANSI standard termcap label for clearing the screen is "cl". We would then have only to make a "call" to the termcap label "cl" to invoke the correct clear screen command. The program doesn't actually care which terminal is logged in, it just knows to call "cl" when it wants to clear the screen. The termcap that gets called from the program depends upon the "TERM=" variable which is set when a user logs in to the system. TERM directly associates the Terminal type to the termcap, among other things. When working with attributes (and ultimately, colors) in the WY-325 terminal, we must now look at the mechanics and definitions of the labels in the termcap. Here are the eight attributes which can be included in the WY-325 termcap and how they should be set up: Termcap Label Description WY325 Definition Code ------------- --------------- ---------------- ------- so Begin Standout Undln/Dim/Rev \EG| se End Standout Normal \EG0 us Begin Underline Underline \EG8 ue End Underline Normal \EG0 mr Reverse On Reverse \EG4 mb Blink On Undln/Rev \EG< md Bold On Dim/Reverse \EGt mh Dim On Dim \EGp mk Blank On Undln/Dim \EGx me Attributes Off Normal \EG0 The line from the termcap (for attributes) would then look like: :so=\EG|:se=\EG0:us=\EG8:ue=\EG0:mr=\EG4:mb=\EG< etc.... Finally, we need to take a look at the mechanics that a typical application program would utilize in calling a termcap and invoking the codes associated with the command "label". The WY-325 color commands are specifically addressed in the following example code: (Note that this is not intended to be an exercise in c programming, but is presented here to show the interaction of the program with the termcap.) /* Program Sample # include /* Declare Pointer Variables static char *IS, *CL, *ME, *MR, *MD; /* these are: Initialize String (*IS) Clear Screen (*CL) Attributes OFF (*ME) Reverse ON (*MR) Bold ON (*MD) static char *ptr; static char *tv_stype; extern char *tgetstr(); extern void tputs(); /* Subroutine to "read" the requested "labels" from termcap buffer static char * qgetstr(ref) char *ref { register char *tmp; if ((tmp = fgetstr(ref,&ptr)) == NULL) { printf("/etc/termcap terminal %s must have a %s= entry\n", tv_stype,ref); } return(tmp); } /* Subroutine to open the termcap and read into 1024 Byte Buffer /* this will speed up the "lookup" process if it's loaded into mem static void tcapopen() { extern char *getenv(),*realloc(); char *tcapbuf; char tcbuf[1024]; if ((tv_stype = getenv("TERM")) == NULL) { printf("TERM type not defined\n"): exit(1); } if ((tgetent(tcbuf,tv_stype) != 1) { printf("Terminal type not in termcap\n"); exit(1); } if ((ptr = tcapbub = malloc(1024)) == NULL) { printf("Out of memory space\n"); exit(1); } /* get the needed "labels from the buffer. IS = qgetstr("is"); /* Get the initialize string CL = qgetstr("cl"); /* Get the clear screen command ME = qgetstr("me"); /* Get the attribute off command MR = qgetstr("mr"); /* Get the Reverse ON command MD = qgetstr("md"); /* Get the Bold ON command } /* Subroutines to send the label's command to terminal static void ttputc(c) { fputc(c,stdout); } void putpad(str) char *str { tputs(str,1,ttputc); } main() { tcapopen(); /* open the termcap putpad(IS); /* send the initialize string putpad(MR); /* start reverse attribute printf("This is in reverse attribute mode/n"); putpad(ME); /* turn off the attribute putpad(MD); /* start bold attribute printf("This is in bold attribute mode\n"); putpad(ME); /* turn off the attribute } The last eight lines of the sample program ( main() ) is a very short example, illustrating how the labels in a termcap are called from a program. This may seem like a long, drawn-out explanation of how to get colors on the WY-325, but the descriptions have covered many areas which, by themselves, would be useful to understand. They collectively will generate the desired colors. To summarize the steps necessary for color/attributes, the following are required in this process: 1) Insure termcap definitions have the necessary "labels" with the proper commands for attributes. (e.g. :mr=\EG4 etc.) 2) Send the terminal the commands to associate the desired colors with the attributes. (e.g. \Edy572 [red on yellow = reverse]) 3) The application program has to call the attribute. Once a particular attribute is called, the colors will affect new text on the screen until the attribute is turned off by the program. =-=-=-=-=-=-=-=-=-=-=-=-= DISCLAIMER =-=-=-=-=-=-=-=-=-=-=-=-=-=-= This information is intended to inform WYSE personnel and WYSE customers of certain issues in a timely fashion. The information has not been extensively verified or tested. WYSE does not warrant the information to be correct, although reasonable effort has been taken to prevent gross inaccuracies. WYSE publishes formal technical communiques in the form of Product Bulletins and warrants the data in Product Bulletins to be accurate at the time of the release. DRL/WY325TCP.WIT