• 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