• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2009 Erwan Velu - All Rights Reserved
4  *
5  *   Permission is hereby granted, free of charge, to any person
6  *   obtaining a copy of this software and associated documentation
7  *   files (the "Software"), to deal in the Software without
8  *   restriction, including without limitation the rights to use,
9  *   copy, modify, merge, publish, distribute, sublicense, and/or
10  *   sell copies of the Software, and to permit persons to whom
11  *   the Software is furnished to do so, subject to the following
12  *   conditions:
13  *
14  *   The above copyright notice and this permission notice shall
15  *   be included in all copies or substantial portions of the Software.
16  *
17  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19  *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21  *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  *   OTHER DEALINGS IN THE SOFTWARE.
25  *
26  * -----------------------------------------------------------------------
27  *  Ansi Sequences can be found here :
28  *  http://ascii-table.com/ansi-escape-sequences-vt-100.php
29  *  http://en.wikipedia.org/wiki/ANSI_escape_code
30  */
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdbool.h>
36 #include <stdint.h>
37 
38 #include "libansi.h"
39 
display_cursor(bool status)40 void display_cursor(bool status)
41 {
42 	if (status == true) {
43 		fputs(CSI "?25h", stdout);
44 	} else {
45 		fputs(CSI "?25l", stdout);
46 	}
47 }
48 
clear_end_of_line(void)49 void clear_end_of_line(void)
50 {
51 	fputs(CSI "0K", stdout);
52 }
53 
move_cursor_left(int count)54 void move_cursor_left(int count)
55 {
56 	char buffer[10];
57 	memset(buffer,0,sizeof(buffer));
58 	sprintf(buffer,CSI "%dD",count);
59 	fputs(buffer, stdout);
60 }
61 
move_cursor_right(int count)62 void move_cursor_right(int count)
63 {
64 	char buffer[10];
65 	memset(buffer,0,sizeof(buffer));
66 	sprintf(buffer, CSI "%dC", count);
67 	fputs(buffer, stdout);
68 }
69 
set_cursor_blink(bool status)70 void set_cursor_blink(bool status) {
71 	if (status == true)
72 		fputs("\033[05m",stdout);
73 	else
74 		fputs("\033[0m",stdout);
75 }
76 
clear_line(void)77 void clear_line(void)
78 {
79 	fputs(CSI "2K", stdout);
80 }
81 
clear_beginning_of_line(void)82 void clear_beginning_of_line(void)
83 {
84 	fputs(CSI "1K", stdout);
85 }
86 
move_cursor_to_column(int count)87 void move_cursor_to_column(int count)
88 {
89 	char buffer[10];
90         memset(buffer,0,sizeof(buffer));
91 	sprintf(buffer, CSI "%dG", count);
92 	fputs(buffer, stdout);
93 }
94 
move_cursor_to_next_line(void)95 void move_cursor_to_next_line(void)
96 {
97 	fputs("\033e", stdout);
98 }
99 
disable_utf8(void)100 void disable_utf8(void)
101 {
102 	fputs("\033%@", stdout);
103 }
104 
set_g1_special_char(void)105 void set_g1_special_char(void){
106 	fputs("\033)0", stdout);
107 }
108 
set_us_g0_charset(void)109 void set_us_g0_charset(void)
110 {
111 	fputs("\033(B\1#0", stdout);
112 }
113 
clear_entire_screen(void)114 void clear_entire_screen(void)
115 {
116 	fputs(CSI "2J", stdout);
117 }
118 
119 /**
120  * cprint_vga2ansi - given a VGA attribute, print a character
121  * @chr:	character to print
122  * @attr:	vga attribute
123  *
124  * Convert the VGA attribute @attr to an ANSI escape sequence and
125  * print it.
126  * For performance, SGR parameters are cached. To reset them,
127  * call cprint_vga2ansi('0', '0').
128  **/
cprint_vga2ansi(const char chr,const char attr)129 static void cprint_vga2ansi(const char chr, const char attr)
130 {
131 	static const char ansi_char[8] = "04261537";
132 	static uint16_t last_attr = 0x300;
133 	char buf[16], *p;
134 
135     if (chr == '0' && attr == '0') {
136         last_attr = 0x300;
137         return;
138     }
139 
140 	if (attr != last_attr) {
141         bool reset = false;
142 		p = buf;
143 		*p++ = '\033';
144 		*p++ = '[';
145 
146 		if (last_attr & ~attr & 0x88) {
147 			*p++ = '0';
148 			*p++ = ';';
149 			/* Reset last_attr to unknown to handle
150 			 * background/foreground attributes correctly */
151 			last_attr = 0x300;
152             reset = true;
153 		}
154 		if (attr & 0x08) {
155 			*p++ = '1';
156 			*p++ = ';';
157 		}
158 		if (attr & 0x80) {
159 			*p++ = '4';
160 			*p++ = ';';
161 		}
162 		if (reset || (attr ^ last_attr) & 0x07) {
163 			*p++ = '3';
164 			*p++ = ansi_char[attr & 7];
165 			*p++ = ';';
166 		}
167 		if (reset || (attr ^ last_attr) & 0x70) {
168 			*p++ = '4';
169 			*p++ = ansi_char[(attr >> 4) & 7];
170 			*p++ = ';';
171 		}
172 		p[-1] = 'm';	/* We'll have generated at least one semicolon */
173 		p[0] = '\0';
174 
175 		last_attr = attr;
176 
177 		fputs(buf, stdout);
178 	}
179 
180 	putchar(chr);
181 }
182 
183 /*
184  * cls - clear and initialize the entire screen
185  *
186  * Note: when initializing xterm, one has to specify that
187  * G1 points to the alternate character set (this is not true
188  * by default). Without the initial printf "\033)0", line drawing
189  * characters won't be displayed.
190  */
cls(void)191 void cls(void)
192 {
193 	fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
194 
195     /* Reset SGR parameters cache */
196     cprint_vga2ansi('0', '0');
197 }
198 
reset_colors(void)199 void reset_colors(void)
200 {
201     csprint(CSI "1D", 0x07);
202 }
203 
204 /**
205  * cprint - given a VGA attribute, print a single character at cursor
206  * @chr:	character to print
207  * @attr:	VGA attribute
208  * @times:	number of times to print @chr
209  *
210  * Note: @attr is a VGA attribute.
211  **/
cprint(const char chr,const char attr,unsigned int times)212 void cprint(const char chr, const char attr, unsigned int times)
213 {
214 	while (times--)
215 		cprint_vga2ansi(chr, attr);
216 }
217 
218 /**
219  * csprint - given a VGA attribute, print a NULL-terminated string
220  * @str:	string to print
221  * @attr:	VGA attribute
222  **/
csprint(const char * str,const char attr)223 void csprint(const char *str, const char attr)
224 {
225 	while (*str) {
226 		cprint(*str, attr, 1);
227 		str++;
228 	}
229 }
230 
231 /**
232  * clearwindow - fill a given a region on the screen
233  * @top, @left, @bot, @right:	coordinates to fill
234  * @fillchar:			character to use to fill the region
235  * @fillattr:			character attribute (VGA)
236  **/
clearwindow(const char top,const char left,const char bot,const char right,const char fillchar,const char fillattr)237 void clearwindow(const char top, const char left, const char bot,
238 		 const char right, const char fillchar, const char fillattr)
239 {
240 	char x;
241 	for (x = top; x < bot + 1; x++) {
242 		gotoxy(x, left);
243 		cprint(fillchar, fillattr, right - left + 1);
244 	}
245 }
246 
247 
248