Author: stepan Date: 2008-09-26 20:36:26 +0200 (Fri, 26 Sep 2008) New Revision: 3604
Modified: trunk/payloads/libpayload/curses/keyboard.c trunk/payloads/libpayload/curses/tinycurses.c trunk/payloads/libpayload/drivers/serial.c trunk/payloads/libpayload/include/curses.h trunk/payloads/libpayload/include/libpayload.h Log: * factor out serial hardware init * add reverse color support for serial * add cursor enable/disable support for serial * fix tinycurses compilation if serial is disabled * add functions to query whether serial or vga console is enabled in tinycurses * initialize uninitialized COLOR_PAIRS variable * implement has_colors(), wredrawln() functions in curses
Signed-off-by: Stefan Reinauer stepan@coresystems.de Acked-by: Jordan Crouse jordan.crouse@amd.com
Modified: trunk/payloads/libpayload/curses/keyboard.c =================================================================== --- trunk/payloads/libpayload/curses/keyboard.c 2008-09-26 17:41:34 UTC (rev 3603) +++ trunk/payloads/libpayload/curses/keyboard.c 2008-09-26 18:36:26 UTC (rev 3604) @@ -44,6 +44,7 @@
/* ============== Serial ==================== */
+#ifdef CONFIG_SERIAL_CONSOLE /* We treat serial like a vt100 terminal. For now we do the cooking in here, but we should probably eventually pass it to dedicated vt100 code */ @@ -135,6 +136,7 @@ return ch; } } +#endif
/* ================ Keyboard ================ */
@@ -215,8 +217,14 @@ else curses_flags &= ~F_ENABLE_CONSOLE; } + +int curses_vga_enabled(void) +{ + return (curses_flags & F_ENABLE_CONSOLE) != 0; +} #else void curses_enable_vga(int state) { } +int curses_vga_enabled(void) { return 0; } #endif
#ifdef CONFIG_SERIAL_CONSOLE @@ -227,7 +235,14 @@ else curses_flags &= ~F_ENABLE_SERIAL; } + +int curses_serial_enabled(void) +{ + return (curses_flags & F_ENABLE_SERIAL) != 0; +} + #else void curses_enable_serial(int state) { } +int curses_serial_enabled(void) { return 0; } #endif
Modified: trunk/payloads/libpayload/curses/tinycurses.c =================================================================== --- trunk/payloads/libpayload/curses/tinycurses.c 2008-09-26 17:41:34 UTC (rev 3603) +++ trunk/payloads/libpayload/curses/tinycurses.c 2008-09-26 18:36:26 UTC (rev 3604) @@ -77,7 +77,7 @@
/* Globals */ int COLORS; /* Currently unused? */ -int COLOR_PAIRS; +int COLOR_PAIRS = 255; WINDOW *stdscr; WINDOW *curscr; WINDOW *newscr; @@ -111,6 +111,7 @@ '|', '<', '>', '*', '!', 'f', 'o', ' ', };
+#ifdef CONFIG_SERIAL_CONSOLE #ifdef CONFIG_SERIAL_ACS_FALLBACK chtype serial_acs_map[128]; #else @@ -135,7 +136,9 @@ 'x', 'y', 'z', '{', '|', '}', '~', 0, }; #endif +#endif
+#ifdef CONFIG_VIDEO_CONSOLE /* See acsc of linux. */ chtype console_acs_map[128] = { @@ -156,6 +159,7 @@ '\304', '\304', '\304', '_', '\303', '\264', '\301', '\302', '\263', '\363', '\362', '\343', '\330', '\234', '\376', 0, }; +#endif
// FIXME: Ugly (and insecure!) hack! char sprintf_tmp[1024]; @@ -196,13 +200,16 @@ // int color_content(short color, short *r, short *g, short *b) {} int curs_set(int on) { +#ifdef CONFIG_SERIAL_CONSOLE if (curses_flags & F_ENABLE_SERIAL) { - // TODO + serial_cursor_enable(on); } - +#endif +#ifdef CONFIG_VIDEO_CONSOLE if (curses_flags & F_ENABLE_CONSOLE) { video_console_cursor_enable(on); } +#endif
return OK; } @@ -284,7 +291,7 @@ // int flash(void) {} int flushinp(void) { /* TODO */ return 0; } // WINDOW *getwin (FILE *) {} -bool has_colors (void) { /* TODO */ return(*(bool *)0); } +bool has_colors (void) { return(TRUE); } // bool has_ic (void) {} // bool has_il (void) {} // void idcok (WINDOW *, bool) {} @@ -300,21 +307,23 @@
for (i = 0; i < 128; i++) acs_map[i] = (chtype) i | A_ALTCHARSET; - +#ifdef CONFIG_SERIAL_CONSOLE if (curses_flags & F_ENABLE_SERIAL) { serial_clear(); } - +#endif +#ifdef CONFIG_VIDEO_CONSOLE if (curses_flags & F_ENABLE_CONSOLE) { /* Clear the screen and kill the cursor */
video_console_clear(); video_console_cursor_enable(0); } +#endif
// Speaker init?
- stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0); + stdscr = newwin(SCREEN_Y, SCREEN_X + 1, 0, 0); // TODO: curscr, newscr?
werase(stdscr); @@ -693,18 +702,23 @@ (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2) int wnoutrefresh(WINDOW *win) { +#ifdef CONFIG_SERIAL_CONSOLE // FIXME. int serial_is_bold = 0; + int serial_is_reverse = 0; int serial_is_altcharset = 0; int serial_cur_pair = 0;
+ int need_altcharset; + short fg, bg; +#endif int x, y; chtype ch; - int need_altcharset; - short fg, bg;
+#ifdef CONFIG_SERIAL_CONSOLE serial_end_bold(); serial_end_altcharset(); +#endif
for (y = 0; y <= win->_maxy; y++) {
@@ -713,9 +727,11 @@
/* Position the serial cursor */
+#ifdef CONFIG_SERIAL_CONSOLE if (curses_flags & F_ENABLE_SERIAL) serial_set_cursor(win->_begy + y, win->_begx + win->_line[y].firstchar); +#endif
for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) { attr_t attr = win->_line[y].text[x].attr; @@ -723,6 +739,7 @@ unsigned int c = ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
+#ifdef CONFIG_SERIAL_CONSOLE if (curses_flags & F_ENABLE_SERIAL) { ch = win->_line[y].text[x].chars[0];
@@ -731,15 +748,35 @@ serial_start_bold(); serial_is_bold = 1; } - } - else { + } else { if (serial_is_bold) { serial_end_bold(); serial_is_bold = 0; + /* work around serial.c + * shortcoming: + */ + serial_is_reverse = 0; serial_cur_pair = 0; } }
+ if (attr & A_REVERSE) { + if (!serial_is_reverse) { + serial_start_reverse(); + serial_is_reverse = 1; + } + } else { + if (serial_is_reverse) { + serial_end_reverse(); + serial_is_reverse = 0; + /* work around serial.c + * shortcoming: + */ + serial_is_bold = 0; + serial_cur_pair = 0; + } + } + need_altcharset = 0; if (attr & A_ALTCHARSET) { if (serial_acs_map[ch & 0x7f]) { @@ -767,7 +804,8 @@ serial_putchar(ch);
} - +#endif +#ifdef CONFIG_VIDEO_CONSOLE c = SWAP_RED_BLUE(c);
if (curses_flags & F_ENABLE_CONSOLE) { @@ -799,16 +837,21 @@ c |= (chtype) (ch & 0xff); video_console_putc(win->_begy + y, win->_begx + x, c); } +#endif } win->_line[y].firstchar = _NOCHANGE; win->_line[y].lastchar = _NOCHANGE; }
+#ifdef CONFIG_SERIAL_CONSOLE if (curses_flags & F_ENABLE_SERIAL) serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx); +#endif
+#ifdef CONFIG_VIDEO_CONSOLE if (curses_flags & F_ENABLE_CONSOLE) video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury); +#endif
return OK; } @@ -823,7 +866,19 @@
return code; } -// int wredrawln (WINDOW *,int,int) {} + +int wredrawln (WINDOW *win, int beg_line, int num_lines) +{ + int i; + + for (i = beg_line; i < beg_line + num_lines; i++) { + win->_line[i].firstchar = 0; + win->_line[i].lastchar = win->_maxx; + } + + return OK; +} + int wrefresh(WINDOW *win) { // FIXME
Modified: trunk/payloads/libpayload/drivers/serial.c =================================================================== --- trunk/payloads/libpayload/drivers/serial.c 2008-09-26 17:41:34 UTC (rev 3603) +++ trunk/payloads/libpayload/drivers/serial.c 2008-09-26 18:36:26 UTC (rev 3604) @@ -32,32 +32,36 @@ #include <libpayload.h>
#define IOBASE lib_sysinfo.ser_ioport +#define DIVISOR(x) (115200 / x)
-#ifdef CONFIG_SERIAL_SET_SPEED -#define DIVISOR (115200 / CONFIG_SERIAL_BAUD_RATE) -#endif - -void serial_init(void) +void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits) { -#ifdef CONFIG_SERIAL_SET_SPEED unsigned char reg;
+ /* We will assume 8n1 for now. Does anyone use anything else these days? */ + /* Disable interrupts. */ - outb(0, IOBASE + 0x01); + outb(0, port + 0x01);
/* Assert RTS and DTR. */ - outb(3, IOBASE + 0x04); + outb(3, port + 0x04);
/* Set the divisor latch. */ - reg = inb(IOBASE + 0x03); - outb(reg | 0x80, IOBASE + 0x03); + reg = inb(port + 0x03); + outb(reg | 0x80, port + 0x03);
/* Write the divisor. */ - outb(DIVISOR & 0xFF, IOBASE); - outb(DIVISOR >> 8 & 0xFF, IOBASE + 1); + outb(DIVISOR(speed) & 0xFF, port); + outb(DIVISOR(speed) >> 8 & 0xFF, port + 1);
/* Restore the previous value of the divisor. */ - outb(reg &= ~0x80, IOBASE + 0x03); + outb(reg &= ~0x80, port + 0x03); +} + +void serial_init(void) +{ +#ifdef CONFIG_SERIAL_SET_SPEED + serial_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1); #endif }
@@ -81,9 +85,17 @@ /* These are thinly veiled vt100 functions used by curses */
#define VT100_CLEAR "\e[H\e[J" +/* These defines will fail if you use bold and reverse at the same time. + * Switching off one of them will switch off both. tinycurses knows about + * this and does the right thing. + */ #define VT100_SBOLD "\e[1m" #define VT100_EBOLD "\e[m" +#define VT100_SREVERSE "\e[7m" +#define VT100_EREVERSE "\e[m" #define VT100_CURSOR_ADDR "\e[%d;%dH" +#define VT100_CURSOR_ON "\e[?25l" +#define VT100_CURSOR_OFF "\e[?25h" /* 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" @@ -112,6 +124,16 @@ serial_putcmd(VT100_EBOLD); }
+void serial_start_reverse(void) +{ + serial_putcmd(VT100_SREVERSE); +} + +void serial_end_reverse(void) +{ + serial_putcmd(VT100_EREVERSE); +} + void serial_start_altcharset(void) { serial_putcmd(VT100_SMACS); @@ -141,3 +163,11 @@ snprintf(buffer, sizeof(buffer), VT100_CURSOR_ADDR, y + 1, x + 1); serial_putcmd(buffer); } + +void serial_cursor_enable(int state) +{ + if (state) + serial_putcmd(VT100_CURSOR_ON); + else + serial_putcmd(VT100_CURSOR_OFF); +}
Modified: trunk/payloads/libpayload/include/curses.h =================================================================== --- trunk/payloads/libpayload/include/curses.h 2008-09-26 17:41:34 UTC (rev 3603) +++ trunk/payloads/libpayload/include/curses.h 2008-09-26 18:36:26 UTC (rev 3604) @@ -1673,4 +1673,7 @@ void curses_enable_vga(int); void curses_enable_serial(int);
+int curses_vga_enabled(void); +int curses_serial_enabled(void); + #endif /* _CURSES_H */
Modified: trunk/payloads/libpayload/include/libpayload.h =================================================================== --- trunk/payloads/libpayload/include/libpayload.h 2008-09-26 17:41:34 UTC (rev 3603) +++ trunk/payloads/libpayload/include/libpayload.h 2008-09-26 18:36:26 UTC (rev 3604) @@ -131,15 +131,19 @@ * @{ */ void serial_init(void); +void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits); void serial_putchar(unsigned char c); int serial_havechar(void); int serial_getchar(void); void serial_clear(void); void serial_start_bold(void); void serial_end_bold(void); +void serial_start_reverse(void); +void serial_end_reverse(void); void serial_start_altcharset(void); void serial_end_altcharset(void); void serial_set_color(short fg, short bg); +void serial_cursor_enable(int state); void serial_set_cursor(int y, int x); /** @} */