diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/ipxe/src/hci/mucurses | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/hci/mucurses')
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/alert.c | 18 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c | 102 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/clear.c | 100 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/colour.c | 66 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/cursor.h | 37 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/edging.c | 111 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/kb.c | 143 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/mucurses.c | 156 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/mucurses.h | 23 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/print.c | 86 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/print_nadv.c | 26 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/slk.c | 363 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c | 103 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/winattrs.c | 133 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/windows.c | 158 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/hci/mucurses/wininit.c | 38 |
16 files changed, 1663 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/hci/mucurses/alert.c b/qemu/roms/ipxe/src/hci/mucurses/alert.c new file mode 100644 index 000000000..00e959a89 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/alert.c @@ -0,0 +1,18 @@ +#include <curses.h> +#include <stdio.h> + +/** @file + * + * MuCurses alert functions + * + */ + +/** + * Audible signal + * + * @ret rc return status code + */ +int beep ( void ) { + printf("\a"); + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c b/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c new file mode 100644 index 000000000..1d3143f89 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c @@ -0,0 +1,102 @@ +#include <stdio.h> +#include <curses.h> +#include <ipxe/ansicol.h> +#include <ipxe/console.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static void ansiscr_reset(struct _curses_screen *scr) __nonnull; +static void ansiscr_movetoyx(struct _curses_screen *scr, + unsigned int y, unsigned int x) __nonnull; +static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull; + +static unsigned int saved_usage; + +static void ansiscr_attrs ( struct _curses_screen *scr, attr_t attrs ) { + int bold = ( attrs & A_BOLD ); + attr_t cpair = PAIR_NUMBER ( attrs ); + + if ( scr->attrs != attrs ) { + scr->attrs = attrs; + /* Reset attributes and set/clear bold as appropriate */ + printf ( "\033[0;%dm", ( bold ? 1 : 22 ) ); + /* Set foreground and background colours */ + ansicol_set_pair ( cpair ); + } +} + +static void ansiscr_reset ( struct _curses_screen *scr ) { + /* Reset terminal attributes and clear screen */ + scr->attrs = 0; + scr->curs_x = 0; + scr->curs_y = 0; + printf ( "\0330m" ); + ansicol_set_pair ( CPAIR_DEFAULT ); + printf ( "\033[2J" ); +} + +static void ansiscr_init ( struct _curses_screen *scr ) { + saved_usage = console_set_usage ( CONSOLE_USAGE_TUI ); + ansiscr_reset ( scr ); +} + +static void ansiscr_exit ( struct _curses_screen *scr ) { + ansiscr_reset ( scr ); + console_set_usage ( saved_usage ); +} + +static void ansiscr_erase ( struct _curses_screen *scr, attr_t attrs ) { + ansiscr_attrs ( scr, attrs ); + printf ( "\033[2J" ); +} + +static void ansiscr_movetoyx ( struct _curses_screen *scr, + unsigned int y, unsigned int x ) { + if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) { + /* ANSI escape sequence to update cursor position */ + printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) ); + scr->curs_x = x; + scr->curs_y = y; + } +} + +static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) { + unsigned int character = ( c & A_CHARTEXT ); + attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) ); + + /* Update attributes if changed */ + ansiscr_attrs ( scr, attrs ); + + /* Print the actual character */ + putchar ( character ); + + /* Update expected cursor position */ + if ( ++(scr->curs_x) == COLS ) { + scr->curs_x = 0; + ++scr->curs_y; + } +} + +static int ansiscr_getc ( struct _curses_screen *scr __unused ) { + return getchar(); +} + +static bool ansiscr_peek ( struct _curses_screen *scr __unused ) { + return iskey(); +} + +static void ansiscr_cursor ( struct _curses_screen *scr __unused, + int visibility ) { + printf ( "\033[?25%c", ( visibility ? 'h' : 'l' ) ); +} + +SCREEN _ansi_screen = { + .init = ansiscr_init, + .exit = ansiscr_exit, + .erase = ansiscr_erase, + .movetoyx = ansiscr_movetoyx, + .putc = ansiscr_putc, + .getc = ansiscr_getc, + .peek = ansiscr_peek, + .cursor = ansiscr_cursor, +}; diff --git a/qemu/roms/ipxe/src/hci/mucurses/clear.c b/qemu/roms/ipxe/src/hci/mucurses/clear.c new file mode 100644 index 000000000..f5e52ca20 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/clear.c @@ -0,0 +1,100 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses clearing functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Clear a window to the bottom from current cursor position + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtobot ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + do { + _wputc( win, ' ', WRAP ); + } while ( win->curs_y + win->curs_x ); + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Clear a window to the end of the current line + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtoeol ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + while ( ( win->curs_y - pos.y ) == 0 ) { + _wputc( win, ' ', WRAP ); + } + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Delete character under the cursor in a window + * + * @v *win subject window + * @ret rc return status code + */ +int wdelch ( WINDOW *win ) { + _wputc( win, ' ', NOWRAP ); + _wcursback( win ); + + return OK; +} + +/** + * Delete line under a window's cursor + * + * @v *win subject window + * @ret rc return status code + */ +int wdeleteln ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + /* let's just set the cursor to the beginning of the line and + let wclrtoeol do the work :) */ + wmove( win, win->curs_y, 0 ); + wclrtoeol( win ); + _restore_curs_pos( win, &pos ); + return OK; +} + +/** + * Completely clear a window + * + * @v *win subject window + * @ret rc return status code + */ +int werase ( WINDOW *win ) { + wmove( win, 0, 0 ); + wclrtobot( win ); + return OK; +} + +/** + * Completely clear the screen + * + * @ret rc return status code + */ +int erase ( void ) { + stdscr->scr->erase( stdscr->scr, stdscr->attrs ); + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/colour.c b/qemu/roms/ipxe/src/hci/mucurses/colour.c new file mode 100644 index 000000000..c1359c868 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/colour.c @@ -0,0 +1,66 @@ +#include <curses.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct colour_pair { + short fcol; + short bcol; +}; + +static struct colour_pair cpairs[COLOUR_PAIRS] = { + [0] = { COLOUR_WHITE, COLOUR_BLACK }, +}; + +/** + * Identify the RGB components of a given colour value + * + * @v colour colour value + * @v *red address to store red component + * @v *green address to store green component + * @v *blue address to store blue component + * @ret rc return status code + */ +int colour_content ( short colour, short *red, short *green, short *blue ) { + *red = ( ( colour & COLOUR_RED ) ? 1 : 0 ); + *green = ( ( colour & COLOUR_GREEN ) ? 1 : 0 ); + *blue = ( ( colour & COLOUR_BLUE ) ? 1 : 0 ); + return OK; +} + +/** + * Initialise colour pair + * + * @v pair colour pair number + * @v fcol foreground colour + * @v bcol background colour + */ +int init_pair ( short pair, short fcol, short bcol ) { + struct colour_pair *cpair; + + if ( ( pair < 1 ) || ( pair >= COLOUR_PAIRS ) ) + return ERR; + + cpair = &cpairs[pair]; + cpair->fcol = fcol; + cpair->bcol = bcol; + return OK; +} + +/** + * Get colours of colour pair + * + * @v pair colour pair number + * @ret fcol foreground colour + * @ret bcol background colour + */ +int pair_content ( short pair, short *fcol, short *bcol ) { + struct colour_pair *cpair; + + if ( ( pair < 0 ) || ( pair >= COLOUR_PAIRS ) ) + return ERR; + + cpair = &cpairs[pair]; + *fcol = cpair->fcol; + *bcol = cpair->bcol; + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/cursor.h b/qemu/roms/ipxe/src/hci/mucurses/cursor.h new file mode 100644 index 000000000..16b7d27c2 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/cursor.h @@ -0,0 +1,37 @@ +#ifndef CURSOR_H +#define CURSOR_H + +/** @file + * + * MuCurses cursor implementation specific header file + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct cursor_pos { + unsigned int y, x; +}; + +/** + * Restore cursor position from encoded backup variable + * + * @v *win window on which to operate + * @v *pos pointer to struct in which original cursor position is stored + */ +static inline void _restore_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + wmove ( win, pos->y, pos->x ); +} + +/** + * Store cursor position for later restoration + * + * @v *win window on which to operate + * @v *pos pointer to struct in which to store cursor position + */ +static inline void _store_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + pos->y = win->curs_y; + pos->x = win->curs_x; +} + +#endif /* CURSOR_H */ diff --git a/qemu/roms/ipxe/src/hci/mucurses/edging.c b/qemu/roms/ipxe/src/hci/mucurses/edging.c new file mode 100644 index 000000000..eccd32422 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/edging.c @@ -0,0 +1,111 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses edging functions + * + */ + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v verch vertical chtype + * @v horch horizontal chtype + * @ret rc return status code + */ +int box ( WINDOW *win, chtype verch, chtype horch ) { + chtype corner = '+' | win->attrs; /* default corner character */ + return wborder( win, verch, verch, horch, horch, + corner, corner, corner, corner ); +} + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v ls left side + * @v rs right side + * @v ts top + * @v bs bottom + * @v tl top left corner + * @v tr top right corner + * @v bl bottom left corner + * @v br bottom right corner + * @ret rc return status code + */ +int wborder ( WINDOW *win, chtype ls, chtype rs, + chtype ts, chtype bs, chtype tl, + chtype tr, chtype bl, chtype br ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + wmove(win,0,0); + + _wputch(win,tl,WRAP); + while ( ( win->width - 1 ) - win->curs_x ) { + _wputch(win,ts,WRAP); + } + _wputch(win,tr,WRAP); + + while ( ( win->height - 1 ) - win->curs_y ) { + _wputch(win,ls,WRAP); + wmove(win,win->curs_y,(win->width)-1); + _wputch(win,rs,WRAP); + } + + _wputch(win,bl,WRAP); + while ( ( win->width -1 ) - win->curs_x ) { + _wputch(win,bs,WRAP); + } + _wputch(win,br,NOWRAP); /* do not wrap last char to leave + cursor in last position */ + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Create a horizontal line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of chars (wide) to render + * @ret rc return status code + */ +int whline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_x - win->width ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} + +/** + * Create a vertical line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of chars (high) to render + * @ret rc return status code + */ +int wvline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_y - win->height ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + wmove( win, ++(win->curs_y), pos.x); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/kb.c b/qemu/roms/ipxe/src/hci/mucurses/kb.c new file mode 100644 index 000000000..b38c8c146 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/kb.c @@ -0,0 +1,143 @@ +#include <curses.h> +#include <stddef.h> +#include <unistd.h> +#include "mucurses.h" + +/** @file + * + * MuCurses keyboard input handling functions + */ + +#define INPUT_DELAY 200 // half-blocking delay timer resolution (ms) +#define INPUT_DELAY_TIMEOUT 1000 // half-blocking delay timeout + +int m_delay; /* + < 0 : blocking read + 0 : non-blocking read + > 0 : timed blocking read + */ +bool m_echo; +bool m_cbreak; + +static int _wgetc ( WINDOW *win ) { + int timer, c; + + if ( win == NULL ) + return ERR; + + timer = INPUT_DELAY_TIMEOUT; + while ( ! win->scr->peek( win->scr ) ) { + if ( m_delay == 0 ) // non-blocking read + return ERR; + if ( timer > 0 ) { // time-limited blocking read + if ( m_delay > 0 ) + timer -= INPUT_DELAY; + mdelay( INPUT_DELAY ); + } else { return ERR; } // non-blocking read + } + + c = win->scr->getc( win->scr ); + + if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters + _wputch( win, (chtype) ( c | win->attrs ), WRAP ); + + return c; +} + +/** + * Pop a character from the FIFO into a window + * + * @v *win window in which to echo input + * @ret c char from input stream + */ +int wgetch ( WINDOW *win ) { + int c; + + c = _wgetc( win ); + + if ( m_echo ) { + if ( c >= KEY_MIN ) { + switch(c) { + case KEY_LEFT : + case KEY_BACKSPACE : + _wcursback( win ); + wdelch( win ); + break; + default : + beep(); + break; + } + } else { + _wputch( win, (chtype)( c | win->attrs ), WRAP ); + } + } + + return c; +} + +/** + * Read at most n characters from the FIFO into a window + * + * @v *win window in which to echo input + * @v *str pointer to string in which to store result + * @v n maximum number of characters to read into string (inc. NUL) + * @ret rc return status code + */ +int wgetnstr ( WINDOW *win, char *str, int n ) { + char *_str; + int c; + + if ( n == 0 ) { + *str = '\0'; + return OK; + } + + _str = str; + + while ( ( c = _wgetc( win ) ) != ERR ) { + /* termination enforcement - don't let us go past the + end of the allocated buffer... */ + if ( n == 0 && ( c >= 32 && c <= 126 ) ) { + _wcursback( win ); + wdelch( win ); + } else { + if ( c >= KEY_MIN ) { + switch(c) { + case KEY_LEFT : + case KEY_BACKSPACE : + _wcursback( win ); + wdelch( win ); + break; + case KEY_ENTER : + *_str = '\0'; + return OK; + default : + beep(); + break; + } + } + if ( c >= 32 && c <= 126 ) { + *(_str++) = c; n--; + } + } + } + + return ERR; +} + + +/** + * + */ +int echo ( void ) { + m_echo = TRUE; + return OK; +} + +/** + * + */ +int noecho ( void ) { + m_echo = FALSE; + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/mucurses.c b/qemu/roms/ipxe/src/hci/mucurses/mucurses.c new file mode 100644 index 000000000..b67445baf --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/mucurses.c @@ -0,0 +1,156 @@ +#include <curses.h> +#include "mucurses.h" + +/** @file + * + * MuCurses core functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +static void _wupdcurs ( WINDOW *win ) __nonnull; +void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull; +void _wputc ( WINDOW *win, char c, int wrap ) __nonnull; +void _wcursback ( WINDOW *win ) __nonnull; +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull; +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull; +int wmove ( WINDOW *win, int y, int x ) __nonnull; + +WINDOW _stdscr = { + .attrs = A_DEFAULT, + .ori_y = 0, + .ori_x = 0, + .curs_y = 0, + .curs_x = 0, + .scr = &_ansi_screen, +}; + +/* + * Primitives + */ + +/** + * Update cursor position + * + * @v *win window in which to update position + */ +static void _wupdcurs ( WINDOW *win ) { + win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y, + win->ori_x + win->curs_x ); +} + +/** + * Write a single character rendition to a window + * + * @v *win window in which to write + * @v ch character rendition to write + * @v wrap wrap "switch" + */ +void _wputch ( WINDOW *win, chtype ch, int wrap ) { + /* make sure we set the screen cursor to the right position + first! */ + _wupdcurs(win); + win->scr->putc(win->scr, ch); + if ( ++(win->curs_x) - win->width == 0 ) { + if ( wrap == WRAP ) { + win->curs_x = 0; + /* specification says we should really scroll, + but we have no buffer to scroll with, so we + can only overwrite back at the beginning of + the window */ + if ( ++(win->curs_y) - win->height == 0 ) + win->curs_y = 0; + } else { + (win->curs_x)--; + } + } +} + +/** + * Write a single character to a window + * + * @v *win window in which to write + * @v c character rendition to write + * @v wrap wrap "switch" + */ +void _wputc ( WINDOW *win, char c, int wrap ) { + _wputch ( win, ( ( ( unsigned char ) c ) | win->attrs ), wrap ); +} + +/** + * Retreat the cursor back one position (useful for a whole host of + * ops) + * + * @v *win window in which to retreat + */ +void _wcursback ( WINDOW *win ) { + if ( win->curs_x == 0 ) { + if ( win->curs_y == 0 ) + win->curs_y = win->height - 1; + win->curs_x = win->width = 1; + } else { + win->curs_x--; + } + + _wupdcurs(win); +} + +/** + * Write a chtype string to a window + * + * @v *win window in which to write + * @v *chstr chtype string + * @v wrap wrap "switch" + * @v n write at most n chtypes + */ +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) { + for ( ; *chstr && n-- ; chstr++ ) { + _wputch(win,*chstr,wrap); + } +} + +/** + * Write a standard c-style string to a window + * + * @v *win window in which to write + * @v *str string + * @v wrap wrap "switch" + * @v n write at most n chars from *str + */ +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) { + for ( ; *str && n-- ; str++ ) { + _wputc ( win, *str, wrap ); + } +} + +/** + * Move a window's cursor to the specified position + * + * @v *win window to be operated on + * @v y Y position + * @v x X position + * @ret rc return status code + */ +int wmove ( WINDOW *win, int y, int x ) { + /* chech for out-of-bounds errors */ + if ( ( (unsigned)y >= win->height ) || + ( (unsigned)x >= win->width ) ) { + return ERR; + } + + win->curs_y = y; + win->curs_x = x; + _wupdcurs(win); + return OK; +} + +/** + * Set cursor visibility + * + * @v visibility cursor visibility + */ +int curs_set ( int visibility ) { + stdscr->scr->cursor ( stdscr->scr, visibility ); + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/mucurses.h b/qemu/roms/ipxe/src/hci/mucurses/mucurses.h new file mode 100644 index 000000000..7ac1086ac --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/mucurses.h @@ -0,0 +1,23 @@ +#ifndef _MUCURSES_H +#define _MUCURSES_H + +/** @file + * + * MuCurses core implementation specific header file + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#define WRAP 0 +#define NOWRAP 1 + +extern SCREEN _ansi_screen; + +extern void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull; +extern void _wputc ( WINDOW *win, char c, int wrap ) __nonnull; +extern void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull; +extern void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull; +extern void _wcursback ( WINDOW *win ) __nonnull; + +#endif /* _MUCURSES_H */ diff --git a/qemu/roms/ipxe/src/hci/mucurses/print.c b/qemu/roms/ipxe/src/hci/mucurses/print.c new file mode 100644 index 000000000..9c682588b --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/print.c @@ -0,0 +1,86 @@ +#include <curses.h> +#include <stdio.h> +#include <stddef.h> +#include <ipxe/vsprintf.h> +#include "mucurses.h" + +/** @file + * + * MuCurses printing functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Add a single-byte character and rendition to a window and advance + * the cursor + * + * @v *win window to be rendered in + * @v ch character to be added at cursor + * @ret rc return status code + */ +int waddch ( WINDOW *win, const chtype ch ) { + _wputch( win, ch, WRAP ); + return OK; +} + +/** + * Add string of single-byte characters to a window + * + * @v *win window to be rendered in + * @v *str standard c-style string + * @v n max number of chars from string to render + * @ret rc return status code + */ +int waddnstr ( WINDOW *win, const char *str, int n ) { + _wputstr( win, str, WRAP, n ); + return OK; +} + +struct printw_context { + struct printf_context ctx; + WINDOW *win; +}; + +static void _printw_handler ( struct printf_context *ctx, unsigned int c ) { + struct printw_context *wctx = + container_of ( ctx, struct printw_context, ctx ); + + _wputch( wctx->win, c | wctx->win->attrs, WRAP ); +} + +/** + * Print formatted output in a window + * + * @v *win subject window + * @v *fmt formatted string + * @v varglist argument list + * @ret rc return status code + */ +int vw_printw ( WINDOW *win, const char *fmt, va_list varglist ) { + struct printw_context wctx; + + wctx.win = win; + wctx.ctx.handler = _printw_handler; + vcprintf ( &(wctx.ctx), fmt, varglist ); + return OK; +} + +/** + * Print formatted output to a window + * + * @v *win subject window + * @v *fmt formatted string + * @v ... string arguments + * @ret rc return status code + */ +int wprintw ( WINDOW *win, const char *fmt, ... ) { + va_list args; + int i; + + va_start ( args, fmt ); + i = vw_printw ( win, fmt, args ); + va_end ( args ); + return i; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c b/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c new file mode 100644 index 000000000..ee472e685 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c @@ -0,0 +1,26 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses printing functions (no cursor advance) + * + */ + +/** + * Add string of single-byte characters and renditions to a window + * + * @v *win window to be rendered in + * @v *chstr pointer to first chtype in "string" + * @v n max number of chars from chstr to render + * @ret rc return status code + */ +int waddchnstr ( WINDOW *win, const chtype *chstr, int n ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + _wputchstr( win, chstr, NOWRAP, n ); + _restore_curs_pos( win, &pos ); + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/slk.c b/qemu/roms/ipxe/src/hci/mucurses/slk.c new file mode 100644 index 000000000..600658e75 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/slk.c @@ -0,0 +1,363 @@ +#include <curses.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * Soft label key functions + */ + +#define MIN_SPACE_SIZE 2 + +#define SLK_MAX_LABEL_LEN 8 + +#define SLK_MAX_NUM_LABELS 12 + +#define SLK_MAX_NUM_SPACES 2 + +struct _softlabel { + // label string + char label[SLK_MAX_LABEL_LEN]; + /* Format of soft label + 0: left justify + 1: centre justify + 2: right justify + */ + unsigned int fmt; +}; + +struct _softlabelkeys { + struct _softlabel fkeys[SLK_MAX_NUM_LABELS]; + attr_t attrs; + /* Soft label layout format + 0: 3-2-3 + 1: 4-4 + 2: 4-4-4 + 3: 4-4-4 with index line + */ + unsigned int fmt; + unsigned int max_label_len; + unsigned int maj_space_len; + unsigned int num_labels; + unsigned int num_spaces; + unsigned int spaces[SLK_MAX_NUM_SPACES]; + struct cursor_pos saved_cursor; + attr_t saved_attrs; + short saved_pair; +}; + +static struct _softlabelkeys *slks; + +/* + I either need to break the primitives here, or write a collection of + functions specifically for SLKs that directly access the screen + functions - since this technically isn't part of stdscr, I think + this should be ok... + */ + +static void _enter_slk ( void ) { + _store_curs_pos ( stdscr, &slks->saved_cursor ); + wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL ); + LINES++; + wmove ( stdscr, LINES, 0 ); + wattrset ( stdscr, slks->attrs ); +} + +static void _leave_slk ( void ) { + LINES--; + wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL ); + _restore_curs_pos ( stdscr, &slks->saved_cursor ); +} + +static void _print_label ( struct _softlabel sl ) { + int space_ch; + char str[SLK_MAX_LABEL_LEN + 1]; + + assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN ); + space_ch = ' '; + + // protect against gaps in the soft label keys array + if ( sl.label == NULL ) { + memset( str, space_ch, (size_t)(slks->max_label_len) ); + } else { + /* we need to pad the label with varying amounts of leading + pad depending on the format of the label */ + if ( sl.fmt == 1 ) { + memset( str, space_ch, + (size_t)(slks->max_label_len + - strlen(sl.label)) / 2 ); + } + if ( sl.fmt == 2 ) { + memset( str, space_ch, + (size_t)(slks->max_label_len + - strlen(sl.label)) ); + } + strcat(str,sl.label); + + // post-padding + memset(str+strlen(str), space_ch, + (size_t)(slks->max_label_len - strlen(str)) ); + } + + // print the formatted label + _wputstr ( stdscr, str, NOWRAP, slks->max_label_len ); +} + +/** + * Return the attribute used for the soft function keys + * + * @ret attrs the current attributes of the soft function keys + */ +attr_t slk_attr ( void ) { + return ( slks == NULL ? 0 : slks->attrs ); +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attroff ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs &= ~( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attron ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs |= ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attrset ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs = ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_off ( const attr_t attrs, void *opts __unused ) { + return slk_attroff( attrs ); +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_on ( attr_t attrs, void *opts __unused ) { + return slk_attron( attrs ); +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_set ( const attr_t attrs, short colour_pair_number, + void *opts __unused ) { + if ( slks == NULL ) + return ERR; + + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) | + ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Clear the soft function key labels from the screen + * + * @ret rc return status code + */ +int slk_clear ( void ) { + if ( slks == NULL ) + return ERR; + + _enter_slk(); + wclrtoeol ( stdscr ); + _leave_slk(); + + return OK; +} + +/** + * Set soft label colour pair + */ +int slk_colour ( short colour_pair_number ) { + if ( slks == NULL ) + return ERR; + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) + | ( slks->attrs & A_ATTRIBUTES ); + + return OK; +} + +/** + * Initialise the soft function keys + * + * @v fmt format of keys + * @ret rc return status code + */ +int slk_init ( int fmt ) { + unsigned short nmaj, nmin, nblocks, available_width; + + if ( (unsigned)fmt > 3 ) { + return ERR; + } + + /* There seems to be no API call to free this data structure... */ + if ( ! slks ) + slks = calloc(1,sizeof(*slks)); + if ( ! slks ) + return ERR; + + slks->attrs = A_DEFAULT; + slks->fmt = fmt; + switch(fmt) { + case 0: + nblocks = 8; nmaj = 2; nmin = 5; + slks->spaces[0] = 2; slks->spaces[1] = 4; + break; + case 1: + nblocks = 8; nmaj = 1; nmin = 6; + slks->spaces[0] = 3; + break; + case 2: + // same allocations as format 3 + case 3: + nblocks = 12; nmaj = 2; nmin = 9; + slks->spaces[0] = 3; slks->spaces[1] = 7; + break; + default: + nblocks = 0; nmaj = 0; nmin = 0; + break; + } + + // determine maximum label length and major space size + available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin ); + slks->max_label_len = available_width / nblocks; + slks->maj_space_len = MIN_SPACE_SIZE + + ( available_width % nblocks ) / nmaj; + slks->num_spaces = nmaj; + slks->num_labels = nblocks; + + // strip a line from the screen + LINES -= 1; + + return OK; +} + +/** + * Return the label for the specified soft key + * + * @v labnum soft key identifier + * @ret label return label + */ +char* slk_label ( int labnum ) { + if ( slks == NULL ) + return NULL; + + return slks->fkeys[labnum].label; +} + +/** + * Restore soft function key labels to the screen + * + * @ret rc return status code + */ +int slk_restore ( void ) { + unsigned int i, j, pos_x, + *next_space, *last_space; + chtype space_ch; + + if ( slks == NULL ) + return ERR; + + pos_x = 0; + + _enter_slk(); + + space_ch = (chtype)' ' | slks->attrs; + next_space = &(slks->spaces[0]); + last_space = &(slks->spaces[slks->num_spaces-1]); + + for ( i = 0; i < slks->num_labels ; i++ ) { + _print_label( slks->fkeys[i] ); + pos_x += slks->max_label_len; + + if ( i == *next_space ) { + for ( j = 0; j < slks->maj_space_len; j++, pos_x++ ) + _wputch ( stdscr, space_ch, NOWRAP ); + if ( next_space < last_space ) + next_space++; + } else { + if ( pos_x < COLS ) + _wputch ( stdscr, space_ch, NOWRAP ); + pos_x++; + } + } + + _leave_slk(); + + return OK; +} + +/** + * Configure specified soft key + * + * @v labnum soft label position to configure + * @v *label string to use as soft key label + * @v fmt justification format of label + * @ret rc return status code + */ +int slk_set ( int labnum, const char *label, int fmt ) { + if ( slks == NULL ) + return ERR; + if ( (unsigned short)labnum >= slks->num_labels ) + return ERR; + if ( (unsigned short)fmt >= 3 ) + return ERR; + + strncpy(slks->fkeys[labnum].label, label, + sizeof(slks->fkeys[labnum].label)); + slks->fkeys[labnum].fmt = fmt; + + return OK; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c b/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c new file mode 100644 index 000000000..630a66e0b --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <string.h> +#include <assert.h> +#include <ipxe/editbox.h> + +/** @file + * + * Editable text box widget + * + */ + +#define EDITBOX_MIN_CHARS 3 + +/** + * Initialise text box widget + * + * @v box Editable text box widget + * @v buf Text buffer + * @v len Size of text buffer + * @v win Containing window + * @v row Row + * @v col Starting column + * @v width Width + * @v flags Flags + */ +void init_editbox ( struct edit_box *box, char *buf, size_t len, + WINDOW *win, unsigned int row, unsigned int col, + unsigned int width, unsigned int flags ) { + memset ( box, 0, sizeof ( *box ) ); + init_editstring ( &box->string, buf, len ); + box->string.cursor = strlen ( buf ); + box->win = ( win ? win : stdscr ); + box->row = row; + box->col = col; + box->width = width; + box->flags = flags; +} + +/** + * Draw text box widget + * + * @v box Editable text box widget + * + */ +void draw_editbox ( struct edit_box *box ) { + size_t width = box->width; + char buf[ width + 1 ]; + signed int cursor_offset, underflow, overflow, first; + size_t len; + + /* Adjust starting offset so that cursor remains within box */ + cursor_offset = ( box->string.cursor - box->first ); + underflow = ( EDITBOX_MIN_CHARS - cursor_offset ); + overflow = ( cursor_offset - ( width - 1 ) ); + first = box->first; + if ( underflow > 0 ) { + first -= underflow; + if ( first < 0 ) + first = 0; + } else if ( overflow > 0 ) { + first += overflow; + } + box->first = first; + cursor_offset = ( box->string.cursor - first ); + + /* Construct underscore-padded string portion */ + memset ( buf, '_', width ); + buf[width] = '\0'; + len = ( strlen ( box->string.buf ) - first ); + if ( len > width ) + len = width; + if ( box->flags & EDITBOX_STARS ) { + memset ( buf, '*', len ); + } else { + memcpy ( buf, ( box->string.buf + first ), len ); + } + + /* Print box content and move cursor */ + if ( ! box->win ) + box->win = stdscr; + mvwprintw ( box->win, box->row, box->col, "%s", buf ); + wmove ( box->win, box->row, ( box->col + cursor_offset ) ); +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/winattrs.c b/qemu/roms/ipxe/src/hci/mucurses/winattrs.c new file mode 100644 index 000000000..f549d7519 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/winattrs.c @@ -0,0 +1,133 @@ +#include <curses.h> + +/** @file + * + * MuCurses window attribute functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Get the background rendition attributes for a window + * + * @v *win subject window + * @ret ch chtype rendition representation + */ +inline chtype getbkgd ( WINDOW *win ) { + return win->attrs; +} + +/** + * Turn off attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattroff ( WINDOW *win, int attrs ) { + win->attrs &= ~attrs; + return OK; +} + +/** + * Turn on attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattron ( WINDOW *win, int attrs ) { + win->attrs |= attrs; + return OK; +} + +/** + * Set attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattrset ( WINDOW *win, int attrs ) { + win->attrs = ( attrs | ( win->attrs & A_COLOR ) ); + return OK; +} + +/** + * Get attributes and colour pair information + * + * @v *win window to obtain information from + * @v *attrs address in which to store attributes + * @v *pair address in which to store colour pair + * @v *opts undefined (for future implementation) + * @ret rc return status cude + */ +int wattr_get ( WINDOW *win, attr_t *attrs, short *pair, + void *opts __unused ) { + *attrs = win->attrs & A_ATTRIBUTES; + *pair = PAIR_NUMBER ( win->attrs ); + return OK; +} + +/** + * Turn off attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_off ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattroff( win, attrs ); + return OK; +} + +/** + * Turn on attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_on ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattron( win, attrs ); + return OK; +} + +/** + * Set attributes and colour pair information in a window + * + * @v *win subject window + * @v attrs attributes to set + * @v cpair colour pair to set + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_set ( WINDOW *win, attr_t attrs, short cpair, + void *opts __unused ) { + wattrset( win, attrs | COLOUR_PAIR ( cpair ) ); + return OK; +} + +/** + * Set colour pair for a window + * + * @v *win subject window + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wcolour_set ( WINDOW *win, short colour_pair_number, + void *opts __unused ) { + if ( ( unsigned short )colour_pair_number > COLOUR_PAIRS ) + return ERR; + + win->attrs = ( ( win->attrs & A_ATTRIBUTES ) | + COLOUR_PAIR ( colour_pair_number ) ); + return OK; +} + diff --git a/qemu/roms/ipxe/src/hci/mucurses/windows.c b/qemu/roms/ipxe/src/hci/mucurses/windows.c new file mode 100644 index 000000000..63d0af08c --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/windows.c @@ -0,0 +1,158 @@ +#include <curses.h> +#include <stddef.h> +#include <stdlib.h> +#include "mucurses.h" + +/** @file + * + * MuCurses windows instance functions + * + */ + +/** + * Delete a window + * + * @v *win pointer to window being deleted + * @ret rc return status code + */ +int delwin ( WINDOW *win ) { + if ( win == NULL ) + return ERR; + + /* I think we should blank the region covered by the window - + ncurses doesn't do this, but they have a buffer, so they + may just be deleting from an offscreen context whereas we + are guaranteed to be deleting something onscreen */ + wmove( win, 0, 0 ); + chtype killch = (chtype)' '; + do { + _wputch( win, killch, WRAP ); + } while ( win->curs_x + win->curs_y ); + + free( win ); + + wmove ( stdscr, 0, 0 ); + + return OK; +} + +/** + * Create a new derived window + * + * @v parent parent window + * @v nlines window height + * @v ncols window width + * @v begin_y window y origin (relative to parent) + * @v begin_x window x origin (relative to parent) + * @ret ptr return pointer to child window + */ +WINDOW *derwin ( WINDOW *parent, int nlines, int ncols, + int begin_y, int begin_x ) { + WINDOW *child; + if ( parent == NULL ) + return NULL; + if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + if ( ( (unsigned)ncols > parent->width ) || + ( (unsigned)nlines > parent->height ) ) + return NULL; + child->ori_y = parent->ori_y + begin_y; + child->ori_x = parent->ori_x + begin_x; + child->height = nlines; + child->width = ncols; + child->parent = parent; + child->scr = parent->scr; + return child; +} + +/** + * Create a duplicate of the specified window + * + * @v orig original window + * @ret ptr pointer to duplicate window + */ +WINDOW *dupwin ( WINDOW *orig ) { + WINDOW *copy; + if ( orig == NULL ) + return NULL; + if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + copy->scr = orig->scr; + copy->attrs = orig->attrs; + copy->ori_y = orig->ori_y; + copy->ori_x = orig->ori_x; + copy->curs_y = orig->curs_y; + copy->curs_x = orig->curs_x; + copy->height = orig->height; + copy->width = orig->width; + return copy; +} + +/** + * Move window origin to specified coordinates + * + * @v *win window to move + * @v y Y position + * @v x X position + * @ret rc return status code + */ +int mvwin ( WINDOW *win, int y, int x ) { + if ( win == NULL ) + return ERR; + if ( ( ( (unsigned)y + win->height ) > LINES ) || + ( ( (unsigned)x + win->width ) > COLS ) ) + return ERR; + + win->ori_y = y; + win->ori_x = x; + + return OK; +} + +/** + * Create new WINDOW + * + * @v nlines number of lines + * @v ncols number of columns + * @v begin_y column origin + * @v begin_x line origin + * @ret *win return pointer to new window + */ +WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) { + WINDOW *win; + if ( ( win = malloc( sizeof(WINDOW) ) ) == NULL ) + return NULL; + if ( ( (unsigned)( begin_y + nlines ) > stdscr->height ) && + ( (unsigned)( begin_x + ncols ) > stdscr->width ) ) + return NULL; + win->ori_y = begin_y; + win->ori_x = begin_x; + win->height = nlines; + win->width = ncols; + win->scr = stdscr->scr; + win->parent = stdscr; + return win; +} + +/** + * Create a new sub-window + * + * @v orig parent window + * @v nlines window height + * @v ncols window width + * @v begin_y window y origin (absolute) + * @v begin_x window x origin (absolute) + * @ret ptr return pointer to child window + */ +WINDOW *subwin ( WINDOW *parent, int nlines, int ncols, + int begin_y, int begin_x ) { + WINDOW *child; + if ( parent == NULL ) + return NULL; + if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + child = newwin( nlines, ncols, begin_y, begin_x ); + child->parent = parent; + child->scr = parent->scr; + return child; +} diff --git a/qemu/roms/ipxe/src/hci/mucurses/wininit.c b/qemu/roms/ipxe/src/hci/mucurses/wininit.c new file mode 100644 index 000000000..b75abba44 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/mucurses/wininit.c @@ -0,0 +1,38 @@ +#include <stddef.h> +#include <curses.h> + +/** @file + * + * MuCurses initialisation functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Initialise console environment + * + * @ret *win return pointer to stdscr + */ +WINDOW *initscr ( void ) { + /* determine console size */ + /* initialise screen */ + stdscr->scr->init( stdscr->scr ); + stdscr->height = LINES; + stdscr->width = COLS; + move ( 0, 0 ); + return stdscr; +} + +/** + * Finalise console environment + * + */ +int endwin ( void ) { + attrset ( 0 ); + color_set ( 0, NULL ); + curs_set ( 1 ); + mvprintw ( ( LINES - 1 ), 0, "\n" ); + stdscr->scr->exit( stdscr->scr ); + return OK; +} |