make serial use ANSI code recognition in terminfo.mod
This commit is contained in:
parent
e903ddec1c
commit
82e32bc310
4 changed files with 30 additions and 121 deletions
|
@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
|
||||||
term/terminfo.c term/tparm.c \
|
term/terminfo.c term/tparm.c \
|
||||||
disk/ieee1275/ofdisk.c \
|
disk/ieee1275/ofdisk.c \
|
||||||
symlist.c
|
symlist.c
|
||||||
kernel_img_HEADERS += ieee1275/ieee1275.h
|
kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h
|
||||||
kernel_img_CFLAGS = $(COMMON_CFLAGS)
|
kernel_img_CFLAGS = $(COMMON_CFLAGS)
|
||||||
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
|
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
|
||||||
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
|
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
|
||||||
|
|
|
@ -23,18 +23,18 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
|
|
||||||
char *grub_terminfo_get_current (void);
|
char *EXPORT_FUNC(grub_terminfo_get_current) (void);
|
||||||
grub_err_t grub_terminfo_set_current (const char *);
|
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);
|
grub_term_output_t oterm);
|
||||||
void grub_terminfo_cls (grub_term_output_t oterm);
|
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t oterm);
|
||||||
void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
|
void EXPORT_FUNC(grub_terminfo_reverse_video_on) (grub_term_output_t oterm);
|
||||||
void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
|
void EXPORT_FUNC(grub_terminfo_reverse_video_off) (grub_term_output_t oterm);
|
||||||
void grub_terminfo_cursor_on (grub_term_output_t oterm);
|
void EXPORT_FUNC(grub_terminfo_cursor_on) (grub_term_output_t oterm);
|
||||||
void grub_terminfo_cursor_off (grub_term_output_t oterm);
|
void EXPORT_FUNC(grub_terminfo_cursor_off) (grub_term_output_t oterm);
|
||||||
|
|
||||||
#define GRUB_TERMINFO_READKEY_MAX_LEN 4
|
#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 */
|
#endif /* ! GRUB_TERMINFO_HEADER */
|
||||||
|
|
|
@ -166,12 +166,12 @@ static int
|
||||||
grub_ofconsole_checkkey (void)
|
grub_ofconsole_checkkey (void)
|
||||||
{
|
{
|
||||||
if (grub_buflen)
|
if (grub_buflen)
|
||||||
return 1;
|
return grub_keybuf[0];
|
||||||
|
|
||||||
grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey);
|
grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey);
|
||||||
|
|
||||||
if (grub_buflen)
|
if (grub_buflen)
|
||||||
return 1;
|
return grub_keybuf[0];
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
123
term/serial.c
123
term/serial.c
|
@ -35,8 +35,8 @@ static unsigned int keep_track = 1;
|
||||||
static unsigned int registered = 0;
|
static unsigned int registered = 0;
|
||||||
|
|
||||||
/* An input buffer. */
|
/* An input buffer. */
|
||||||
static char input_buf[8];
|
static int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
|
||||||
static unsigned int npending = 0;
|
static int npending = 0;
|
||||||
|
|
||||||
static struct grub_term_output grub_serial_term_output;
|
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);
|
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. */
|
/* Convert speed to divisor. */
|
||||||
static unsigned short
|
static unsigned short
|
||||||
serial_get_divisor (unsigned int speed)
|
serial_get_divisor (unsigned int speed)
|
||||||
|
@ -248,9 +156,14 @@ serial_get_divisor (unsigned int speed)
|
||||||
static int
|
static int
|
||||||
grub_serial_checkkey (void)
|
grub_serial_checkkey (void)
|
||||||
{
|
{
|
||||||
if (fill_input_buf (1))
|
if (npending)
|
||||||
return input_buf[0];
|
return input_buf[0];
|
||||||
else
|
|
||||||
|
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
|
||||||
|
|
||||||
|
if (npending)
|
||||||
|
return input_buf[0];
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,18 +171,14 @@ grub_serial_checkkey (void)
|
||||||
static int
|
static int
|
||||||
grub_serial_getkey (void)
|
grub_serial_getkey (void)
|
||||||
{
|
{
|
||||||
int c;
|
int ret;
|
||||||
|
while (! npending)
|
||||||
|
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
|
||||||
|
|
||||||
while (! fill_input_buf (0))
|
ret = input_buf[0];
|
||||||
;
|
npending--;
|
||||||
|
grub_memmove (input_buf, input_buf + 1, npending);
|
||||||
c = input_buf[0];
|
return ret;
|
||||||
if (c == 0x7f)
|
|
||||||
c = GRUB_TERM_BACKSPACE;
|
|
||||||
|
|
||||||
grub_memmove (input_buf, input_buf + 1, --npending);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize a serial device. PORT is the port number for a serial device.
|
/* Initialize a serial device. PORT is the port number for a serial device.
|
||||||
|
|
Loading…
Reference in a new issue