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 * 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 * 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 * 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 * 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 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 227 ti_clear_screen (void) 228 { 229 grub_putstr (grub_tparm (term.clear_screen)); 230 } 231 232 /* enter reverse video */ 233 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 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 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 255 ti_get_term(struct terminfo *copy) 256 { 257 grub_memmove (copy, &term, sizeof (struct terminfo)); 258 } 259