1 /* terminfo.c - read a terminfo entry from the command line */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2004 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * ######################################################################
21 *
22 * This file contains various functions dealing with different
23 * terminal capabilities. It knows the difference between a vt52 and vt100
24 * terminal (and much more) and is mainly used the terminal emulation
25 * in the serial driver.
26 */
27
28 #include <shared.h>
29 #include "terminfo.h"
30 #include "tparm.h"
31 #include "serial.h"
32
33 /* Current terminal capabilities. Default is "vt100". */
34 struct terminfo term =
35 {
36 .name = "vt100",
37 .cursor_address = "\e[%i%p1%d;%p2%dH",
38 .clear_screen = "\e[H\e[J",
39 .enter_standout_mode = "\e[7m",
40 .exit_standout_mode = "\e[m"
41 };
42
43 /* A number of escape sequences are provided in the string valued
44 capabilities for easy encoding of characters there. Both \E and \e
45 map to an ESCAPE character, ^x maps to a control-x for any
46 appropriate x, and the sequences \n \l \r \t \b \f \s give a
47 newline, line-feed, return, tab, backspace, form-feed, and space.
48 Other escapes include \^ for ^, \\ for \, \, for comma, \: for :,
49 and \0 for null. (\0 will produce \200, which does not terminate a
50 string but behaves as a null character on most terminals, provid�
51 ing CS7 is specified. See stty(1).) Finally, characters may be
52 given as three octal digits after a \. */
53
54 char *
ti_unescape_memory(const char * in,const char * end)55 ti_unescape_memory (const char *in, const char *end)
56 {
57 static char out_buffer[256];
58 char c;
59 char *out;
60
61 out = out_buffer;
62 do
63 {
64 c = *(in++);
65 switch (c)
66 {
67 case '^':
68 if (*in >= 'A' && *in <= 'Z')
69 {
70 *out = (*in) - 'A';
71 in++;
72 }
73 else
74 {
75 *out = '^';
76 }
77 break;
78 case '\\':
79 c = *(in++);
80 if (c >= '0' && c <= '9')
81 {
82 // octal number
83 int n = 0;
84 do
85 {
86 n = (n << 4) | (c - '0');
87 c = *(in++);
88 }
89 while (c >= '0' && c <= '9');
90
91 *out++ = (char)(n & 0xff);
92
93 // redo last character
94 in--;
95
96 break;
97 }
98
99 switch (c)
100 {
101 case 'e':
102 case 'E':
103 *out++ = '\e';
104 break;
105 case 'n':
106 *out++ = '\n';
107 break;
108 case 'r':
109 *out++ = '\r';
110 break;
111 case 't':
112 *out++ = '\t';
113 break;
114 case 'b':
115 *out++ = '\b';
116 break;
117 case 'f':
118 *out++ = '\f';
119 break;
120 case 's':
121 *out++ = ' ';
122 break;
123 case '\\':
124 *out++ = '\\';
125 break;
126 case '^':
127 *out++ = '^';
128 break;
129 case ',':
130 *out++ = ',';
131 break;
132 case ':':
133 *out++ = ':';
134 break;
135 case '0':
136 *out++ = '\200';
137 break;
138 }
139 break;
140 default:
141 *out++ = c;
142 break;
143 }
144 }
145 while (in <= end);
146
147 return out_buffer;
148 }
149
150 char *
ti_unescape_string(const char * in)151 ti_unescape_string (const char *in)
152 {
153 return ti_unescape_memory (in, in + grub_strlen (in));
154 }
155
156 /* convert a memory region containing binary character into an external
157 * ascii representation. The binary characters will be replaced by an
158 * "ecsape notation". E.g. "033" will become "\e". */
159 char *
ti_escape_memory(const char * in,const char * end)160 ti_escape_memory (const char *in, const char *end)
161 {
162 static char out_buffer[256];
163 char c;
164 char *out;
165
166 out = out_buffer;
167 do
168 {
169 c = *(in++);
170 switch (c)
171 {
172 case '\e':
173 *out++ = '\\'; *out++ = 'e'; break;
174 case ' ':
175 *out++ = '\\'; *out++ = 's'; break;
176 case '\\':
177 *out++ = '\\'; *out++ = '\\'; break;
178 case '0' ... '9':
179 case 'a' ... 'z':
180 case 'A' ... 'Z':
181 case '%':
182 case '+':
183 case '-':
184 case '*':
185 case '/':
186 case ';':
187 case ':':
188 case '{':
189 case '}':
190 case '[':
191 case ']':
192 *out++ = c; break;
193 case 0 ... 25:
194 *out++ = '^'; *out++ = 'A' + c; break;
195 default:
196 *out++ = '\\';
197 *out++ = ((c >> 8) & 7) + '0';
198 *out++ = ((c >> 4) & 7) + '0';
199 *out++ = ((c >> 0) & 7) + '0';
200 break;
201 }
202 }
203 while (in < end);
204
205 *out++ = 0;
206
207 return out_buffer;
208 }
209
210 /* convert a string containing binary character into an external ascii
211 * representation. */
212 char *
ti_escape_string(const char * in)213 ti_escape_string (const char *in)
214 {
215 return ti_escape_memory (in, in + grub_strlen (in));
216 }
217
218 /* move the cursor to the given position starting with "0". */
219 void
ti_cursor_address(int x,int y)220 ti_cursor_address (int x, int y)
221 {
222 grub_putstr (grub_tparm (term.cursor_address, y, x));
223 }
224
225 /* clear the screen. */
226 void
ti_clear_screen(void)227 ti_clear_screen (void)
228 {
229 grub_putstr (grub_tparm (term.clear_screen));
230 }
231
232 /* enter reverse video */
233 void
ti_enter_standout_mode(void)234 ti_enter_standout_mode (void)
235 {
236 grub_putstr (grub_tparm (term.enter_standout_mode));
237 }
238
239 /* exit reverse video */
240 void
ti_exit_standout_mode(void)241 ti_exit_standout_mode (void)
242 {
243 grub_putstr (grub_tparm (term.exit_standout_mode));
244 }
245
246 /* set the current terminal emulation to use */
247 void
ti_set_term(const struct terminfo * new)248 ti_set_term (const struct terminfo *new)
249 {
250 grub_memmove (&term, new, sizeof (struct terminfo));
251 }
252
253 /* get the current terminal emulation */
254 void
ti_get_term(struct terminfo * copy)255 ti_get_term(struct terminfo *copy)
256 {
257 grub_memmove (copy, &term, sizeof (struct terminfo));
258 }
259