File: padala.html

package info (click to toggle)
lg-issue65 1-6
  • links: PTS
  • area: main
  • in suites: woody
  • size: 3,776 kB
  • ctags: 230
  • sloc: sh: 171; perl: 133; makefile: 36
file content (364 lines) | stat: -rw-r--r-- 12,740 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>So You Like Color !!!  (The mysterious ^[[ characters) LG #65</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->

<CENTER>
<A HREF="http://www.linuxgazette.com/">
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png" 
	WIDTH="600" HEIGHT="124" border="0"></H1></A> 

<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="okopnik.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc65.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue65/padala.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="puryear.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>

<!--endcut ============================================================-->

<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">So You Like Color !!!<BR>
(The mysterious ^[[ characters)</font></H1>
<H4>By <a href="mailto:p_padala@yahoo.com">Pradeep Padala</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




Have you ever redirected the output of a curses program with colors and wondered
what those mysterious ^[[ are? Did you
ever try to produce colors with a printf without using curses? If the 
answer to either of these questions is yes, read on... 
</P>
This article attempts to explain those mysterious characters that one finds in 
the output of a curses program which produces colors. Later on, we extend
the concept to produce colors with a mere printf.

</P>
<H3> Terminal Codes </H3> 
<P>
In the olden days of teletype terminals, terminals were away from 
computers and were connected to them through serial cables. The terminals could
be configured by sending a series of bytes to each of them. All the capabilities of
terminals could be accessed through these series of bytes which are usually called escape
sequences because they start with an escape(0x1B) character. Even today with vt100
emulation, we can send escape sequences to the emulator and it will have the
same effect on the terminal window.  Hence, in order to print
color, we merely echo a control code.
</P>
Type this on your console.
<PRE>
	echo "^[[0;31;40mIn Color"
</PRE>
<P>
The first character is an escape character, which looks like two characters
^ and [. To be able to print that you have to press CTRL+V and then the ESC key. All the others are
normal printable characters.
You see the string "In Color" in red. It stays that way and to revert back type
this
</P>
<PRE>
	echo "^[[0;37;40m"
</PRE>
<P>
As you can see it's pretty easy to set color and reset it back. There are 
a myriad of escape sequences with which you can do a lot of things like moving
the cursor, resetting the terminal etc..
</P>
<H3> The Color Code: &nbsp;&nbsp;&nbsp;&nbsp;&lt;ESC&gt;[{attr};{fg};{bg}m </H3>
<P>
I'll explain the escape sequence to produce colors. The sequence to be printed
or echoed to the terminal is 
<PRE>
	&lt;ESC&gt;[{attr};{fg};{bg}m
</PRE>
<P>
The first character is ESC which has to be printed by pressing CTRL+V and then 
ESC on the Linux console or in xterm, konsole, kvt, etc.  ("CTRL+V ESC" is also
the way to embed an escape character in a document in vim.)  Then {attr}, {fg},
{bg} have to be replaced with the correct value to get the corresponding
effect. attr is the attribute like blinking or underlined etc.. fg and bg are
foreground and background colors
respectively. You don't have to put braces around the number. Just writing the  
number will suffice. 
</P>
<P>
{attr} is one of following
<PRE>
	0	Reset All Attributes (return to normal mode)
	1	Bright (Usually turns on BOLD)
	2 	Dim
	3	Underline
	5	Blink
	7 	Reverse
	8	Hidden
</PRE>
{fg} is one of the following
<PRE>
	30	Black
	31	Red
	32	Green
	33	Yellow
	34	Blue
	35	Magenta
	36	Cyan
	37	White
</PRE>
{bg} is one of the following
<PRE>
	40	Black
	41	Red
	42	Green
	43	Yellow
	44	Blue
	45	Magenta
	46	Cyan
	47	White
</PRE>
<P>
So to get a blinking line with Blue foreground and Green background, the combination to be used should
be
<PRE>	
echo "^[[5;34;42mIn color"
</PRE>
which actually is very ugly. :-)  Revert back with 
<PRE>
echo "^[0;37;40m"
</PRE>


<H3> With printf() </H3>
<P>
What if you want to use this functionality in a C program? Simple! Before you printf
something print this escape sequence to produce it in the desired color. I 
have written a small routine <CODE>textcolor()</CODE> which does this 
automatically. You can use it in your programs along with the #define constants. 
The text version of this program is <A HREF=misc/padala/color.c.txt> here </A>
</P>
<H3><CODE>textcolor()</CODE> </H3>
<TABLE BGCOLOR="#C5C5C5" WIDTH=450>
<TR> <TD>
<PRE>
#include &lt;stdio.h&gt;

#define RESET		0
#define BRIGHT 		1
#define DIM		2
#define UNDERLINE 	3
#define BLINK		4
#define REVERSE		7
#define HIDDEN		8

#define BLACK 		0
#define RED		1
#define GREEN		2
#define YELLOW		3
#define BLUE		4
#define MAGENTA		5
#define CYAN		6
#define	WHITE		7

void textcolor(int attr, int fg, int bg);
int main()
{	textcolor(BRIGHT, RED, BLACK);	
	printf("In color\n");
	textcolor(RESET, WHITE, BLACK);	
	return 0;
}

void textcolor(int attr, int fg, int bg)
{	char command[13];

	/* Command is the control command to the terminal */
	sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
	printf("%s", command);
}
</PRE>
</TD>
</TABLE>
<P>
The <CODE>textcolor()</CODE> is modeled against the Turbo C API function. You 
call the function to set the color and then print with a <CODE>sprintf()</CODE>
(a function used in Turbo C to produce console output in color). 
</P>
<H3> A Demo of colors</H3>
<TABLE BGCOLOR="#C5C5C5" WIDTH=450>
<TR> <TD>
<PRE>
#include &lt;stdio.h&gt;

#define RESET		0
#define BRIGHT 		1
#define DIM		2
#define UNDERLINE 	3
#define BLINK		4
#define REVERSE		7
#define HIDDEN		8

#define BLACK 		0
#define RED		1
#define GREEN		2
#define YELLOW		3
#define BLUE		4
#define MAGENTA		5
#define CYAN		6
#define	WHITE		7

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

char *attrs[] = {"NORMAL", "BRIGHT", "DIM", "UNDERLINE", "BLINK",
		 "REVERSE", "HIDDEN", "EXIT"};
char *colors[] = {"BLACK", "RED", "GREEN", "YELLOW", "BLUE", "MAGENTA",
		 "CYAN", "WHITE", "EXIT"};
void textcolor(int attr, int fg, int bg);
int print_menu(char *array[], int n_options, char *title);
int main()
{	int attr, fg, bg;
	int attr_size, colors_size;
	
	attr_size = ARRAY_SIZE(attrs);
	colors_size = ARRAY_SIZE(colors);
	while(1)
	{	printf("\n");
		attr = print_menu(attrs, attr_size, "Choose the attr you want:");
		if(attr == attr_size - 1)
			break;
		fg = print_menu(colors, colors_size, "Choose the foreground you want:");
		if(attr == colors_size - 1)
			break;
		bg = print_menu(colors, colors_size, "Choose the background you want:");
		if(attr == colors_size - 1)
			break;
		printf("\n");
		textcolor(attr, fg, bg);	
		printf("This is what you get if you use the combination %s attribute %s foreground and %s
 background", attrs[attr], colors[fg], colors[bg]);
		textcolor(RESET, WHITE, BLACK);
		system("clear");
	}
	return 0;
}

int print_menu(char *array[], int n_options, char *title)
{	int choice, i;
	for(i = 0;i &lt; n_options; ++i)
		printf("%d.%s\n", i, array[i]);
	printf("%s", title);
	scanf("%d", &amp;choice);
	return choice;
}		
void textcolor(int attr, int fg, int bg)
{	char command[13];

	/* Command is the control command to the terminal */
	sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
	printf("%s", command);
}
</PRE>
</TD>
</TABLE>
<P> This program asks the user to play with attributes and colors and shows 
a string in that color. I usually use it to find out the best combination
of colors for my GUIs. Text version of above program is <A HREF=misc/padala/demo.c.txt> here </A>.
</P>
<H3> The Catch </H3>
<P>
Then what's the catch? If producing color is so easy, why do people waste their
time
writing huge programs in curses, which in turn query terminfo in a
complex way? As we know, there are many terminals with very few capabilities
and terminals which don't recognize these escape codes or need different codes
to achieve the same effect. So if you want a portable program which would run
on any terminal with the same (or reduced) functionality, you should use
curses. Curses uses terminfo to find the correct codes to
accomplish the task in style. Terminfo is a big database
which contains information about the various functionalities of different
terminals.
</P>
<P>
But if you just want to write a simple program which produces color on a Linux 
console or xterm window, you can just use the escape sequences above to do
it easily. The Linux console mostly emulates vt100, so it recognizes these
escape sequences. 
</P>
<H3> With tput </H3>
<P>
But there is a way to query the terminfo database and do the work. tput is the
command which queries the database and executes the functionality you specify.
The two capabilities setf and setb are useful to set foreground and background
colors. Use this to set foreground color to red and background color to green.
</P>
<PRE>
	tput setf 4	# tput setf {fg color number}
	tput setb 2	# tput setb {bg color number}
</PRE>
<P>
This can be used in shell scripts where you want. See the tput manual page for
additional capabilities of tput.
The terminfo manpages contain a lot of information
regarding terminal capabilities - how to get and set their values and
more.  There are two terminfo manpages.  "man 5 terminfo" describes
the terminfo database.  
"man 3ncurses terminfo" describes the C functions that use the database.

<P> These are the color numbers to be passed as arguments to "tput setf" and
"tput setb".
</P>
<PRE>
	0	Black
	1	Red
	2	Green
	3	Yellow
	4	Blue
	5	Magenta
	6	Cyan
	7	White
</PRE>
<P>
Have fun !!!
</P>

<H3> References </H3>
<UL>
<LI>The <A HREF=http://www.linuxdoc.org/HOWTO/Text-Terminal-HOWTO.html>
	Text-Terminal-HOWTO </A> </LI>
<LI>Man pages for <A HREF=http://linux.ctyme.com/man/man2488.htm>tput</A> 
and <A HREF=http://linux.ctyme.com/man/man2346.htm> terminfo<A>. </LI>
</UL>




<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P --> 
<H5 ALIGN=center>

Copyright &copy; 2001, Pradeep Padala.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR> 
Published in Issue 65 of <i>Linux Gazette</i>, April 2001</H5>
<!-- *** END copyright *** -->

<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="okopnik.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc65.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue65/padala.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="puryear.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->