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 UiDrawProgressBar(IN ULONG Left, IN ULONG Top, IN ULONG Right, IN ULONG Bottom, IN ULONG Position, IN ULONG Range, IN PCHAR ProgressText) { ULONG i, ProgressBarWidth; /* Calculate the width of the bar proper */ ProgressBarWidth = (Right - Left) - 3; /* First make sure the progress bar text fits */ UiTruncateStringEllipsis(ProgressText, ProgressBarWidth - 4); if (Position > Range) Position = Range; /* Draw the "Loading..." text */ UiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, ProgressText, ATTR(7, 0)); /* Draw the percent complete */ for (i = 0; i < (Position * ProgressBarWidth) / Range; i++) { /* Use the fill character */ UiDrawText(Left + 2 + i, Top + 2, "\xDB", ATTR(UiTextColor, UiMenuBgColor)); } }
VOID NTAPI UiDrawMenuItem(IN PUI_MENU_INFO MenuInfo, IN ULONG MenuItemNumber) { CHAR MenuLineText[80]; UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor); /* Simply left-align it */ MenuLineText[0] = '\0'; strcat(MenuLineText, " "); /* Now append the text string */ strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]); /* If it is a separator */ if (!(_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR"))) { /* Make it a separator line and use menu colors */ memset(MenuLineText, 0, 80); memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1)); Attribute = ATTR(UiMenuFgColor, UiMenuBgColor); } else if (MenuItemNumber == MenuInfo->SelectedMenuItem) { /* If this is the selected item, use the selected colors */ Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor); } /* Draw the item */ UiDrawText(MenuInfo->Left + 1, MenuInfo->Top + 1 + MenuItemNumber, MenuLineText, Attribute); }
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(); } }
VOID DisplayBootTimeOptions(VOID) { CHAR BootOptions[260] = ""; switch (BootOptionChoice) { case SAFE_MODE: strcat(BootOptions, OptionsMenuList[0]); break; case SAFE_MODE_WITH_NETWORKING: strcat(BootOptions, OptionsMenuList[1]); break; case SAFE_MODE_WITH_COMMAND_PROMPT: strcat(BootOptions, OptionsMenuList[2]); break; case LAST_KNOWN_GOOD_CONFIGURATION: strcat(BootOptions, OptionsMenuList[6]); break; case DIRECTORY_SERVICES_RESTORE_MODE: strcat(BootOptions, OptionsMenuList[7]); break; default: break; } if (BootLogging) { if ( (BootOptionChoice != SAFE_MODE) && (BootOptionChoice != SAFE_MODE_WITH_NETWORKING) && (BootOptionChoice != SAFE_MODE_WITH_COMMAND_PROMPT) ) { if (BootOptionChoice != NO_OPTION) { strcat(BootOptions, ", "); } strcat(BootOptions, OptionsMenuList[4]); } } if (VgaMode) { if ((BootOptionChoice != NO_OPTION) || BootLogging) { strcat(BootOptions, ", "); } strcat(BootOptions, OptionsMenuList[5]); } if (DebuggingMode) { if ((BootOptionChoice != NO_OPTION) || BootLogging || VgaMode) { strcat(BootOptions, ", "); } strcat(BootOptions, OptionsMenuList[8]); } /* Display the chosen boot options */ UiDrawText(0, UiScreenHeight - 2, BootOptions, ATTR(COLOR_LIGHTBLUE, UiMenuBgColor)); }
VOID NTAPI UiDrawMenuBox(IN PUI_MENU_INFO MenuInfo) { CHAR MenuLineText[80], TempString[80]; ULONG i; /* If there is a timeout draw the time remaining */ if (MenuInfo->MenuTimeRemaining >= 0) { /* Copy the integral time text string, and remove the last 2 chars */ strcpy(TempString, UiTimeText); i = strlen(TempString); TempString[i - 2] = 0; /* Display the first part of the string and the remaining time */ strcpy(MenuLineText, TempString); _itoa(MenuInfo->MenuTimeRemaining, TempString, 10); strcat(MenuLineText, TempString); /* Add the last 2 chars */ strcat(MenuLineText, &UiTimeText[i - 2]); /* Display under the menu directly */ UiDrawText(0, MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } else { /* Erase the timeout string with spaces, and 0-terminate for sure */ for (i=0; i<sizeof(MenuLineText)-1; i++) { MenuLineText[i] = ' '; } MenuLineText[sizeof(MenuLineText)-1] = 0; /* Draw this "empty" string to erase */ UiDrawText(0, MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } /* Loop each item */ for (i = 0; i < MenuInfo->MenuItemCount; i++) { /* Check if it's a separator */ if (MenuInfo->MenuItemList[i] == NULL) { /* Draw the separator line */ UiDrawText(MenuInfo->Left, MenuInfo->Top + i + 1, "\xC7", ATTR(UiMenuFgColor, UiMenuBgColor)); UiDrawText(MenuInfo->Right, MenuInfo->Top + i + 1, "\xB6", ATTR(UiMenuFgColor, UiMenuBgColor)); } } }
VOID UiDrawCenteredText(IN ULONG Left, IN ULONG Top, IN ULONG Right, IN ULONG Bottom, IN PCSTR TextString, IN UCHAR Attr) { ULONG TextLength, BoxWidth, BoxHeight, LineBreakCount, Index, LastIndex; ULONG RealLeft, RealTop, X, Y; CHAR Temp[2]; /* Query text length */ TextLength = strlen(TextString); /* Count the new lines and the box width */ LineBreakCount = 0; BoxWidth = 0; LastIndex = 0; for (Index=0; Index < TextLength; Index++) { /* Scan for new lines */ if (TextString[Index] == '\n') { /* Remember the new line */ LastIndex = Index; LineBreakCount++; } else { /* Check for new larger box width */ if ((Index - LastIndex) > BoxWidth) { /* Update it */ BoxWidth = (Index - LastIndex); } } } /* Base the box height on the number of lines */ BoxHeight = LineBreakCount + 1; /* Create the centered coordinates */ RealLeft = (((Right - Left) - BoxWidth) / 2) + Left; RealTop = (((Bottom - Top) - BoxHeight) / 2) + Top; /* Now go for a second scan */ LastIndex = 0; for (Index=0; Index < TextLength; Index++) { /* Look for new lines again */ if (TextString[Index] == '\n') { /* Update where the text should start */ RealTop++; LastIndex = 0; } else { /* We've got a line of text to print, do it */ X = RealLeft + LastIndex; Y = RealTop; LastIndex++; Temp[0] = TextString[Index]; Temp[1] = 0; UiDrawText(X, Y, Temp, Attr); } } }
VOID NTAPI TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, ULONG MenuItemNumber) { ULONG i; CHAR MenuLineText[80]; ULONG SpaceTotal; ULONG SpaceLeft; ULONG SpaceRight = 0; UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor); // // Check if using centered menu // if (UiCenterMenu) { // // We will want the string centered so calculate // how many spaces will be to the left and right // SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) - (ULONG)(MenuInfo->MenuItemList[MenuItemNumber] ? strlen(MenuInfo->MenuItemList[MenuItemNumber]) : 0); SpaceLeft = (SpaceTotal / 2) + 1; SpaceRight = (SpaceTotal - SpaceLeft) + 1; // // Insert the spaces on the left // for (i = 0; i < SpaceLeft; i++) MenuLineText[i] = ' '; MenuLineText[i] = '\0'; } else { // // Simply left-align it // MenuLineText[0] = '\0'; strcat(MenuLineText, " "); } // // Now append the text string // if (MenuInfo->MenuItemList[MenuItemNumber]) strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]); // // Check if using centered menu, and add spaces on the right if so // if (UiCenterMenu) for (i=0; i < SpaceRight; i++) strcat(MenuLineText, " "); // // If it is a separator // if (MenuInfo->MenuItemList[MenuItemNumber] == NULL) { // // Make it a separator line and use menu colors // memset(MenuLineText, 0, 80); memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1)); Attribute = ATTR(UiMenuFgColor, UiMenuBgColor); } else if (MenuItemNumber == MenuInfo->SelectedMenuItem) { // // If this is the selected item, use the selected colors // Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor); } // // Draw the item // UiDrawText(MenuInfo->Left + 1, MenuInfo->Top + 1 + MenuItemNumber, MenuLineText, Attribute); }
VOID NTAPI TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) { CHAR MenuLineText[80], TempString[80]; ULONG i; // // Draw the menu box if requested // if (UiMenuBox) { UiDrawBox(MenuInfo->Left, MenuInfo->Top, MenuInfo->Right, MenuInfo->Bottom, D_VERT, D_HORZ, FALSE, // Filled TRUE, // Shadow ATTR(UiMenuFgColor, UiMenuBgColor)); } // // If there is a timeout draw the time remaining // if (MenuInfo->MenuTimeRemaining >= 0) { // // Copy the integral time text string, and remove the last 2 chars // strcpy(TempString, UiTimeText); i = (ULONG)strlen(TempString); TempString[i - 2] = 0; // // Display the first part of the string and the remaining time // strcpy(MenuLineText, TempString); _itoa(MenuInfo->MenuTimeRemaining, TempString, 10); strcat(MenuLineText, TempString); // // Add the last 2 chars // strcat(MenuLineText, &UiTimeText[i - 2]); // // Check if this is a centered menu // if (UiCenterMenu) { // // Display it in the center of the menu // UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1, MenuInfo->Bottom, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } else { // // Display under the menu directly // UiDrawText(0, MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } } else { // // Erase the timeout string with spaces, and 0-terminate for sure // for (i=0; i<sizeof(MenuLineText)-1; i++) { MenuLineText[i] = ' '; } MenuLineText[sizeof(MenuLineText)-1] = 0; // // Draw this "empty" string to erase // if (UiCenterMenu) { UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1, MenuInfo->Bottom, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } else { UiDrawText(0, MenuInfo->Bottom + 4, MenuLineText, ATTR(UiMenuFgColor, UiMenuBgColor)); } } // // Loop each item // for (i = 0; i < MenuInfo->MenuItemCount; i++) { // // Check if it's a separator // if (MenuInfo->MenuItemList[i] == NULL) { // // Draw the separator line // UiDrawText(MenuInfo->Left, MenuInfo->Top + i + 1, "\xC7", ATTR(UiMenuFgColor, UiMenuBgColor)); UiDrawText(MenuInfo->Right, MenuInfo->Top + i + 1, "\xB6", ATTR(UiMenuFgColor, UiMenuBgColor)); } } }
BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length) { int width = 8; unsigned int height = 1; int curline = 0; int k; size_t i , j; int x1, x2, y1, y2; char temp[260]; char key; int EditBoxLine; ULONG EditBoxStartX, EditBoxEndX; int EditBoxCursorX; unsigned int EditBoxTextCount; int EditBoxTextDisplayIndex; BOOLEAN ReturnCode; PVOID ScreenBuffer; // Save the screen contents ScreenBuffer = MmHeapAlloc(UiScreenWidth * UiScreenHeight * 2); TuiSaveScreen(ScreenBuffer); // Find the height for (i=0; i<strlen(MessageText); i++) { if (MessageText[i] == '\n') height++; } // Find the width for (i=0,j=0,k=0; i<height; i++) { while ((MessageText[j] != '\n') && (MessageText[j] != 0)) { j++; k++; } if (k > width) width = k; k = 0; j++; } // Calculate box area x1 = (UiScreenWidth - (width+2))/2; x2 = x1 + width + 3; y1 = ((UiScreenHeight - height - 2)/2) + 1; y2 = y1 + height + 4; // Draw the box TuiDrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor)); // Draw the text for (i=0,j=0; i<strlen(MessageText)+1; i++) { if ((MessageText[i] == '\n') || (MessageText[i] == 0)) { temp[j] = 0; j = 0; UiDrawText(x1+2, y1+1+curline, temp, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor)); curline++; } else temp[j++] = MessageText[i]; } EditBoxTextCount = 0; EditBoxLine = y2 - 2; EditBoxStartX = x1 + 3; EditBoxEndX = x2 - 3; UiFillArea(EditBoxStartX, EditBoxLine, EditBoxEndX, EditBoxLine, ' ', ATTR(UiEditBoxTextColor, UiEditBoxBgColor)); // Show the cursor EditBoxCursorX = EditBoxStartX; MachVideoSetTextCursorPosition(EditBoxCursorX, EditBoxLine); MachVideoHideShowTextCursor(TRUE); // Draw status text UiDrawStatusText("Press ENTER to continue, or ESC to cancel"); VideoCopyOffScreenBufferToVRAM(); for (;;) { if (MachConsKbHit()) { key = MachConsGetCh(); if(key == KEY_EXTENDED) { key = MachConsGetCh(); } if(key == KEY_ENTER) { ReturnCode = TRUE; break; } else if(key == KEY_ESC) { ReturnCode = FALSE; break; } else if (key == KEY_BACKSPACE) // Remove a character { if (EditBoxTextCount) { EditBoxTextCount--; EditTextBuffer[EditBoxTextCount] = 0; } else { MachBeep(); } } else // Add this key to the buffer { if (EditBoxTextCount < Length - 1) { EditTextBuffer[EditBoxTextCount] = key; EditBoxTextCount++; EditTextBuffer[EditBoxTextCount] = 0; } else { MachBeep(); } } } // Draw the edit box background UiFillArea(EditBoxStartX, EditBoxLine, EditBoxEndX, EditBoxLine, ' ', ATTR(UiEditBoxTextColor, UiEditBoxBgColor)); // Fill the text in if (EditBoxTextCount > (EditBoxEndX - EditBoxStartX)) { EditBoxTextDisplayIndex = EditBoxTextCount - (EditBoxEndX - EditBoxStartX); EditBoxCursorX = EditBoxEndX; } else { EditBoxTextDisplayIndex = 0; EditBoxCursorX = EditBoxStartX + EditBoxTextCount; } UiDrawText(EditBoxStartX, EditBoxLine, &EditTextBuffer[EditBoxTextDisplayIndex], ATTR(UiEditBoxTextColor, UiEditBoxBgColor)); // Move the cursor MachVideoSetTextCursorPosition(EditBoxCursorX, EditBoxLine); TuiUpdateDateTime(); VideoCopyOffScreenBufferToVRAM(); } // Hide the cursor again MachVideoHideShowTextCursor(FALSE); // Restore the screen contents TuiRestoreScreen(ScreenBuffer); MmHeapFree(ScreenBuffer); return ReturnCode; }
VOID TuiMessageBoxCritical(PCSTR MessageText) { int width = 8; unsigned int height = 1; int curline = 0; int k; size_t i , j; int x1, x2, y1, y2; char temp[260]; char key; // Find the height for (i=0; i<strlen(MessageText); i++) { if (MessageText[i] == '\n') height++; } // Find the width for (i=0,j=0,k=0; i<height; i++) { while ((MessageText[j] != '\n') && (MessageText[j] != 0)) { j++; k++; } if (k > width) width = k; k = 0; j++; } // Calculate box area x1 = (UiScreenWidth - (width+2))/2; x2 = x1 + width + 3; y1 = ((UiScreenHeight - height - 2)/2) + 1; y2 = y1 + height + 4; // Draw the box TuiDrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor)); // Draw the text for (i=0,j=0; i<strlen(MessageText)+1; i++) { if ((MessageText[i] == '\n') || (MessageText[i] == 0)) { temp[j] = 0; j = 0; UiDrawText(x1+2, y1+1+curline, temp, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor)); curline++; } else temp[j++] = MessageText[i]; } // Draw OK button strcpy(temp, " OK "); UiDrawText(x1+((x2-x1)/2)-3, y2-2, temp, ATTR(COLOR_BLACK, COLOR_GRAY)); // Draw status text UiDrawStatusText("Press ENTER to continue"); VideoCopyOffScreenBufferToVRAM(); for (;;) { if (MachConsKbHit()) { key = MachConsGetCh(); if(key == KEY_EXTENDED) key = MachConsGetCh(); if(key == KEY_ENTER) break; else if(key == KEY_SPACE) break; else if(key == KEY_ESC) break; } TuiUpdateDateTime(); VideoCopyOffScreenBufferToVRAM(); } }