make serial use ANSI code recognition in terminfo.mod

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-05-06 21:32:58 +02:00
parent e903ddec1c
commit 82e32bc310
4 changed files with 30 additions and 121 deletions

View file

@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
symlist.c
kernel_img_HEADERS += ieee1275/ieee1275.h
kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic

View file

@ -23,18 +23,18 @@
#include <grub/types.h>
#include <grub/term.h>
char *grub_terminfo_get_current (void);
grub_err_t grub_terminfo_set_current (const char *);
char *EXPORT_FUNC(grub_terminfo_get_current) (void);
grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (const char *);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_uint8_t x, grub_uint8_t y,
grub_term_output_t oterm);
void grub_terminfo_cls (grub_term_output_t oterm);
void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
void grub_terminfo_cursor_on (grub_term_output_t oterm);
void grub_terminfo_cursor_off (grub_term_output_t oterm);
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t oterm);
void EXPORT_FUNC(grub_terminfo_reverse_video_on) (grub_term_output_t oterm);
void EXPORT_FUNC(grub_terminfo_reverse_video_off) (grub_term_output_t oterm);
void EXPORT_FUNC(grub_terminfo_cursor_on) (grub_term_output_t oterm);
void EXPORT_FUNC(grub_terminfo_cursor_off) (grub_term_output_t oterm);
#define GRUB_TERMINFO_READKEY_MAX_LEN 4
void grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void));
void EXPORT_FUNC(grub_terminfo_readkey) (int *keys, int *len, int (*readkey) (void));
#endif /* ! GRUB_TERMINFO_HEADER */

View file

@ -166,12 +166,12 @@ static int
grub_ofconsole_checkkey (void)
{
if (grub_buflen)
return 1;
return grub_keybuf[0];
grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey);
if (grub_buflen)
return 1;
return grub_keybuf[0];
return -1;
}

View file

@ -35,8 +35,8 @@ static unsigned int keep_track = 1;
static unsigned int registered = 0;
/* An input buffer. */
static char input_buf[8];
static unsigned int npending = 0;
static int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
static int npending = 0;
static struct grub_term_output grub_serial_term_output;
@ -114,98 +114,6 @@ serial_hw_put (const int c)
grub_outb (c, serial_settings.port + UART_TX);
}
static void
serial_translate_key_sequence (void)
{
unsigned int i;
static struct
{
char key;
char ascii;
}
three_code_table[] =
{
{'A', 16},
{'B', 14},
{'C', 6},
{'D', 2},
{'F', 5},
{'H', 1},
{'4', 4}
};
static struct
{
short key;
char ascii;
}
four_code_table[] =
{
{('1' | ('~' << 8)), 1},
{('3' | ('~' << 8)), 4},
{('5' | ('~' << 8)), 7},
{('6' | ('~' << 8)), 3}
};
if (npending < 3)
return;
/* The buffer must start with "ESC [". */
if (input_buf[0] != '\e' || input_buf[1] != '[')
return;
for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
if (three_code_table[i].key == input_buf[2])
{
input_buf[0] = three_code_table[i].ascii;
npending -= 2;
grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
return;
}
if (npending >= 4)
{
short key = input_buf[3] | (input_buf[4] << 8);
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
if (four_code_table[i].key == key)
{
input_buf[0] = four_code_table[i].ascii;
npending -= 3;
grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
return;
}
}
}
static int
fill_input_buf (const int nowait)
{
int i;
for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
{
int c;
c = serial_hw_fetch ();
if (c >= 0)
{
input_buf[npending++] = c;
/* Reset the counter to zero, to wait for the same interval. */
i = 0;
}
if (nowait)
break;
}
/* Translate some key sequences. */
serial_translate_key_sequence ();
return npending;
}
/* Convert speed to divisor. */
static unsigned short
serial_get_divisor (unsigned int speed)
@ -248,9 +156,14 @@ serial_get_divisor (unsigned int speed)
static int
grub_serial_checkkey (void)
{
if (fill_input_buf (1))
if (npending)
return input_buf[0];
else
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
if (npending)
return input_buf[0];
return -1;
}
@ -258,18 +171,14 @@ grub_serial_checkkey (void)
static int
grub_serial_getkey (void)
{
int c;
int ret;
while (! npending)
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
while (! fill_input_buf (0))
;
c = input_buf[0];
if (c == 0x7f)
c = GRUB_TERM_BACKSPACE;
grub_memmove (input_buf, input_buf + 1, --npending);
return c;
ret = input_buf[0];
npending--;
grub_memmove (input_buf, input_buf + 1, npending);
return ret;
}
/* Initialize a serial device. PORT is the port number for a serial device.