iPXE
Data Structures | Functions
menu.h File Reference

Menu selection. More...

#include <ipxe/list.h>

Go to the source code of this file.

Data Structures

struct  menu
 A menu. More...
struct  menu_item
 A menu item. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
struct menucreate_menu (const char *name, const char *title)
 Create menu.
struct menu_itemadd_menu_item (struct menu *menu, const char *label, const char *text, int shortcut, int is_default)
 Add menu item.
void destroy_menu (struct menu *menu)
 Destroy menu.
struct menufind_menu (const char *name)
 Find menu.
int show_menu (struct menu *menu, unsigned long timeout, const char *select, struct menu_item **selected)
 Show menu.

Detailed Description

Menu selection.

Definition in file menu.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
struct menu* create_menu ( const char *  name,
const char *  title 
) [read]

Create menu.

Parameters:
nameMenu name, or NULL
titleMenu title, or NULL
Return values:
menuMenu, or NULL on failure

Definition at line 48 of file menu.c.

References DBGC, destroy_menu(), find_menu(), INIT_LIST_HEAD, menu::items, len, menu::list, list_add_tail, menu::name, NULL, strcpy(), strlen(), menu::title, and zalloc().

Referenced by menu_exec().

                                                                  {
        size_t name_len;
        size_t title_len;
        size_t len;
        struct menu *menu;
        char *name_copy;
        char *title_copy;

        /* Destroy any existing menu of this name */
        menu = find_menu ( name );
        if ( menu )
                destroy_menu ( menu );

        /* Use empty title if none given */
        if ( ! title )
                title = "";

        /* Allocate menu */
        name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
        title_len = ( strlen ( title ) + 1 /* NUL */ );
        len = ( sizeof ( *menu ) + name_len + title_len );
        menu = zalloc ( len );
        if ( ! menu )
                return NULL;
        name_copy = ( ( void * ) ( menu + 1 ) );
        title_copy = ( name_copy + name_len );

        /* Initialise menu */
        if ( name ) {
                strcpy ( name_copy, name );
                menu->name = name_copy;
        }
        strcpy ( title_copy, title );
        menu->title = title_copy;
        INIT_LIST_HEAD ( &menu->items );

        /* Add to list of menus */
        list_add_tail ( &menu->list, &menus );

        DBGC ( menu, "MENU %s created with title \"%s\"\n",
               menu->name, menu->title );

        return menu;
}
struct menu_item* add_menu_item ( struct menu menu,
const char *  label,
const char *  text,
int  shortcut,
int  is_default 
) [read]

Add menu item.

Parameters:
menuMenu
labelLabel, or NULL
textText, or NULL
shortcutShortcut key
is_defaultItem is the default item
Return values:
itemMenu item, or NULL on failure

Definition at line 103 of file menu.c.

References menu_item::is_default, menu::items, menu_item::label, len, menu_item::list, list_add_tail, NULL, menu_item::shortcut, strcpy(), strlen(), menu_item::text, and zalloc().

Referenced by item_exec().

                                                    {
        size_t label_len;
        size_t text_len;
        size_t len;
        struct menu_item *item;
        char *label_copy;
        char *text_copy;

        /* Use empty text if none given */
        if ( ! text )
                text = "";

        /* Allocate item */
        label_len = ( label ? ( strlen ( label ) + 1 /* NUL */ ) : 0 );
        text_len = ( strlen ( text ) + 1 /* NUL */ );
        len = ( sizeof ( *item ) + label_len + text_len );
        item = zalloc ( len );
        if ( ! item )
                return NULL;
        label_copy = ( ( void * ) ( item + 1 ) );
        text_copy = ( label_copy + label_len );

        /* Initialise item */
        if ( label ) {
                strcpy ( label_copy, label );
                item->label = label_copy;
        }
        strcpy ( text_copy, text );
        item->text = text_copy;
        item->shortcut = shortcut;
        item->is_default = is_default;

        /* Add to list of items */
        list_add_tail ( &item->list, &menu->items );

        return item;
}
void destroy_menu ( struct menu menu)

Destroy menu.

Parameters:
menuMenu

Definition at line 148 of file menu.c.

References free, menu::items, menu::list, menu_item::list, list_del, and list_for_each_entry_safe.

Referenced by choose_exec(), create_menu(), and menu_exec().

                                        {
        struct menu_item *item;
        struct menu_item *tmp;

        /* Remove from list of menus */
        list_del ( &menu->list );

        /* Free items */
        list_for_each_entry_safe ( item, tmp, &menu->items, list ) {
                list_del ( &item->list );
                free ( item );
        }

        /* Free menu */
        free ( menu );
}
struct menu* find_menu ( const char *  name) [read]

Find menu.

Parameters:
nameMenu name, or NULL
Return values:
menuMenu, or NULL if not found

Definition at line 171 of file menu.c.

References menu::list, list_for_each_entry, menu::name, NULL, and strcmp().

Referenced by create_menu(), and parse_menu().

                                             {
        struct menu *menu;

        list_for_each_entry ( menu, &menus, list ) {
                if ( ( menu->name == name ) ||
                     ( strcmp ( menu->name, name ) == 0 ) ) {
                        return menu;
                }
        }

        return NULL;
}
int show_menu ( struct menu menu,
unsigned long  timeout,
const char *  select,
struct menu_item **  selected 
)

Show menu.

Parameters:
menuMenu
timeoutTimeout period, in ticks (0=indefinite)
Return values:
selectedSelected item
rcReturn status code

Definition at line 273 of file menu_ui.c.

References A_BOLD, assert, attroff(), attron(), color_set, COLS, jump_scroller::count, CPAIR_NORMAL, jump_scroller::current, curs_set(), draw_menu_item(), draw_menu_items(), endwin(), ENOENT, erase(), initscr(), menu_item::is_default, menu::items, jump_scroll(), menu_item::label, list_for_each_entry, memset(), menu_ui::menu, MENU_COLS, menu_loop(), MENU_ROWS, mvprintw, NULL, rc, jump_scroller::rows, menu_ui::scroll, snprintf(), start_color, strcmp(), strlen(), menu_ui::timeout, timeout(), menu::title, and TITLE_ROW.

Referenced by choose_exec().

                                                                  {
        struct menu_item *item;
        struct menu_ui ui;
        char buf[ MENU_COLS + 1 /* NUL */ ];
        int labelled_count = 0;
        int rc;

        /* 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.scroll.current = ui.scroll.count;
                        labelled_count++;
                        if ( select ) {
                                if ( strcmp ( select, item->label ) == 0 )
                                        ui.scroll.current = ui.scroll.count;
                        } else {
                                if ( item->is_default )
                                        ui.scroll.current = ui.scroll.count;
                        }
                }
                ui.scroll.count++;
        }
        if ( ! labelled_count ) {
                /* Menus with no labelled items cannot be selected
                 * from, and will seriously confuse the navigation
                 * logic.  Refuse to display any such menus.
                 */
                return -ENOENT;
        }

        /* Initialise screen */
        initscr();
        start_color();
        color_set ( CPAIR_NORMAL, NULL );
        curs_set ( 0 );
        erase();

        /* Draw initial content */
        attron ( A_BOLD );
        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.scroll.current );

        /* Enter main loop */
        rc = menu_loop ( &ui, selected );
        assert ( *selected );

        /* Clear screen */
        endwin();

        return rc;
}