static void GUI_showMenu( const MenuItem * items, int count, int selection, int row, int height ) { int i; CursorState cursorState; if ( items == NULL || count == 0 ) return; // head and tail points to the start and the end of the list. // top and bottom points to the first and last visible items // in the menu window. gMenuItems = items; gMenuRow = row; gMenuHeight = height; gMenuItemCount = count; gMenuTop = 0; gMenuBottom = min( count, height ) - 1; gMenuSelection = selection; gMenuStart = 0; gMenuEnd = min( count, gui.maxdevices ) - 1; // If the selected item is not visible, shift the list down. if ( gMenuSelection > gMenuBottom ) { gMenuTop += ( gMenuSelection - gMenuBottom ); gMenuBottom = gMenuSelection; } if ( gMenuSelection > gMenuEnd ) { gMenuStart += ( gMenuSelection - gMenuEnd ); gMenuEnd = gMenuSelection; } // Draw the visible items. if( bootArgs->Video.v_display == GRAPHICS_MODE ) { drawDeviceList(gMenuStart, gMenuEnd, gMenuSelection); } else { changeCursor( 0, row, kCursorTypeHidden, &cursorState ); for ( i = gMenuTop; i <= gMenuBottom; i++ ) { printMenuItem( &items[i], (i == gMenuSelection) ); } restoreCursor( &cursorState ); } }
static int updateMenu( int key, void ** paramPtr ) { int moved = 0; union { struct { unsigned int selectionUp : 1, selectionDown : 1, scrollUp : 1, scrollDown : 1; } f; unsigned int w; } draw = {{0}}; if ( gMenuItems == NULL ) return 0; if( bootArgs->Video.v_display == GRAPHICS_MODE ) { int res; // set navigation keys for horizontal layout as defaults int previous = 0x4B00; // left arrow int subsequent = 0x4D00; // right arrow int menu = 0x5000; // down arrow if ( gui.layout == VerticalLayout ) { // set navigation keys for vertical layout previous = 0x4800; // up arrow subsequent = 0x5000; // down arrow menu = 0x4B00; // right arrow } if ( key == previous ) { if ( gMenuSelection > gMenuTop ) draw.f.selectionUp = 1; else if ( gMenuTop > 0 ) draw.f.scrollDown = 1; } else if ( key == subsequent ) { if ( gMenuSelection != gMenuBottom) draw.f.selectionDown = 1; else if ( gMenuBottom < ( gMenuItemCount - 1 ) ) draw.f.scrollUp = 1; } else if ( key == menu ) { if ( gui.menu.draw ) updateInfoMenu(key); else drawInfoMenu(); } else if ( gui.menu.draw ) { res = updateInfoMenu(key); if ( res == CLOSE_INFO_MENU ) gui.menu.draw = false; else { shouldboot = ( res != DO_NOT_BOOT ); if ( shouldboot ) gui.menu.draw = false; switch (res) { case BOOT_NORMAL: gVerboseMode = false; gBootMode = kBootModeNormal; break; case BOOT_VERBOSE: gVerboseMode = true; gBootMode = kBootModeNormal; addBootArg(kVerboseModeFlag); break; case BOOT_IGNORECACHE: gVerboseMode = false; gBootMode = kBootModeNormal; addBootArg(kIgnoreCachesFlag); break; case BOOT_SINGLEUSER: gVerboseMode = true; gBootMode = kBootModeNormal; addBootArg(kSingleUserModeFlag); break; } } } } else { switch ( key ) { case 0x4800: // Up Arrow if ( gMenuSelection != gMenuTop ) draw.f.selectionUp = 1; else if ( gMenuTop > 0 ) draw.f.scrollDown = 1; break; case 0x5000: // Down Arrow if ( gMenuSelection != gMenuBottom ) draw.f.selectionDown = 1; else if ( gMenuBottom < (gMenuItemCount - 1) ) draw.f.scrollUp = 1; break; } } if ( draw.w ) { if ( draw.f.scrollUp ) { scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, 1); gMenuTop++; gMenuBottom++; gMenuStart++; gMenuEnd++; draw.f.selectionDown = 1; } if ( draw.f.scrollDown ) { scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, -1); gMenuTop--; gMenuBottom--; gMenuStart--; gMenuEnd--; draw.f.selectionUp = 1; } if ( draw.f.selectionUp || draw.f.selectionDown ) { CursorState cursorState; // Set cursor at current position, and clear inverse video. if( bootArgs->Video.v_display == VGA_TEXT_MODE ) { changeCursor( 0, gMenuRow + gMenuSelection - gMenuTop, kCursorTypeHidden, &cursorState ); printMenuItem( &gMenuItems[gMenuSelection], 0 ); } if ( draw.f.selectionUp ) { gMenuSelection--; if(( gMenuSelection - gMenuStart) == -1 ) { gMenuStart--; gMenuEnd--; } } else { gMenuSelection++; if(( gMenuSelection - ( gui.maxdevices - 1) - gMenuStart) > 0 ) { gMenuStart++; gMenuEnd++; } } if( bootArgs->Video.v_display == VGA_TEXT_MODE ) { moveCursor( 0, gMenuRow + gMenuSelection - gMenuTop ); printMenuItem( &gMenuItems[gMenuSelection], 1 ); restoreCursor( &cursorState ); } else drawDeviceList (gMenuStart, gMenuEnd, gMenuSelection); } *paramPtr = gMenuItems[gMenuSelection].param; moved = 1; } return moved; }