VOID UiDrawMenu(IN PUI_MENU_INFO MenuInfo) { ULONG i; /* No GUI status bar text, just minimal text. first to tell the user to choose */ UiDrawText(0, MenuInfo->Top - 2, "Please select the operating system to start:", ATTR(UiMenuFgColor, UiMenuBgColor)); /* Now tell him how to choose */ UiDrawText(0, MenuInfo->Bottom + 1, "Use the up and down arrow keys to move the highlight to " "your choice.", ATTR(UiMenuFgColor, UiMenuBgColor)); UiDrawText(0, MenuInfo->Bottom + 2, "Press ENTER to choose.", ATTR(UiMenuFgColor, UiMenuBgColor)); /* And offer F8 options */ UiDrawText(0, UiScreenHeight - 4, "For troubleshooting and advanced startup options for " "Odyssey, press F8.", ATTR(UiMenuFgColor, UiMenuBgColor)); /* Draw the menu box */ UiDrawMenuBox(MenuInfo); /* Draw each line of the menu */ for (i = 0; i < MenuInfo->MenuItemCount; i++) UiDrawMenuItem(MenuInfo, i); }
VOID UiDrawMenu(IN PUI_MENU_INFO MenuInfo) { ULONG i; /* No GUI status bar text, just minimal text. Show the menu header. */ UiDrawText(0, MenuInfo->Top - 2, MenuInfo->MenuHeader, ATTR(UiMenuFgColor, UiMenuBgColor)); /* Now tell the user how to choose */ UiDrawText(0, MenuInfo->Bottom + 1, "Use \x18 and \x19 to move the highlight to your choice.", ATTR(UiMenuFgColor, UiMenuBgColor)); UiDrawText(0, MenuInfo->Bottom + 2, "Press ENTER to choose.", ATTR(UiMenuFgColor, UiMenuBgColor)); /* And show the menu footer */ UiDrawText(0, UiScreenHeight - 4, MenuInfo->MenuFooter, ATTR(UiMenuFgColor, UiMenuBgColor)); /* Draw the menu box */ UiDrawMenuBox(MenuInfo); /* Draw each line of the menu */ for (i = 0; i < MenuInfo->MenuItemCount; i++) { UiDrawMenuItem(MenuInfo, i); } /* Display the boot options if needed */ if (MenuInfo->ShowBootOptions) { DisplayBootTimeOptions(); } }
BOOLEAN UiDisplayMenu(IN PCSTR MenuHeader, IN PCSTR MenuFooter, IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, IN LONG MenuTimeOut, OUT PULONG SelectedMenuItem, IN BOOLEAN CanEscape, IN UiMenuKeyPressFilterCallback KeyPressFilter) { UI_MENU_INFO MenuInformation; ULONG LastClockSecond; ULONG CurrentClockSecond; ULONG KeyPress; /* Check if there's no timeout */ if (!MenuTimeOut) { /* Return the default selected item */ if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem; return TRUE; } /* Setup the MENU_INFO structure */ MenuInformation.MenuHeader = MenuHeader; MenuInformation.MenuFooter = MenuFooter; MenuInformation.ShowBootOptions = ShowBootOptions; MenuInformation.MenuItemList = MenuItemList; MenuInformation.MenuItemCount = MenuItemCount; MenuInformation.MenuTimeRemaining = MenuTimeOut; MenuInformation.SelectedMenuItem = DefaultMenuItem; /* Calculate the size of the menu box */ UiCalcMenuBoxSize(&MenuInformation); /* Draw the menu */ UiDrawMenu(&MenuInformation); /* Get the current second of time */ LastClockSecond = ArcGetTime()->Second; /* Process keys */ while (TRUE) { /* Process key presses */ KeyPress = UiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter); /* Check for ENTER or ESC */ if (KeyPress == KEY_ENTER) break; if (CanEscape && KeyPress == KEY_ESC) return FALSE; /* Check if there is a countdown */ if (MenuInformation.MenuTimeRemaining > 0) { /* Get the updated time, seconds only */ CurrentClockSecond = ArcGetTime()->Second; /* Check if more then a second has now elapsed */ if (CurrentClockSecond != LastClockSecond) { /* Update the time information */ LastClockSecond = CurrentClockSecond; MenuInformation.MenuTimeRemaining--; /* Update the menu */ UiDrawMenuBox(&MenuInformation); } } else if (MenuInformation.MenuTimeRemaining == 0) { /* A time out occurred, exit this loop and return default OS */ break; } } /* Return the selected item */ if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem; return TRUE; }
ULONG NTAPI UiProcessMenuKeyboardEvent(IN PUI_MENU_INFO MenuInfo, IN UiMenuKeyPressFilterCallback KeyPressFilter) { ULONG KeyEvent = 0; ULONG Selected, Count; /* Check for a keypress */ if (MachConsKbHit()) { /* Check if the timeout is not already complete */ if (MenuInfo->MenuTimeRemaining != -1) { /* Cancel it and remove it */ MenuInfo->MenuTimeRemaining = -1; UiDrawMenuBox(MenuInfo); } /* Get the key */ KeyEvent = MachConsGetCh(); /* Is it extended? Then get the extended key */ if (!KeyEvent) KeyEvent = MachConsGetCh(); /* * Call the supplied key filter callback function to see * if it is going to handle this keypress. */ if ((KeyPressFilter) && (KeyPressFilter(KeyEvent))) { /* It processed the key character, so redraw and exit */ UiDrawMenu(MenuInfo); return 0; } /* Process the key */ if ((KeyEvent == KEY_UP ) || (KeyEvent == KEY_DOWN) || (KeyEvent == KEY_HOME) || (KeyEvent == KEY_END )) { /* Get the current selected item and count */ Selected = MenuInfo->SelectedMenuItem; Count = MenuInfo->MenuItemCount - 1; /* Check the key and change the selected menu item */ if ((KeyEvent == KEY_UP) && (Selected > 0)) { /* Deselect previous item and go up */ MenuInfo->SelectedMenuItem--; UiDrawMenuItem(MenuInfo, Selected); Selected--; // Skip past any separators if ((Selected > 0) && (MenuInfo->MenuItemList[Selected] == NULL)) { MenuInfo->SelectedMenuItem--; } } else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) || (KeyEvent == KEY_END) ) { /* Go to the end */ MenuInfo->SelectedMenuItem = Count; UiDrawMenuItem(MenuInfo, Selected); } else if ((KeyEvent == KEY_DOWN) && (Selected < Count)) { /* Deselect previous item and go down */ MenuInfo->SelectedMenuItem++; UiDrawMenuItem(MenuInfo, Selected); Selected++; // Skip past any separators if ((Selected < Count) && (MenuInfo->MenuItemList[Selected] == NULL)) { MenuInfo->SelectedMenuItem++; } } else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) || (KeyEvent == KEY_HOME) ) { /* Go to the beginning */ MenuInfo->SelectedMenuItem = 0; UiDrawMenuItem(MenuInfo, Selected); } /* Select new item and update video buffer */ UiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); } } /* Return the pressed key */ return KeyEvent; }
ULONG NTAPI UiProcessMenuKeyboardEvent(IN PUI_MENU_INFO MenuInfo, IN UiMenuKeyPressFilterCallback KeyPressFilter) { ULONG KeyEvent = 0, Selected, Count; /* Check for a keypress */ if (MachConsKbHit()) { /* Check if the timeout is not already complete */ if (MenuInfo->MenuTimeRemaining != -1) { // // Cancel it and remove it // MenuInfo->MenuTimeRemaining = -1; UiDrawMenuBox(MenuInfo); } /* Get the key */ KeyEvent = MachConsGetCh(); /* Is it extended? Then get the extended key */ if (!KeyEvent) KeyEvent = MachConsGetCh(); /* Call the supplied key filter callback function to see if it is going to handle this keypress. */ if ((KeyPressFilter) && (KeyPressFilter(KeyEvent))) { /* It processed the key character, so redraw and exit */ UiDrawMenu(MenuInfo); return 0; } /* Process the key */ if ((KeyEvent == KEY_UP) || (KeyEvent == KEY_DOWN)) { /* Get the current selected item and count */ Selected = MenuInfo->SelectedMenuItem; Count = MenuInfo->MenuItemCount - 1; /* Check if this was a key up and there's a selected menu item */ if ((KeyEvent == KEY_UP) && (Selected)) { /* Update the menu (Deselect previous item) */ MenuInfo->SelectedMenuItem--; UiDrawMenuItem(MenuInfo, Selected); Selected--; /* Skip past any separators */ if ((Selected) && !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR"))) { MenuInfo->SelectedMenuItem--; } } else if ((KeyEvent == KEY_DOWN) && (Selected < Count)) { /* Update the menu (deselect previous item) */ MenuInfo->SelectedMenuItem++; UiDrawMenuItem(MenuInfo, Selected); Selected++; /* Skip past any separators */ if ((Selected < Count) && !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR"))) { MenuInfo->SelectedMenuItem++; } } /* Select new item and update video buffer */ UiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); } } /* Return the pressed key */ return KeyEvent; }