2002-06-12 Yoshinori K. Okuji <okuji@enbug.org>

The terminal handling code is rewritten radically.

	* stage2/console.c: New file.
	* stage2/term.h: Likewise.

	* stage2/Makefile.am (noinst_HEADERS): Added term.h.
	(libgrub_a_SOURCES): Added serial.c.
	(pre_stage2_exec_SOURCES): Added console.c.

	* stage2/asm.S (console_putchar): Rewritten from scratch.
	[!STAGE1_5] (translation_table): New variable.
	[!STAGE1_5] (translate_keycode): New function.
	[!STAGE1_5] (console_getkey): Call translate_keycode.
	[!STAGE1_5] (console_checkkey): Likewise.
	[!STAGE1_5] (nocursor): Renamed to ...
	[!STAGE1_5] (console_nocursor): ... this.
	[!STAGE1_5] (console_set_attrib): Removed.

	* stage2/builtins.c: Include term.h.
	(terminal): Removed.
	(normal_color): Likewise.
	(highlight_color): Likewise.
	(cat_func): Display a question mark when a non-printable
	character was read.
	(terminal_func): Rewritten almost from scratch.

	* stage2/char_io.c: Include term.h.
	[!STAGE1_5] (auto_fill): Removed.
	[!STAGE1_5] (term_table): New variable.
	[!STAGE1_5] (current_term): Likewise.
	[!STAGE1_5] (real_get_cmdline): New function. The code was
	stolen from the previous version of get_cmdline.
	[!STAGE1_5] (get_cmdline): Rewritten from scratch.
	[!STAGE1_5] (translate_keycode): Removed.
	[!STAGE1_5] (getkey): Rewritten from scratch.
	[!STAGE1_5] (checkkey): Likewise.
	(grub_putchar): Likewise.
	[!STAGE1_5] (gotoxy): Likewise.
	[!STAGE1_5] (getxy): Likewise.
	[!STAGE1_5] (cls): Likewise.
	[!STAGE1_5] (nocursor): New function.
	[SUPPORT_SERIAL] (serial_getxy): Removed.
	[SUPPORT_SERIAL] (serial_gotoxy): Likewise.
	[SUPPORT_SERIAL] (serial_cls): Likewise.
	[SUPPORT_SERIAL] (serial_getxy): Likewise.
	[!STAGE1_5] (set_attrib): Likewise.

	* stage2/cmdline.c (init_cmdline): Set COUNT_LINES to -1.

	* stage2/common.c [!STAGE1_5] (err_list): Removed
	ERR_NEED_SERIAL and added ERR_DEV_NEED_INIT.

	* stage2/hercules.c: Rewritten almost from scratch.
	* stage2/hercules.h (herc_putchar): Removed.
	(herc_cls): Likewise.
	(herc_getxy): Likewise.
	(herc_gotoxy): Likewise.
	(herc_set_attrib): Likewise.

	* stage2/serial.c: Rewritten almost from scratch.
	* stage2/serial.h: Likewise.

	* stage2/shared.h [GRUB_UTIL] (DISP_UL): Set to the same value
	as VGA's.
	[GRUB_UTIL] (DISP_UR): Likewise.
	[GRUB_UTIL] (DISP_LL): Likewise.
	[GRUB_UTIL] (DISP_LR): Likewise.
	[GRUB_UTIL] (DISP_HORIZ): Likewise.
	[GRUB_UTIL] (DISP_VERT): Likewise.
	[GRUB_UTIL] (DISP_LEFT): Likewise.
	[GRUB_UTIL] (DISP_RIGHT): Likewise.
	[GRUB_UTIL] (DISP_UP): Likewise.
	[GRUB_UTIL] (DISP_DOWN): Likewise.
	(grub_error_t): Removed ERR_NEED_SERIAL.
	Added ERR_DEV_NEED_INIT.
	(normal_color): Removed.
	(highlight_color): Likewise.
	(console_cls): Removed, because this is declared in term.h.
	(console_getxy): Likewise.
	(console_gotoxy): Likewise.
	(console_putchar): Likewise.
	(console_getkey): Likewise.
	(console_checkkey): Likewise.
	(console_set_attrib): Removed.
	(set_attrib): Likewise.
	[GRUB_UTIL] (nocursor): Declared.
	(auto_fill): Removed.
	(terminal): Likewise.
	(TERMINAL_CONSOLE): Likewise.
	(TERMINAL_SERIAL): Likewise.
	(TERMINAL_HERCULES): Likewise.
	(TERMINAL_DUMB): Likewise.
	(translate_keycode): Likewise.

	* stage2/stage2.c: Include term.h.
	(print_entry): Rewritten from scratch.
	(print_entries): Likewise.
	(print_border): Likewise.
	(set_line): Removed.
	(set_line_normal): Likewise.
	(set_line_highlight): Likewise.

	* grub/Makefile.am (AM_CFLAGS): Added -DSUPPORT_HERCULES=1.

	* grub/asmstub.c: Don't include hercules.h. Include term.h.
	(console_current_color): New variable.
	(console_translate_key): New function.
	(console_checkkey): Rewritten from scratch.
	(console_getkey): Likewise.
	(console_putchar): Likewise.
	(console_set_attrib): Removed.
	(console_highlight): New function.
	(console_setcolor): Likewise.
	(console_nocursor): Likewise.
	(serial_getkey): Removed.
	(serial_checkkey): Likewise.
	(serial_putchar): Likewise.
	(serial_exists): Likewise.
	(serial_get_port): Likewise.
	(serial_init): Likewise.
	(serial_hw_fetch): New function.
	(serial_hw_put): Likewise.
	(serial_hw_delay): Likewise.
	(serial_hw_get_port): Likewise.
	(serial_hw_init): Likewise.
	(set_serial_device): Renamed to ...
	(serial_set_device): ... this.
	(herc_putchar): Renamed to ...
	(hercules_putchar): ... this.
	(herc_cls): Renamed to ...
	(hercules_cls): ... this.
	(herc_getxy): Renamed to ...
	(hercules_getxy): ... this.
	(herc_gotoxy): Renamed to ...
	(hercules_gotoxy): ... this.
	(hercules_highlight): New function.
	(hercules_setcolor): Likewise.
	(hercules_nocursor): Likewise.
	(herc_set_attrib): Removed.

	* grub/main.c: Include term.h.
	(main): If USE_CURSES is false, set CURRENT_TERM->FLAGS to
	TERM_NO_EDIT | TERM_DUMB. TERMINAL is not used any longer.
This commit is contained in:
okuji committed 2002-06-11 16:36:54 +00:00
1 parent 9ab2360b15
commit 2369202e83
22 files changed
+1626 -1502

No files matched your search

+175 -430
View File
@@ -19,6 +19,7 @@
*/
#include <shared.h>
#include <term.h>
#ifdef SUPPORT_HERCULES
# include <hercules.h>
@@ -29,7 +30,59 @@
#endif
#ifndef STAGE1_5
int auto_fill = 1;
struct term_entry term_table[] =
{
{
"console",
0,
console_putchar,
console_checkkey,
console_getkey,
console_getxy,
console_gotoxy,
console_cls,
console_highlight,
console_setcolor,
console_nocursor
},
#ifdef SUPPORT_SERIAL
{
"serial",
/* A serial device must be initialized. */
TERM_NEED_INIT,
serial_putchar,
serial_checkkey,
serial_getkey,
serial_getxy,
serial_gotoxy,
serial_cls,
serial_highlight,
0,
0
},
#endif /* SUPPORT_SERIAL */
#ifdef SUPPORT_HERCULES
{
"hercules",
0,
hercules_putchar,
console_checkkey,
console_getkey,
hercules_getxy,
hercules_gotoxy,
hercules_cls,
hercules_highlight,
hercules_setcolor,
hercules_nocursor
},
#endif /* SUPPORT_HERCULES */
/* This must be the last entry. */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
/* This must be console. */
struct term_entry *current_term = term_table;
int max_lines = 24;
int count_lines = -1;
int use_pager = 1;
@@ -101,7 +154,7 @@ grub_printf (const char *format,...)
while ((c = *(format++)) != 0)
{
if (c != '%')
putchar (c);
grub_putchar (c);
else
switch (c = *(format++))
{
@@ -120,19 +173,19 @@ grub_printf (const char *format,...)
ptr = str;
while (*ptr)
putchar (*(ptr++));
grub_putchar (*(ptr++));
break;
#ifndef STAGE1_5
case 'c':
putchar ((*(dataptr++)) & 0xff);
grub_putchar ((*(dataptr++)) & 0xff);
break;
case 's':
ptr = (char *) (*(dataptr++));
while ((c = *(ptr++)) != 0)
putchar (c);
grub_putchar (c);
break;
#endif
}
@@ -220,17 +273,9 @@ add_history (const char *cmdline, int no)
num_history++;
}
/* Don't use this with a MAXLEN greater than 1600 or so! The problem
is that GET_CMDLINE depends on the everything fitting on the screen
at once. So, the whole screen is about 2000 characters, minus the
PROMPT, and space for error and status lines, etc. MAXLEN must be
at least 1, and PROMPT and CMDLINE must be valid strings (not NULL
or zero-length).
If ECHO_CHAR is nonzero, echo it instead of the typed character. */
int
get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int readline)
static int
real_get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int readline)
{
/* This is a rather complicated function. So explain the concept.
@@ -279,8 +324,6 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
char *buf = (char *) CMDLINE_BUF;
/* The kill buffer. */
char *kill_buf = (char *) KILL_BUF;
/* The original state of AUTO_FILL. */
int saved_auto_fill = auto_fill;
/* Nested function definitions for code simplicity. */
@@ -308,29 +351,15 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
{
xpos -= count;
if ((terminal & TERMINAL_CONSOLE)
# ifdef SUPPORT_HERCULES
|| (terminal & TERMINAL_HERCULES)
# endif /* SUPPORT_HERCULES */
)
{
int y = getxy () & 0xFF;
gotoxy (xpos, y);
}
# ifdef SUPPORT_SERIAL
else if (! (terminal & TERMINAL_DUMB) && (count > 4))
{
grub_printf ("\e[%dD", count);
}
else
if (current_term->flags & TERM_DUMB)
{
int i;
for (i = 0; i < count; i++)
grub_putchar ('\b');
}
# endif /* SUPPORT_SERIAL */
else
gotoxy (xpos, getxy () & 0xFF);
}
}
@@ -346,22 +375,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
{
xpos += count;
if ((terminal & TERMINAL_CONSOLE)
# ifdef SUPPORT_HERCULES
|| (terminal & TERMINAL_HERCULES)
# endif /* SUPPORT_HERCULES */
)
{
int y = getxy () & 0xFF;
gotoxy (xpos, y);
}
# ifdef SUPPORT_SERIAL
else if (! (terminal & TERMINAL_DUMB) && (count > 4))
{
grub_printf ("\e[%dC", count);
}
else
if (current_term->flags & TERM_DUMB)
{
int i;
@@ -373,7 +387,8 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
grub_putchar (echo_char);
}
}
# endif /* SUPPORT_SERIAL */
else
gotoxy (xpos, getxy () & 0xFF);
}
}
@@ -388,8 +403,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
if (full)
{
/* Recompute the section number. */
if ((terminal & TERMINAL_DUMB)
|| (lpos + plen < CMDLINE_WIDTH))
if (lpos + plen < CMDLINE_WIDTH)
section = 0;
else
section = ((lpos + plen - CMDLINE_WIDTH)
@@ -453,50 +467,33 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
pos++;
}
if (! (terminal & TERMINAL_DUMB))
/* Fill up the rest of the line with spaces. */
for (; i < start + len; i++)
{
/* Fill up the rest of the line with spaces. */
for (; i < start + len; i++)
{
grub_putchar (' ');
pos++;
}
grub_putchar (' ');
pos++;
}
/* If the cursor is at the last position, put `>' or a space,
depending on if there are more characters in BUF. */
if (pos == CMDLINE_WIDTH)
{
if (start + len < llen)
grub_putchar ('>');
else
grub_putchar (' ');
/* If the cursor is at the last position, put `>' or a space,
depending on if there are more characters in BUF. */
if (pos == CMDLINE_WIDTH)
{
if (start + len < llen)
grub_putchar ('>');
else
grub_putchar (' ');
pos++;
}
/* Back to XPOS. */
if ((terminal & TERMINAL_CONSOLE)
# ifdef SUPPORT_HERCULES
|| (terminal & TERMINAL_HERCULES)
# endif /* SUPPORT_HERCULES */
)
{
int y = getxy () & 0xFF;
gotoxy (xpos, y);
}
# ifdef SUPPORT_SERIAL
else if (! (terminal & TERMINAL_SERIAL) && (pos - xpos > 4))
{
grub_printf ("\e[%dD", pos - xpos);
}
else
{
for (i = 0; i < pos - xpos; i++)
grub_putchar ('\b');
}
# endif /* SUPPORT_SERIAL */
}
pos++;
}
/* Back to XPOS. */
if (current_term->flags & TERM_DUMB)
{
for (i = 0; i < pos - xpos; i++)
grub_putchar ('\b');
}
else
gotoxy (xpos, getxy () & 0xFF);
}
/* Initialize the command-line. */
@@ -562,15 +559,10 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
lpos = llen;
grub_strcpy (buf, cmdline);
/* Disable the auto fill mode. */
auto_fill = 0;
cl_init ();
while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r')
while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
{
c = translate_keycode (c);
/* If READLINE is non-zero, handle readline-like key bindings. */
if (readline)
{
@@ -617,11 +609,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
completion. */
grub_memmove (completion_buffer, buf + i, lpos - i);
completion_buffer[lpos - i] = 0;
/* Enable the auto fill mode temporarily. */
auto_fill = 1;
ret = print_completions (is_filename, 1);
/* Disable the auto fill mode again. */
auto_fill = 0;
errnum = ERR_NONE;
if (ret >= 0)
@@ -633,13 +621,8 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
{
/* There are more than one candidates, so print
the list. */
grub_putchar ('\n');
/* Enable the auto fill mode temporarily. */
auto_fill = 1;
print_completions (is_filename, 0);
/* Disable the auto fill mode again. */
auto_fill = 0;
errnum = ERR_NONE;
}
}
@@ -792,124 +775,66 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
if (readline && lpos < llen)
add_history (cmdline, 0);
/* Restore the auto fill mode. */
auto_fill = saved_auto_fill;
return 0;
}
/* Translate a special key to a common ascii code. */
/* Don't use this with a MAXLEN greater than 1600 or so! The problem
is that GET_CMDLINE depends on the everything fitting on the screen
at once. So, the whole screen is about 2000 characters, minus the
PROMPT, and space for error and status lines, etc. MAXLEN must be
at least 1, and PROMPT and CMDLINE must be valid strings (not NULL
or zero-length).
If ECHO_CHAR is nonzero, echo it instead of the typed character. */
int
translate_keycode (int c)
get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int readline)
{
# ifdef SUPPORT_SERIAL
if (terminal & TERMINAL_SERIAL)
/* Because it is hard to deal with different conditions simultaneously,
less functional cases are handled here. Assume that TERM_NO_ECHO
implies TERM_NO_EDIT. */
if (current_term->flags & (TERM_NO_ECHO | TERM_NO_EDIT))
{
/* In a serial terminal, things are complicated, because several
key codes start from the character ESC, while we want to accept
ESC itself. */
if (c == '\e')
char *p = cmdline;
int c;
/* Make sure that MAXLEN is not too large. */
if (maxlen > MAX_CMDLINE)
maxlen = MAX_CMDLINE;
/* Print only the prompt. The contents of CMDLINE is simply discarded,
even if it is not empty. */
grub_printf ("%s", prompt);
/* Gather characters until a newline is gotten. */
while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
{
int start;
/* Return immediately if ESC is pressed. */
if (c == 27)
return 1;
/* Get current time. */
start = currticks ();
while (checkkey () == -1)
/* Printable characters are added into CMDLINE. */
if (c >= ' ' && c <= '~')
{
/* Wait for a next character, at least for 0.1 sec
(18.2 ticks/sec). */
int now;
now = currticks ();
if (now - start >= 2)
return c;
}
if (! (current_term->flags & TERM_NO_ECHO))
grub_putchar (c);
c = getkey ();
if (c == '[')
{
int c1, c2;
/* To filter illegal states. */
c = 0;
c1 = getkey ();
switch (c1)
{
case 'A': /* KEY_UP */
c = 16;
break;
case 'B': /* KEY_DOWN */
c = 14;
break;
case 'C': /* KEY_RIGHT */
c = 6;
break;
case 'D': /* KEY_LEFT */
c = 2;
break;
case 'F': /* End */
c = 5;
break;
case 'H': /* Home */
c = 1;
break;
case '1':
c2 = getkey ();
if (c2 == '~')
{
/* One of control keys (pos1,....). */
c = 1;
}
break;
case '3':
c2 = getkey ();
if (c2 == '~')
{
/* One of control keys (del,....). */
c = 4;
}
break;
case '4': /* Del */
c = 4;
break;
}
/* Preceding space characters must be ignored. */
if (c != ' ' || p != cmdline)
*p++ = c;
}
}
*p = 0;
if (! (current_term->flags & TERM_NO_ECHO))
grub_putchar ('\n');
return 0;
}
else
# endif /* SUPPORT_SERIAL */
{
switch (c)
{
case KEY_LEFT:
c = 2;
break;
case KEY_RIGHT:
c = 6;
break;
case KEY_UP:
c = 16;
break;
case KEY_DOWN:
c = 14;
break;
case KEY_HOME:
c = 1;
break;
case KEY_END:
c = 5;
break;
case KEY_DC:
c = 4;
break;
case KEY_BACKSPACE:
c = 8;
break;
}
}
return ASCII_CHAR (c);
/* Complicated features are left to real_get_cmdline. */
return real_get_cmdline (prompt, cmdline, maxlen, echo_char, readline);
}
#endif /* STAGE1_5 */
@@ -1029,7 +954,7 @@ grub_strncat (char *s1, const char *s2, int n)
a static library supporting minimal standard C functions and link
each image with the library. Complicated things should be left to
computer, definitely. -okuji */
#if ! defined(STAGE1_5) || defined(FSYS_VSTAFS)
#if !defined(STAGE1_5) || defined(FSYS_VSTAFS)
int
grub_strcmp (const char *s1, const char *s2)
{
@@ -1052,55 +977,35 @@ grub_strcmp (const char *s1, const char *s2)
int
getkey (void)
{
int c = -1;
if ((terminal & TERMINAL_CONSOLE)
#ifdef SUPPORT_HERCULES
|| (terminal & TERMINAL_HERCULES)
#endif /* SUPPORT_HERCULES */
)
c = console_getkey ();
#ifdef SUPPORT_SERIAL
else if (terminal & TERMINAL_SERIAL)
c = serial_getkey ();
#endif /* SUPPORT_SERIAL */
return c;
return current_term->getkey ();
}
/* Check if a key code is available. */
int
checkkey (void)
{
int c = -1;
if ((terminal & TERMINAL_CONSOLE)
#ifdef SUPPORT_HERCULES
|| (terminal & TERMINAL_HERCULES)
#endif /* SUPPORT_HERCULES */
)
c = console_checkkey ();
#ifdef SUPPORT_SERIAL
if (terminal & TERMINAL_SERIAL)
c = serial_checkkey ();
#endif /* SUPPORT_SERIAL */
return c;
return current_term->checkkey ();
}
#endif /* ! STAGE1_5 */
/* Display an ASCII character. */
void
grub_putchar (int c)
{
#ifndef STAGE1_5
static int col = 0;
#endif
if (c == '\n')
grub_putchar ('\r');
#ifndef STAGE1_5
else if (c == '\t' && current_term->getxy)
{
int n;
n = 8 - ((current_term->getxy () >> 8) & 3);
while (n--)
grub_putchar (' ');
return;
}
#endif /* ! STAGE1_5 */
#ifdef STAGE1_5
@@ -1109,27 +1014,10 @@ grub_putchar (int c)
#else /* ! STAGE1_5 */
/* Track the cursor by software here. */
/* XXX: This doesn't handle horizontal or vertical tabs. */
if (c == '\r')
col = 0;
else if (c == '\b')
{
if (col > 0)
col--;
}
else if (c >= ' ' && c <= '~')
{
/* Fold a line only if AUTO_FILL is true. */
if (auto_fill && col >= 79)
grub_putchar ('\n');
col++;
}
else if (c == '\n')
if (c == '\n')
{
/* Internal `more'-like feature. */
if (count_lines != -1)
if (count_lines >= 0)
{
count_lines++;
if (count_lines >= max_lines - 2)
@@ -1139,14 +1027,21 @@ grub_putchar (int c)
/* It's important to disable the feature temporarily, because
the following grub_printf call will print newlines. */
count_lines = -1;
if (current_term->highlight)
current_term->highlight (1);
grub_printf ("\n[Hit return to continue]");
if (current_term->highlight)
current_term->highlight (0);
grub_printf ("\n\n[Hit return to continue]");
do
{
tmp = ASCII_CHAR (getkey ());
}
while (tmp != '\n' && tmp != '\r');
grub_printf ("\n\n");
grub_printf ("\r \r");
/* Restart to count lines. */
count_lines = 0;
@@ -1155,18 +1050,7 @@ grub_putchar (int c)
}
}
if (terminal & TERMINAL_CONSOLE)
console_putchar (c);
# ifdef SUPPORT_HERCULES
if (terminal & TERMINAL_HERCULES)
herc_putchar (c);
# endif /* SUPPORT_HERCULES */
# ifdef SUPPORT_SERIAL
if (terminal & TERMINAL_SERIAL)
serial_putchar (c);
# endif /* SUPPORT_SERIAL */
current_term->putchar (c);
#endif /* ! STAGE1_5 */
}
@@ -1175,169 +1059,30 @@ grub_putchar (int c)
void
gotoxy (int x, int y)
{
if (terminal & TERMINAL_CONSOLE)
console_gotoxy (x, y);
#ifdef SUPPORT_HERCULES
else if (terminal & TERMINAL_HERCULES)
herc_gotoxy (x, y);
#endif /* SUPPORT_HERCULES */
#ifdef SUPPORT_SERIAL
else if (terminal & TERMINAL_SERIAL)
serial_gotoxy (x, y);
#endif /* SUPPORT_SERIAL */
current_term->gotoxy (x, y);
}
#ifdef SUPPORT_SERIAL
/* The serial part of gotoxy. */
void
serial_gotoxy (int x, int y)
{
grub_printf ("\e[%d;%dH", y + 1, x + 1);
}
#endif /* SUPPORT_SERIAL */
int
getxy (void)
{
int ret = 0;
if (terminal & TERMINAL_CONSOLE)
ret = console_getxy ();
#ifdef SUPPORT_HERCULES
else if (terminal & TERMINAL_HERCULES)
ret = herc_getxy ();
#endif /* SUPPORT_HERCULES */
#ifdef SUPPORT_SERIAL
else if (terminal & TERMINAL_SERIAL)
ret = serial_getxy ();
#endif /* SUPPORT_SERIAL */
return ret;
return current_term->getxy ();
}
#ifdef SUPPORT_SERIAL
/* The serial part of getxy. */
int
serial_getxy (void)
{
int x, y;
int start, now;
char buf[32]; /* XXX */
int i;
int c;
char *p;
/* Drain the input buffer. */
while (serial_checkkey () != -1)
serial_getkey ();
/* CPR. */
grub_printf ("\e[6n");
/* Get current time. */
while ((start = getrtsecs ()) == 0xFF)
;
again:
i = 0;
c = 0;
do
{
if (serial_checkkey () != -1)
{
c = serial_getkey ();
if (i == 1 && c != '[')
i = 0;
if (i == 0 && c != '\e')
continue;
if (i != 0 && c == '\e')
i = 0;
buf[i] = c;
i++;
}
else
{
/* Get current time. */
while ((now = getrtsecs ()) == 0xFF)
;
/* FIXME: Remove this magic number. */
if (now - start > 10)
{
/* Something is quite wrong. */
return 0;
}
}
}
while (c != 'R' && i < sizeof (buf));
if (c != 'R')
goto again;
p = buf + 2;
if (! safe_parse_maxint (&p, &y))
{
errnum = 0;
goto again;
}
if (*p != ';')
goto again;
p++;
if (! safe_parse_maxint (&p, &x))
{
errnum = 0;
goto again;
}
if (*p != 'R')
goto again;
return ((x - 1) << 8) | (y - 1);
}
#endif /* SUPPORT_SERIAL */
void
cls (void)
{
if (terminal & TERMINAL_CONSOLE)
console_cls ();
#ifdef SUPPORT_HERCULES
else if (terminal & TERMINAL_HERCULES)
herc_cls ();
#endif /* SUPPORT_HERCULES */
#ifdef SUPPORT_SERIAL
else if (terminal & TERMINAL_SERIAL)
serial_cls ();
#endif /* SUPPORT_SERIAL */
}
#ifdef SUPPORT_SERIAL
/* The serial part of cls. */
void
serial_cls (void)
{
/* If the terminal is dumb, there is no way to clean the terminal. */
if (terminal & TERMINAL_DUMB)
if (current_term->flags & TERM_DUMB)
grub_putchar ('\n');
else
grub_printf ("\e[H\e[J");
current_term->cls ();
}
#endif /* SUPPORT_SERIAL */
void
set_attrib (int attr)
nocursor (void)
{
#ifdef SUPPORT_HERCULES
if (terminal & TERMINAL_HERCULES)
herc_set_attrib (attr);
else
#endif /* SUPPORT_HERCULES */
console_set_attrib (attr);
if (current_term->nocursor)
current_term->nocursor ();
}
#endif /* ! STAGE1_5 */