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