From 437fd90c0250dee670290f9b714253671a990160 Mon Sep 17 00:00:00 2001 From: José Pekkarinen Date: Wed, 18 May 2016 13:18:31 +0300 Subject: These changes are the raw update to qemu-2.6. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collission happened in the following patches: migration: do cleanup operation after completion(738df5b9) Bug fix.(1750c932f86) kvmclock: add a new function to update env->tsc.(b52baab2) The code provided by the patches was already in the upstreamed version. Change-Id: I3cc11841a6a76ae20887b2e245710199e1ea7f9a Signed-off-by: José Pekkarinen --- qemu/roms/ipxe/src/hci/tui/login_ui.c | 6 +- qemu/roms/ipxe/src/hci/tui/menu_ui.c | 102 ++++----- qemu/roms/ipxe/src/hci/tui/settings_ui.c | 355 ++++++++++++++----------------- 3 files changed, 198 insertions(+), 265 deletions(-) (limited to 'qemu/roms/ipxe/src/hci/tui') diff --git a/qemu/roms/ipxe/src/hci/tui/login_ui.c b/qemu/roms/ipxe/src/hci/tui/login_ui.c index 996b68a0a..3c55325d5 100644 --- a/qemu/roms/ipxe/src/hci/tui/login_ui.c +++ b/qemu/roms/ipxe/src/hci/tui/login_ui.c @@ -15,9 +15,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * diff --git a/qemu/roms/ipxe/src/hci/tui/menu_ui.c b/qemu/roms/ipxe/src/hci/tui/menu_ui.c index 0a9566def..f9dd9d100 100644 --- a/qemu/roms/ipxe/src/hci/tui/menu_ui.c +++ b/qemu/roms/ipxe/src/hci/tui/menu_ui.c @@ -15,9 +15,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * @@ -32,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include /* Screen layout */ @@ -46,12 +51,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); struct menu_ui { /** Menu */ struct menu *menu; - /** Number of menu items */ - unsigned int count; - /** Currently selected item */ - int selected; - /** First visible item */ - int first_visible; + /** Jump scroller */ + struct jump_scroller scroll; /** Timeout (0=indefinite) */ unsigned long timeout; }; @@ -80,7 +81,7 @@ static struct menu_item * menu_item ( struct menu *menu, unsigned int index ) { * @v ui Menu user interface * @v index Index */ -static void draw_menu_item ( struct menu_ui *ui, int index ) { +static void draw_menu_item ( struct menu_ui *ui, unsigned int index ) { struct menu_item *item; unsigned int row_offset; char buf[ MENU_COLS + 1 /* NUL */ ]; @@ -90,7 +91,7 @@ static void draw_menu_item ( struct menu_ui *ui, int index ) { size_t len; /* Move to start of row */ - row_offset = ( index - ui->first_visible ); + row_offset = ( index - ui->scroll.first ); move ( ( MENU_ROW + row_offset ), MENU_COL ); /* Get menu item */ @@ -102,7 +103,7 @@ static void draw_menu_item ( struct menu_ui *ui, int index ) { color_set ( CPAIR_SEPARATOR, NULL ); /* Highlight if this is the selected item */ - if ( index == ui->selected ) { + if ( index == ui->scroll.current ) { color_set ( CPAIR_SELECT, NULL ); attron ( A_BOLD ); } @@ -121,7 +122,7 @@ static void draw_menu_item ( struct menu_ui *ui, int index ) { snprintf ( timeout_buf, sizeof ( timeout_buf ), "(%ld)", ( ( ui->timeout + TICKS_PER_SEC - 1 ) / TICKS_PER_SEC ) ); - if ( ( index == ui->selected ) && ( ui->timeout != 0 ) ) { + if ( ( index == ui->scroll.current ) && ( ui->timeout != 0 ) ) { memcpy ( ( buf + MENU_COLS - MENU_PAD - timeout_len ), timeout_buf, timeout_len ); } @@ -150,24 +151,17 @@ static void draw_menu_item ( struct menu_ui *ui, int index ) { static void draw_menu_items ( struct menu_ui *ui ) { unsigned int i; - /* Jump scroll to correct point in list */ - while ( ui->first_visible < ui->selected ) - ui->first_visible += MENU_ROWS; - while ( ui->first_visible > ui->selected ) - ui->first_visible -= MENU_ROWS; - /* Draw ellipses before and/or after the list as necessary */ color_set ( CPAIR_SEPARATOR, NULL ); mvaddstr ( ( MENU_ROW - 1 ), ( MENU_COL + MENU_PAD ), - ( ( ui->first_visible > 0 ) ? "..." : " " ) ); + ( jump_scroll_is_first ( &ui->scroll ) ? " " : "..." ) ); mvaddstr ( ( MENU_ROW + MENU_ROWS ), ( MENU_COL + MENU_PAD ), - ( ( ( ui->first_visible + MENU_ROWS ) < ui->count ) ? - "..." : " " ) ); + ( jump_scroll_is_last ( &ui->scroll ) ? " " : "..." ) ); color_set ( CPAIR_NORMAL, NULL ); /* Draw visible items */ for ( i = 0 ; i < MENU_ROWS ; i++ ) - draw_menu_item ( ui, ( ui->first_visible + i ) ); + draw_menu_item ( ui, ( ui->scroll.first + i ) ); } /** @@ -180,8 +174,7 @@ static void draw_menu_items ( struct menu_ui *ui ) { static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { struct menu_item *item; unsigned long timeout; - unsigned int delta; - int current; + unsigned int previous; int key; int i; int move; @@ -190,7 +183,7 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { do { /* Record current selection */ - current = ui->selected; + previous = ui->scroll.current; /* Calculate timeout as remainder of current second */ timeout = ( ui->timeout % TICKS_PER_SEC ); @@ -209,27 +202,11 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { /* Cancel any timeout */ ui->timeout = 0; - /* Handle key */ + /* Handle scroll keys */ + move = jump_scroll_key ( &ui->scroll, key ); + + /* Handle other keys */ switch ( key ) { - case KEY_UP: - move = -1; - break; - case KEY_DOWN: - move = +1; - break; - case KEY_PPAGE: - move = ( ui->first_visible - ui->selected - 1 ); - break; - case KEY_NPAGE: - move = ( ui->first_visible - ui->selected - + MENU_ROWS ); - break; - case KEY_HOME: - move = -ui->count; - break; - case KEY_END: - move = +ui->count; - break; case ESC: case CTRL_C: rc = -ECANCELED; @@ -247,7 +224,7 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { i++; continue; } - ui->selected = i; + ui->scroll.current = i; if ( item->label ) { chosen = 1; } else { @@ -260,31 +237,22 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { /* Move selection, if applicable */ while ( move ) { - ui->selected += move; - if ( ui->selected < 0 ) { - ui->selected = 0; - move = +1; - } else if ( ui->selected >= ( int ) ui->count ) { - ui->selected = ( ui->count - 1 ); - move = -1; - } - item = menu_item ( ui->menu, ui->selected ); + move = jump_scroll_move ( &ui->scroll, move ); + item = menu_item ( ui->menu, ui->scroll.current ); if ( item->label ) break; - move = ( ( move > 0 ) ? +1 : -1 ); } /* Redraw selection if necessary */ - if ( ( ui->selected != current ) || ( timeout != 0 ) ) { - draw_menu_item ( ui, current ); - delta = ( ui->selected - ui->first_visible ); - if ( delta >= MENU_ROWS ) + if ( ( ui->scroll.current != previous ) || ( timeout != 0 ) ) { + draw_menu_item ( ui, previous ); + if ( jump_scroll ( &ui->scroll ) ) draw_menu_items ( ui ); - draw_menu_item ( ui, ui->selected ); + draw_menu_item ( ui, ui->scroll.current ); } /* Record selection */ - item = menu_item ( ui->menu, ui->selected ); + item = menu_item ( ui->menu, ui->scroll.current ); assert ( item != NULL ); assert ( item->label != NULL ); *selected = item; @@ -313,21 +281,22 @@ int show_menu ( struct menu *menu, unsigned long timeout, /* Initialise UI */ memset ( &ui, 0, sizeof ( ui ) ); ui.menu = menu; + ui.scroll.rows = MENU_ROWS; ui.timeout = timeout; list_for_each_entry ( item, &menu->items, list ) { if ( item->label ) { if ( ! labelled_count ) - ui.selected = ui.count; + ui.scroll.current = ui.scroll.count; labelled_count++; if ( select ) { if ( strcmp ( select, item->label ) == 0 ) - ui.selected = ui.count; + ui.scroll.current = ui.scroll.count; } else { if ( item->is_default ) - ui.selected = ui.count; + ui.scroll.current = ui.scroll.count; } } - ui.count++; + ui.scroll.count++; } if ( ! labelled_count ) { /* Menus with no labelled items cannot be selected @@ -349,8 +318,9 @@ int show_menu ( struct menu *menu, unsigned long timeout, snprintf ( buf, sizeof ( buf ), "%s", ui.menu->title ); mvprintw ( TITLE_ROW, ( ( COLS - strlen ( buf ) ) / 2 ), "%s", buf ); attroff ( A_BOLD ); + jump_scroll ( &ui.scroll ); draw_menu_items ( &ui ); - draw_menu_item ( &ui, ui.selected ); + draw_menu_item ( &ui, ui.scroll.current ); /* Enter main loop */ rc = menu_loop ( &ui, selected ); diff --git a/qemu/roms/ipxe/src/hci/tui/settings_ui.c b/qemu/roms/ipxe/src/hci/tui/settings_ui.c index 221839730..be421cc0a 100644 --- a/qemu/roms/ipxe/src/hci/tui/settings_ui.c +++ b/qemu/roms/ipxe/src/hci/tui/settings_ui.c @@ -15,9 +15,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include @@ -29,7 +33,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include +#include /** @file * @@ -47,7 +53,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define INSTRUCTION_ROW ( LINES - 2U ) #define INSTRUCTION_PAD " " -/** Layout of text within a setting widget */ +/** Layout of text within a setting row */ #define SETTING_ROW_TEXT( cols ) struct { \ char start[0]; \ char pad1[1]; \ @@ -63,8 +69,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); char nul; \ } __attribute__ (( packed )) -/** A setting row widget */ -struct setting_row_widget { +/** A settings user interface row */ +struct settings_ui_row { /** Target configuration settings block * * Valid only for rows that lead to new settings blocks. @@ -82,8 +88,6 @@ struct setting_row_widget { struct setting setting; /** Screen row */ unsigned int row; - /** Screen column */ - unsigned int col; /** Edit box widget used for editing setting */ struct edit_box editbox; /** Editing in progress flag */ @@ -92,28 +96,24 @@ struct setting_row_widget { char value[256]; /* enough size for a DHCP string */ }; -/** A settings widget */ -struct setting_widget { +/** A settings user interface */ +struct settings_ui { /** Settings block */ struct settings *settings; - /** Number of rows */ - unsigned int num_rows; - /** Current row index */ - unsigned int current; - /** Index of the first visible row, for scrolling. */ - unsigned int first_visible; - /** Active row */ - struct setting_row_widget row; + /** Jump scroller */ + struct jump_scroller scroll; + /** Current row */ + struct settings_ui_row row; }; /** - * Select a setting row + * Select a setting * - * @v widget Setting widget + * @v ui Settings user interface * @v index Index of setting row - * @ret count Number of settings rows + * @ret count Number of setting rows */ -static unsigned int select_setting_row ( struct setting_widget *widget, +static unsigned int select_setting_row ( struct settings_ui *ui, unsigned int index ) { SETTING_ROW_TEXT ( COLS ) *text; struct settings *settings; @@ -122,25 +122,22 @@ static unsigned int select_setting_row ( struct setting_widget *widget, unsigned int count = 0; /* Initialise structure */ - memset ( &widget->row, 0, sizeof ( widget->row ) ); - widget->current = index; - widget->row.row = ( SETTINGS_LIST_ROW + index - widget->first_visible ); - widget->row.col = SETTINGS_LIST_COL; + memset ( &ui->row, 0, sizeof ( ui->row ) ); + ui->row.row = ( SETTINGS_LIST_ROW + index - ui->scroll.first ); /* Include parent settings block, if applicable */ - if ( widget->settings->parent && ( count++ == index ) ) { - widget->row.settings = widget->settings->parent; - snprintf ( widget->row.value, sizeof ( widget->row.value ), + if ( ui->settings->parent && ( count++ == index ) ) { + ui->row.settings = ui->settings->parent; + snprintf ( ui->row.value, sizeof ( ui->row.value ), "../" ); } /* Include any child settings blocks, if applicable */ - list_for_each_entry ( settings, &widget->settings->children, siblings ){ + list_for_each_entry ( settings, &ui->settings->children, siblings ) { if ( count++ == index ) { - widget->row.settings = settings; - snprintf ( widget->row.value, - sizeof ( widget->row.value ), "%s/", - settings->name ); + ui->row.settings = settings; + snprintf ( ui->row.value, sizeof ( ui->row.value ), + "%s/", settings->name ); } } @@ -148,7 +145,7 @@ static unsigned int select_setting_row ( struct setting_widget *widget, for_each_table_entry ( setting, SETTINGS ) { /* Skip inapplicable settings */ - if ( ! setting_applies ( widget->settings, setting ) ) + if ( ! setting_applies ( ui->settings, setting ) ) continue; /* Skip duplicate settings */ @@ -158,18 +155,16 @@ static unsigned int select_setting_row ( struct setting_widget *widget, /* Read current setting value and origin */ if ( count++ == index ) { - fetchf_setting ( widget->settings, setting, - &widget->row.origin, - &widget->row.setting, - widget->row.value, - sizeof ( widget->row.value ) ); + fetchf_setting ( ui->settings, setting, &ui->row.origin, + &ui->row.setting, ui->row.value, + sizeof ( ui->row.value ) ); } } /* Initialise edit box */ - init_editbox ( &widget->row.editbox, widget->row.value, - sizeof ( widget->row.value ), NULL, widget->row.row, - ( widget->row.col + + init_editbox ( &ui->row.editbox, ui->row.value, + sizeof ( ui->row.value ), NULL, ui->row.row, + ( SETTINGS_LIST_COL + offsetof ( typeof ( *text ), u.setting.value ) ), sizeof ( text->u.setting.value ), 0 ); @@ -197,9 +192,9 @@ static size_t string_copy ( char *dest, const char *src, size_t len ) { /** * Draw setting row * - * @v widget Setting widget + * @v ui Settings UI */ -static void draw_setting_row ( struct setting_widget *widget ) { +static void draw_setting_row ( struct settings_ui *ui ) { SETTING_ROW_TEXT ( COLS ) text; unsigned int curs_offset; char *value; @@ -209,12 +204,12 @@ static void draw_setting_row ( struct setting_widget *widget ) { text.nul = '\0'; /* Construct row content */ - if ( widget->row.settings ) { + if ( ui->row.settings ) { /* Construct space-padded name */ curs_offset = ( offsetof ( typeof ( text ), u.settings ) + string_copy ( text.u.settings, - widget->row.value, + ui->row.value, sizeof ( text.u.settings ) ) ); } else { @@ -222,11 +217,11 @@ static void draw_setting_row ( struct setting_widget *widget ) { /* Construct dot-padded name */ memset ( text.u.setting.name, '.', sizeof ( text.u.setting.name ) ); - string_copy ( text.u.setting.name, widget->row.setting.name, + string_copy ( text.u.setting.name, ui->row.setting.name, sizeof ( text.u.setting.name ) ); /* Construct space-padded value */ - value = widget->row.value; + value = ui->row.value; if ( ! *value ) value = ""; curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) + @@ -235,37 +230,34 @@ static void draw_setting_row ( struct setting_widget *widget ) { } /* Print row */ - if ( ( widget->row.origin == widget->settings ) || - ( widget->row.settings != NULL ) ) { + if ( ( ui->row.origin == ui->settings ) || ( ui->row.settings != NULL )) attron ( A_BOLD ); - } - mvprintw ( widget->row.row, widget->row.col, "%s", text.start ); + mvprintw ( ui->row.row, SETTINGS_LIST_COL, "%s", text.start ); attroff ( A_BOLD ); - move ( widget->row.row, widget->row.col + curs_offset ); + move ( ui->row.row, ( SETTINGS_LIST_COL + curs_offset ) ); } /** - * Edit setting widget + * Edit setting ui * - * @v widget Setting widget + * @v ui Settings UI * @v key Key pressed by user * @ret key Key returned to application, or zero */ -static int edit_setting ( struct setting_widget *widget, int key ) { - assert ( widget->row.setting.name != NULL ); - widget->row.editing = 1; - return edit_editbox ( &widget->row.editbox, key ); +static int edit_setting ( struct settings_ui *ui, int key ) { + assert ( ui->row.setting.name != NULL ); + ui->row.editing = 1; + return edit_editbox ( &ui->row.editbox, key ); } /** - * Save setting widget value back to configuration settings + * Save setting ui value back to configuration settings * - * @v widget Setting widget + * @v ui Settings UI */ -static int save_setting ( struct setting_widget *widget ) { - assert ( widget->row.setting.name != NULL ); - return storef_setting ( widget->settings, &widget->row.setting, - widget->row.value ); +static int save_setting ( struct settings_ui *ui ) { + assert ( ui->row.setting.name != NULL ); + return storef_setting ( ui->settings, &ui->row.setting, ui->row.value ); } /** @@ -340,15 +332,15 @@ static void alert ( const char *fmt, ... ) { /** * Draw title row * - * @v widget Setting widget + * @v ui Settings UI */ -static void draw_title_row ( struct setting_widget *widget ) { +static void draw_title_row ( struct settings_ui *ui ) { const char *name; clearmsg ( TITLE_ROW ); - name = settings_name ( widget->settings ); + name = settings_name ( ui->settings ); attron ( A_BOLD ); - msg ( TITLE_ROW, "iPXE configuration settings%s%s", + msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s", ( name[0] ? " - " : "" ), name ); attroff ( A_BOLD ); } @@ -356,89 +348,73 @@ static void draw_title_row ( struct setting_widget *widget ) { /** * Draw information row * - * @v widget Setting widget + * @v ui Settings UI */ -static void draw_info_row ( struct setting_widget *widget ) { +static void draw_info_row ( struct settings_ui *ui ) { char buf[32]; /* Draw nothing unless this row represents a setting */ clearmsg ( INFO_ROW ); clearmsg ( INFO_ROW + 1 ); - if ( ! widget->row.setting.name ) + if ( ! ui->row.setting.name ) return; /* Determine a suitable setting name */ - setting_name ( ( widget->row.origin ? - widget->row.origin : widget->settings ), - &widget->row.setting, buf, sizeof ( buf ) ); + setting_name ( ( ui->row.origin ? + ui->row.origin : ui->settings ), + &ui->row.setting, buf, sizeof ( buf ) ); /* Draw row */ attron ( A_BOLD ); - msg ( INFO_ROW, "%s - %s", buf, widget->row.setting.description ); + msg ( INFO_ROW, "%s - %s", buf, ui->row.setting.description ); attroff ( A_BOLD ); color_set ( CPAIR_URL, NULL ); - msg ( ( INFO_ROW + 1 ), "http://ipxe.org/cfg/%s", - widget->row.setting.name ); + msg ( ( INFO_ROW + 1 ), PRODUCT_SETTING_URI, ui->row.setting.name ); color_set ( CPAIR_NORMAL, NULL ); } /** * Draw instruction row * - * @v widget Setting widget + * @v ui Settings UI */ -static void draw_instruction_row ( struct setting_widget *widget ) { +static void draw_instruction_row ( struct settings_ui *ui ) { clearmsg ( INSTRUCTION_ROW ); - if ( widget->row.editing ) { + if ( ui->row.editing ) { msg ( INSTRUCTION_ROW, "Enter - accept changes" INSTRUCTION_PAD "Ctrl-C - discard changes" ); } else { msg ( INSTRUCTION_ROW, "%sCtrl-X - exit configuration utility", - ( ( widget->row.origin == widget->settings ) ? + ( ( ui->row.origin == ui->settings ) ? "Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) ); } } /** - * Reveal setting row + * Draw the current block of setting rows * - * @v widget Setting widget - * @v index Index of setting row + * @v ui Settings UI */ -static void reveal_setting_row ( struct setting_widget *widget, - unsigned int index ) { +static void draw_setting_rows ( struct settings_ui *ui ) { unsigned int i; - /* Simply return if setting N is already on-screen. */ - if ( index - widget->first_visible < SETTINGS_LIST_ROWS ) - return; - - /* Jump scroll to make the specified setting row visible. */ - while ( widget->first_visible < index ) - widget->first_visible += SETTINGS_LIST_ROWS; - while ( widget->first_visible > index ) - widget->first_visible -= SETTINGS_LIST_ROWS; - - /* Draw ellipses before and/or after the settings list to - * represent any invisible settings. - */ - mvaddstr ( SETTINGS_LIST_ROW - 1, - SETTINGS_LIST_COL + 1, - widget->first_visible > 0 ? "..." : " " ); - mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS, - SETTINGS_LIST_COL + 1, - ( ( widget->first_visible + SETTINGS_LIST_ROWS ) - < widget->num_rows ? "..." : " " ) ); + /* Draw ellipses before and/or after the list as necessary */ + color_set ( CPAIR_SEPARATOR, NULL ); + mvaddstr ( ( SETTINGS_LIST_ROW - 1 ), ( SETTINGS_LIST_COL + 1 ), + jump_scroll_is_first ( &ui->scroll ) ? " " : "..." ); + mvaddstr ( ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS ), + ( SETTINGS_LIST_COL + 1 ), + jump_scroll_is_last ( &ui->scroll ) ? " " : "..." ); + color_set ( CPAIR_NORMAL, NULL ); /* Draw visible settings. */ - for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) { - if ( ( widget->first_visible + i ) < widget->num_rows ) { - select_setting_row ( widget, - widget->first_visible + i ); - draw_setting_row ( widget ); + for ( i = 0 ; i < SETTINGS_LIST_ROWS ; i++ ) { + if ( ( ui->scroll.first + i ) < ui->scroll.count ) { + select_setting_row ( ui, ( ui->scroll.first + i ) ); + draw_setting_row ( ui ); } else { clearmsg ( SETTINGS_LIST_ROW + i ); } @@ -446,69 +422,72 @@ static void reveal_setting_row ( struct setting_widget *widget, } /** - * Reveal setting row + * Select settings block * - * @v widget Setting widget + * @v ui Settings UI * @v settings Settings block */ -static void init_widget ( struct setting_widget *widget, - struct settings *settings ) { - - widget->settings = settings_target ( settings ); - widget->num_rows = select_setting_row ( widget, 0 ); - widget->first_visible = SETTINGS_LIST_ROWS; - draw_title_row ( widget ); - reveal_setting_row ( widget, 0 ); - select_setting_row ( widget, 0 ); +static void select_settings ( struct settings_ui *ui, + struct settings *settings ) { + + ui->settings = settings_target ( settings ); + ui->scroll.count = select_setting_row ( ui, 0 ); + ui->scroll.rows = SETTINGS_LIST_ROWS; + ui->scroll.current = 0; + ui->scroll.first = 0; + draw_title_row ( ui ); + draw_setting_rows ( ui ); + select_setting_row ( ui, 0 ); } static int main_loop ( struct settings *settings ) { - struct setting_widget widget; + struct settings_ui ui; + unsigned int previous; int redraw = 1; int move; - unsigned int next; int key; int rc; /* Print initial screen content */ color_set ( CPAIR_NORMAL, NULL ); - memset ( &widget, 0, sizeof ( widget ) ); - init_widget ( &widget, settings ); + memset ( &ui, 0, sizeof ( ui ) ); + select_settings ( &ui, settings ); while ( 1 ) { /* Redraw rows if necessary */ if ( redraw ) { - draw_info_row ( &widget ); - draw_instruction_row ( &widget ); - color_set ( ( widget.row.editing ? + draw_info_row ( &ui ); + draw_instruction_row ( &ui ); + color_set ( ( ui.row.editing ? CPAIR_EDIT : CPAIR_SELECT ), NULL ); - draw_setting_row ( &widget ); + draw_setting_row ( &ui ); color_set ( CPAIR_NORMAL, NULL ); - curs_set ( widget.row.editing ); + curs_set ( ui.row.editing ); redraw = 0; } - if ( widget.row.editing ) { + /* Edit setting, if we are currently editing */ + if ( ui.row.editing ) { /* Sanity check */ - assert ( widget.row.setting.name != NULL ); + assert ( ui.row.setting.name != NULL ); /* Redraw edit box */ color_set ( CPAIR_EDIT, NULL ); - draw_editbox ( &widget.row.editbox ); + draw_editbox ( &ui.row.editbox ); color_set ( CPAIR_NORMAL, NULL ); /* Process keypress */ - key = edit_setting ( &widget, getkey ( 0 ) ); + key = edit_setting ( &ui, getkey ( 0 ) ); switch ( key ) { case CR: case LF: - if ( ( rc = save_setting ( &widget ) ) != 0 ) + if ( ( rc = save_setting ( &ui ) ) != 0 ) alert ( " %s ", strerror ( rc ) ); /* Fall through */ case CTRL_C: - select_setting_row ( &widget, widget.current ); + select_setting_row ( &ui, ui.scroll.current ); redraw = 1; break; default: @@ -516,72 +495,52 @@ static int main_loop ( struct settings *settings ) { break; } - } else { + continue; + } - /* Process keypress */ - key = getkey ( 0 ); - move = 0; - switch ( key ) { - case KEY_UP: - move = -1; - break; - case KEY_DOWN: - move = +1; - break; - case KEY_PPAGE: - move = ( widget.first_visible - - widget.current - 1 ); - break; - case KEY_NPAGE: - move = ( widget.first_visible - widget.current - + SETTINGS_LIST_ROWS ); - break; - case KEY_HOME: - move = -widget.num_rows; - break; - case KEY_END: - move = +widget.num_rows; - break; - case CTRL_D: - if ( ! widget.row.setting.name ) - break; - if ( ( rc = delete_setting ( widget.settings, - &widget.row.setting ) ) != 0 ) { - alert ( " %s ", strerror ( rc ) ); - } - select_setting_row ( &widget, widget.current ); + /* Otherwise, navigate through settings */ + key = getkey ( 0 ); + move = jump_scroll_key ( &ui.scroll, key ); + if ( move ) { + previous = ui.scroll.current; + jump_scroll_move ( &ui.scroll, move ); + if ( ui.scroll.current != previous ) { + draw_setting_row ( &ui ); redraw = 1; + if ( jump_scroll ( &ui.scroll ) ) + draw_setting_rows ( &ui ); + select_setting_row ( &ui, ui.scroll.current ); + } + continue; + } + + /* Handle non-navigation keys */ + switch ( key ) { + case CTRL_D: + if ( ! ui.row.setting.name ) break; - case CTRL_X: - return 0; - case CR: - case LF: - if ( widget.row.settings ) { - init_widget ( &widget, - widget.row.settings ); - redraw = 1; - } - /* Fall through */ - default: - if ( widget.row.setting.name ) { - edit_setting ( &widget, key ); - redraw = 1; - } - break; + if ( ( rc = delete_setting ( ui.settings, + &ui.row.setting ) ) != 0 ){ + alert ( " %s ", strerror ( rc ) ); + } + select_setting_row ( &ui, ui.scroll.current ); + redraw = 1; + break; + case CTRL_X: + return 0; + case CR: + case LF: + if ( ui.row.settings ) { + select_settings ( &ui, ui.row.settings ); + redraw = 1; } - if ( move ) { - next = ( widget.current + move ); - if ( ( int ) next < 0 ) - next = 0; - if ( next >= widget.num_rows ) - next = ( widget.num_rows - 1 ); - if ( next != widget.current ) { - draw_setting_row ( &widget ); - redraw = 1; - reveal_setting_row ( &widget, next ); - select_setting_row ( &widget, next ); - } + /* Fall through */ + default: + if ( ui.row.setting.name ) { + edit_setting ( &ui, key ); + redraw = 1; } + break; } } } -- cgit 1.2.3-korg