mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-22 15:22:39 +00:00
* stage2/terminfo.c (ti_set_term): Use a pointer to struct terminfo instead to avoid GCC's bug, which inserts a reference to memcpy implicitly. (ti_get_term): Likewise. All callers are fixed. * stage2/terminfo.h (ti_set_term): Updated. (ti_get_term): Likewise. * stage2/shared.h (struct linux_kernel_header): New member, initrd_max_address. Defined in the boot protocol 2.03 or higher. * stage2/boot.c (load_initrd): If the boot protocol is greater than or equal to 2.03, use the field ``initrd_max_address'' instead of LINUX_INITRD_MAX_ADDRESS.
259 lines
5.6 KiB
C
259 lines
5.6 KiB
C
/* terminfo.c - read a terminfo entry from the command line */
|
||
/*
|
||
* GRUB -- GRand Unified Bootloader
|
||
* Copyright (C) 2002,2004 Free Software Foundation, Inc.
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
*
|
||
* ######################################################################
|
||
*
|
||
* This file contains various functions dealing with different
|
||
* terminal capabilities. It knows the difference between a vt52 and vt100
|
||
* terminal (and much more) and is mainly used the terminal emulation
|
||
* in the serial driver.
|
||
*/
|
||
|
||
#include <shared.h>
|
||
#include "terminfo.h"
|
||
#include "tparm.h"
|
||
#include "serial.h"
|
||
|
||
/* Current terminal capabilities. Default is "vt100". */
|
||
struct terminfo term =
|
||
{
|
||
.name = "vt100",
|
||
.cursor_address = "\e[%i%p1%d;%p2%dH",
|
||
.clear_screen = "\e[H\e[J",
|
||
.enter_standout_mode = "\e[7m",
|
||
.exit_standout_mode = "\e[m"
|
||
};
|
||
|
||
/* A number of escape sequences are provided in the string valued
|
||
capabilities for easy encoding of characters there. Both \E and \e
|
||
map to an ESCAPE character, ^x maps to a control-x for any
|
||
appropriate x, and the sequences \n \l \r \t \b \f \s give a
|
||
newline, line-feed, return, tab, backspace, form-feed, and space.
|
||
Other escapes include \^ for ^, \\ for \, \, for comma, \: for :,
|
||
and \0 for null. (\0 will produce \200, which does not terminate a
|
||
string but behaves as a null character on most terminals, provid
|
||
ing CS7 is specified. See stty(1).) Finally, characters may be
|
||
given as three octal digits after a \. */
|
||
|
||
char *
|
||
ti_unescape_memory (const char *in, const char *end)
|
||
{
|
||
static char out_buffer[256];
|
||
char c;
|
||
char *out;
|
||
|
||
out = out_buffer;
|
||
do
|
||
{
|
||
c = *(in++);
|
||
switch (c)
|
||
{
|
||
case '^':
|
||
if (*in >= 'A' && *in <= 'Z')
|
||
{
|
||
*out = (*in) - 'A';
|
||
in++;
|
||
}
|
||
else
|
||
{
|
||
*out = '^';
|
||
}
|
||
break;
|
||
case '\\':
|
||
c = *(in++);
|
||
if (c >= '0' && c <= '9')
|
||
{
|
||
// octal number
|
||
int n = 0;
|
||
do
|
||
{
|
||
n = (n << 4) | (c - '0');
|
||
c = *(in++);
|
||
}
|
||
while (c >= '0' && c <= '9');
|
||
|
||
*out++ = (char)(n & 0xff);
|
||
|
||
// redo last character
|
||
in--;
|
||
|
||
break;
|
||
}
|
||
|
||
switch (c)
|
||
{
|
||
case 'e':
|
||
case 'E':
|
||
*out++ = '\e';
|
||
break;
|
||
case 'n':
|
||
*out++ = '\n';
|
||
break;
|
||
case 'r':
|
||
*out++ = '\r';
|
||
break;
|
||
case 't':
|
||
*out++ = '\t';
|
||
break;
|
||
case 'b':
|
||
*out++ = '\b';
|
||
break;
|
||
case 'f':
|
||
*out++ = '\f';
|
||
break;
|
||
case 's':
|
||
*out++ = ' ';
|
||
break;
|
||
case '\\':
|
||
*out++ = '\\';
|
||
break;
|
||
case '^':
|
||
*out++ = '^';
|
||
break;
|
||
case ',':
|
||
*out++ = ',';
|
||
break;
|
||
case ':':
|
||
*out++ = ':';
|
||
break;
|
||
case '0':
|
||
*out++ = '\200';
|
||
break;
|
||
}
|
||
break;
|
||
default:
|
||
*out++ = c;
|
||
break;
|
||
}
|
||
}
|
||
while (in <= end);
|
||
|
||
return out_buffer;
|
||
}
|
||
|
||
char *
|
||
ti_unescape_string (const char *in)
|
||
{
|
||
return ti_unescape_memory (in, in + grub_strlen (in));
|
||
}
|
||
|
||
/* convert a memory region containing binary character into an external
|
||
* ascii representation. The binary characters will be replaced by an
|
||
* "ecsape notation". E.g. "033" will become "\e". */
|
||
char *
|
||
ti_escape_memory (const char *in, const char *end)
|
||
{
|
||
static char out_buffer[256];
|
||
char c;
|
||
char *out;
|
||
|
||
out = out_buffer;
|
||
do
|
||
{
|
||
c = *(in++);
|
||
switch (c)
|
||
{
|
||
case '\e':
|
||
*out++ = '\\'; *out++ = 'e'; break;
|
||
case ' ':
|
||
*out++ = '\\'; *out++ = 's'; break;
|
||
case '\\':
|
||
*out++ = '\\'; *out++ = '\\'; break;
|
||
case '0' ... '9':
|
||
case 'a' ... 'z':
|
||
case 'A' ... 'Z':
|
||
case '%':
|
||
case '+':
|
||
case '-':
|
||
case '*':
|
||
case '/':
|
||
case ';':
|
||
case ':':
|
||
case '{':
|
||
case '}':
|
||
case '[':
|
||
case ']':
|
||
*out++ = c; break;
|
||
case 0 ... 25:
|
||
*out++ = '^'; *out++ = 'A' + c; break;
|
||
default:
|
||
*out++ = '\\';
|
||
*out++ = ((c >> 8) & 7) + '0';
|
||
*out++ = ((c >> 4) & 7) + '0';
|
||
*out++ = ((c >> 0) & 7) + '0';
|
||
break;
|
||
}
|
||
}
|
||
while (in < end);
|
||
|
||
*out++ = 0;
|
||
|
||
return out_buffer;
|
||
}
|
||
|
||
/* convert a string containing binary character into an external ascii
|
||
* representation. */
|
||
char *
|
||
ti_escape_string (const char *in)
|
||
{
|
||
return ti_escape_memory (in, in + grub_strlen (in));
|
||
}
|
||
|
||
/* move the cursor to the given position starting with "0". */
|
||
void
|
||
ti_cursor_address (int x, int y)
|
||
{
|
||
grub_putstr (grub_tparm (term.cursor_address, y, x));
|
||
}
|
||
|
||
/* clear the screen. */
|
||
void
|
||
ti_clear_screen (void)
|
||
{
|
||
grub_putstr (grub_tparm (term.clear_screen));
|
||
}
|
||
|
||
/* enter reverse video */
|
||
void
|
||
ti_enter_standout_mode (void)
|
||
{
|
||
grub_putstr (grub_tparm (term.enter_standout_mode));
|
||
}
|
||
|
||
/* exit reverse video */
|
||
void
|
||
ti_exit_standout_mode (void)
|
||
{
|
||
grub_putstr (grub_tparm (term.exit_standout_mode));
|
||
}
|
||
|
||
/* set the current terminal emulation to use */
|
||
void
|
||
ti_set_term (const struct terminfo *new)
|
||
{
|
||
grub_memmove (&term, new, sizeof (struct terminfo));
|
||
}
|
||
|
||
/* get the current terminal emulation */
|
||
void
|
||
ti_get_term(struct terminfo *copy)
|
||
{
|
||
grub_memmove (copy, &term, sizeof (struct terminfo));
|
||
}
|