Add support for line drawing characters and the alternate character set.
This enables using the ACS_ curses macros with libpayload. The translation from ACS_ macros (or characters with attribute A_ALTCHARSET) is done using one acs map for the video console, one for serial console (xterm/vt100/vt220), and one fallback, from which an ASCII substitute is taken if the device specific map doesn't contain an entry (ie NUL). Signed-off-by: Ulf Jordan <jordan@chalmers.se> Acked-by: Jordan Crouse <jordan.crouse@amd.com> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3499 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
42a0c80b9b
commit
b4d4bac1c4
|
@ -2,6 +2,7 @@
|
||||||
* This file is part of the libpayload project.
|
* This file is part of the libpayload project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
|
* Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
|
||||||
|
* Copyright (C) 2008 Ulf Jordan <jordan@chalmers.se>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -88,6 +89,69 @@ int ESCDELAY;
|
||||||
SCREEN *SP;
|
SCREEN *SP;
|
||||||
chtype acs_map[128];
|
chtype acs_map[128];
|
||||||
|
|
||||||
|
/* See terminfo(5). */
|
||||||
|
chtype fallback_acs_map[128] =
|
||||||
|
{
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', '>', '<', '^', 'v', ' ',
|
||||||
|
'#', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||||
|
'+', ':', ' ', ' ', ' ', ' ', '\\', '#',
|
||||||
|
'#', '#', '+', '+', '+', '+', '+', '~',
|
||||||
|
'-', '-', '-', '_', '+', '+', '+', '+',
|
||||||
|
'|', '<', '>', '*', '!', 'f', 'o', ' ',
|
||||||
|
};
|
||||||
|
|
||||||
|
/* See acsc of vt100. */
|
||||||
|
chtype serial_acs_map[128] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
'`', 'a', 0, 0, 0, 0, 'f', 'g',
|
||||||
|
0, 0, 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||||
|
'x', 'y', 'z', '{', '|', '}', '~', 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* See acsc of linux. */
|
||||||
|
chtype console_acs_map[128] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, '\020', '\021', '\030', '\031', 0,
|
||||||
|
'\333', 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
'\004', '\261', 0, 0, 0, 0, '\370', '\361',
|
||||||
|
'\260', '\316', '\331', '\277', '\332', '\300', '\305', '~',
|
||||||
|
'\304', '\304', '\304', '_', '\303', '\264', '\301', '\302',
|
||||||
|
'\263', '\363', '\362', '\342', '\330', '\234', '\376', 0,
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME: Ugly (and insecure!) hack!
|
// FIXME: Ugly (and insecure!) hack!
|
||||||
char sprintf_tmp[1024];
|
char sprintf_tmp[1024];
|
||||||
|
|
||||||
|
@ -213,11 +277,14 @@ void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
|
||||||
/** Note: Must _not_ be called twice! */
|
/** Note: Must _not_ be called twice! */
|
||||||
WINDOW *initscr(void)
|
WINDOW *initscr(void)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y, i;
|
||||||
|
|
||||||
// newterm(name, stdout, stdin);
|
// newterm(name, stdout, stdin);
|
||||||
// def_prog_mode();
|
// def_prog_mode();
|
||||||
|
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
acs_map[i] = (chtype) i | A_ALTCHARSET;
|
||||||
|
|
||||||
if (curses_flags & F_ENABLE_SERIAL) {
|
if (curses_flags & F_ENABLE_SERIAL) {
|
||||||
serial_clear();
|
serial_clear();
|
||||||
}
|
}
|
||||||
|
@ -409,12 +476,12 @@ int waddch(WINDOW *win, const chtype ch)
|
||||||
// NCURSES_CH_T wch;
|
// NCURSES_CH_T wch;
|
||||||
// SetChar2(wch, ch);
|
// SetChar2(wch, ch);
|
||||||
|
|
||||||
win->_line[win->_cury].text[win->_curx].chars[0] = ch;
|
win->_line[win->_cury].text[win->_curx].chars[0] =
|
||||||
|
((ch) & (chtype)A_CHARTEXT);
|
||||||
/* Use the window attributes - perhaps we also pull attributes from
|
|
||||||
the ch itself, I don't know */
|
|
||||||
|
|
||||||
win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
|
win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
|
||||||
|
win->_line[win->_cury].text[win->_curx].attr |=
|
||||||
|
((ch) & (chtype)A_ATTRIBUTES);
|
||||||
win->_curx++; // FIXME
|
win->_curx++; // FIXME
|
||||||
|
|
||||||
// if (win && (waddch_nosync(win, wch) != ERR)) {
|
// if (win && (waddch_nosync(win, wch) != ERR)) {
|
||||||
|
@ -595,10 +662,14 @@ int wnoutrefresh(WINDOW *win)
|
||||||
{
|
{
|
||||||
// FIXME.
|
// FIXME.
|
||||||
int serial_is_bold = 0;
|
int serial_is_bold = 0;
|
||||||
|
int serial_is_altcharset = 0;
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
chtype ch;
|
||||||
|
int need_altcharset;
|
||||||
|
|
||||||
serial_end_bold();
|
serial_end_bold();
|
||||||
|
serial_end_altcharset();
|
||||||
|
|
||||||
for (y = 0; y <= win->_maxy; y++) {
|
for (y = 0; y <= win->_maxy; y++) {
|
||||||
|
|
||||||
|
@ -614,6 +685,7 @@ int wnoutrefresh(WINDOW *win)
|
||||||
((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
|
((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
|
||||||
|
|
||||||
if (curses_flags & F_ENABLE_SERIAL) {
|
if (curses_flags & F_ENABLE_SERIAL) {
|
||||||
|
ch = win->_line[y].text[x].chars[0];
|
||||||
|
|
||||||
if (attr & A_BOLD) {
|
if (attr & A_BOLD) {
|
||||||
if (!serial_is_bold) {
|
if (!serial_is_bold) {
|
||||||
|
@ -628,10 +700,28 @@ int wnoutrefresh(WINDOW *win)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_putchar(win->_line[y].text[x].chars[0]);
|
need_altcharset = 0;
|
||||||
|
if (attr & A_ALTCHARSET) {
|
||||||
|
if (serial_acs_map[ch & 0x7f]) {
|
||||||
|
ch = serial_acs_map[ch & 0x7f];
|
||||||
|
need_altcharset = 1;
|
||||||
|
} else
|
||||||
|
ch = fallback_acs_map[ch & 0x7f];
|
||||||
|
}
|
||||||
|
if (need_altcharset && !serial_is_altcharset) {
|
||||||
|
serial_start_altcharset();
|
||||||
|
serial_is_altcharset = 1;
|
||||||
|
}
|
||||||
|
if (!need_altcharset && serial_is_altcharset) {
|
||||||
|
serial_end_altcharset();
|
||||||
|
serial_is_altcharset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_putchar(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curses_flags & F_ENABLE_CONSOLE) {
|
if (curses_flags & F_ENABLE_CONSOLE) {
|
||||||
|
ch = win->_line[y].text[x].chars[0];
|
||||||
|
|
||||||
/* Handle some of the attributes. */
|
/* Handle some of the attributes. */
|
||||||
if (attr & A_BOLD)
|
if (attr & A_BOLD)
|
||||||
|
@ -643,6 +733,12 @@ int wnoutrefresh(WINDOW *win)
|
||||||
c = (c >> 4) & 0xf00;
|
c = (c >> 4) & 0xf00;
|
||||||
c |= tmp << 12;
|
c |= tmp << 12;
|
||||||
}
|
}
|
||||||
|
if (attr & A_ALTCHARSET) {
|
||||||
|
if (console_acs_map[ch & 0x7f])
|
||||||
|
ch = console_acs_map[ch & 0x7f];
|
||||||
|
else
|
||||||
|
ch = fallback_acs_map[ch & 0x7f];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Somewhere along the line, the
|
* FIXME: Somewhere along the line, the
|
||||||
|
@ -650,7 +746,7 @@ int wnoutrefresh(WINDOW *win)
|
||||||
* For now grab just the 8 bit character,
|
* For now grab just the 8 bit character,
|
||||||
* but this will break wide characters!
|
* but this will break wide characters!
|
||||||
*/
|
*/
|
||||||
c |= (chtype) (win->_line[y].text[x].chars[0] & 0xff);
|
c |= (chtype) (ch & 0xff);
|
||||||
video_console_putc(win->_begy + y, win->_begx + x, c);
|
video_console_putc(win->_begy + y, win->_begx + x, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* This file is part of the libpayload project.
|
* This file is part of the libpayload project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||||
|
* Copyright (C) 2008 Ulf Jordan <jordan@chalmers.se>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -105,6 +106,10 @@ int serial_getchar(void)
|
||||||
#define VT100_SBOLD "\e[1m"
|
#define VT100_SBOLD "\e[1m"
|
||||||
#define VT100_EBOLD "\e[m"
|
#define VT100_EBOLD "\e[m"
|
||||||
#define VT100_CURSOR_ADDR "\e[%d;%dH"
|
#define VT100_CURSOR_ADDR "\e[%d;%dH"
|
||||||
|
/* The following smacs/rmacs are actually for xterm; a real vt100 has
|
||||||
|
enacs=\E(B\E)0, smacs=^N, rmacs=^O. */
|
||||||
|
#define VT100_SMACS "\e(0"
|
||||||
|
#define VT100_RMACS "\e(B"
|
||||||
|
|
||||||
static void serial_putcmd(char *str)
|
static void serial_putcmd(char *str)
|
||||||
{
|
{
|
||||||
|
@ -127,6 +132,16 @@ void serial_end_bold(void)
|
||||||
serial_putcmd(VT100_EBOLD);
|
serial_putcmd(VT100_EBOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serial_start_altcharset(void)
|
||||||
|
{
|
||||||
|
serial_putcmd(VT100_SMACS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_end_altcharset(void)
|
||||||
|
{
|
||||||
|
serial_putcmd(VT100_RMACS);
|
||||||
|
}
|
||||||
|
|
||||||
void serial_set_cursor(int y, int x)
|
void serial_set_cursor(int y, int x)
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
|
|
|
@ -105,6 +105,8 @@ int serial_getchar(void);
|
||||||
void serial_clear(void);
|
void serial_clear(void);
|
||||||
void serial_start_bold(void);
|
void serial_start_bold(void);
|
||||||
void serial_end_bold(void);
|
void serial_end_bold(void);
|
||||||
|
void serial_start_altcharset(void);
|
||||||
|
void serial_end_altcharset(void);
|
||||||
void serial_set_cursor(int y, int x);
|
void serial_set_cursor(int y, int x);
|
||||||
|
|
||||||
/* drivers/speaker.c */
|
/* drivers/speaker.c */
|
||||||
|
|
Loading…
Reference in New Issue