From 451a84a20f6efb84aa0cdf6f225b2c0b02249d69 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 13:41:35 +0100 Subject: [PATCH] Almost complete TUI --- sdk/xtdk/bltypes.h | 22 +- xtldr2/includes/bootman.h | 52 +++++ xtldr2/textui.c | 412 ++++++++++++++++++++++---------------- 3 files changed, 305 insertions(+), 181 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 6954fb7..5615a6b 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: sdk/xtdk/bmtypes.h + * FILE: sdk/xtdk/bltypes.h * DESCRIPTION: XT Boot Manager structures definitions * DEVELOPERS: Rafal Kupiec */ -#ifndef __XTDK_BMTYPES_H -#define __XTDK_BMTYPES_H +#ifndef __XTDK_BLTYPES_H +#define __XTDK_BLTYPES_H #include #include @@ -71,6 +71,20 @@ typedef struct _XTBL_CONFIG_SECTION PWCHAR SectionName; } XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; +/* XTLDR Dialog handle data */ +typedef struct _XTBL_DIALOG_HANDLE +{ + UCHAR Attributes; + UCHAR DialogColor; + UCHAR TextColor; + UINT_PTR ResX; + UINT_PTR ResY; + UINT_PTR PosX; + UINT_PTR PosY; + UINT_PTR Width; + UINT_PTR Height; +} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; + /* XTLDR Status data */ typedef struct _XTBL_STATUS { @@ -125,4 +139,4 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; -#endif /* __XTDK_BMTYPES_H */ +#endif /* __XTDK_BLTYPES_H */ diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index c4ef222..6e727bc 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -42,6 +42,22 @@ XTCDECL VOID BlDisableConsoleCursor(); +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage); + XTCDECL VOID BlEnableConsoleCursor(); @@ -148,6 +164,12 @@ EFI_STATUS BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage); + XTCDECL EFI_STATUS BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, @@ -170,6 +192,11 @@ XTCDECL VOID BlpDebugPutChar(IN USHORT Character); +XTCDECL +VOID +BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + XTCDECL EFI_STATUS BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); @@ -183,6 +210,31 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, OUT PULONG DriveNumber, OUT PULONG PartNumber); +XTCDECL +VOID +BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle); + +XTCDECL +VOID +BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText); + +XTCDECL +VOID +BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage); + XTCDECL PEFI_DEVICE_PATH_PROTOCOL BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); diff --git a/xtldr2/textui.c b/xtldr2/textui.c index ef9fa97..88360d2 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -20,18 +20,185 @@ #define TUI_MAX_DIALOG_WIDTH 100 -typedef struct _XTBL_DIALOG_HANDLE +/** + * Displays a red error dialog box with the specified caption and message. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message) { - UCHAR Attributes; - UCHAR DialogColor; - UCHAR TextColor; - UINT_PTR ResX; - UINT_PTR ResY; - UINT_PTR PosX; - UINT_PTR PosY; - UINT_PTR Width; - UINT_PTR Height; -} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); +} + +/** + * Displays a blue informational dialog box with the specified caption and message. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message) +{ + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); +} + +/** + * Displays a blue informational dialog box with the specified caption and message and a progress bar. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @param Percentage + * Specifies the percentage progress of the progress bar. + * + * @return This routine returns a dialog box handle needed to update the progress bar. + * + * @since XT 1.0 + */ +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + XTBL_DIALOG_HANDLE Handle; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogProgressBar(&Handle, Percentage); + + /* Return dialog handle */ + return Handle; +} + +/** + * Updates the progress bar on the dialog box. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a new message that will be put on the dialog box, while updating the progress bar. + * + * @param Percentage + * Specifies the new percentage progress of the progress bar. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + /* Check if message needs an update */ + if(Message != NULL) + { + /* Update a message on the dialog box */ + BlpDrawDialogMessage(Handle, Message); + } + + /* Update progress bar */ + BlpDrawDialogProgressBar(Handle, Percentage); +} /** * Determines dialog box size based on enabled components and message length. @@ -175,9 +342,8 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message) { WCHAR BoxLine[TUI_MAX_DIALOG_WIDTH]; - PWCHAR MsgLine, LastMsgLine; - UINT_PTR Line, PosX, PosY; SIZE_T CaptionLength; + UINT_PTR PosX, PosY; /* Set dialog colors */ if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) @@ -270,21 +436,8 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); BlConsolePrint(L"%S", Caption); - /* Tokenize dialog box message */ - MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); - - /* Iterate through message lines */ - Line = 0; - while(MsgLine) - { - /* Write line in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); - BlConsolePrint(L"%S", MsgLine); - - /* Get next line */ - MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); - Line++; - } + /* Write a message on the dialog box */ + BlpDrawDialogMessage(Handle, Message); } /** @@ -408,6 +561,59 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } } +/** + * Draws a message on the dialog box specified by the handle. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a message that will be displayed on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message) +{ + PWCHAR MsgLine, LastMsgLine; + SIZE_T Index, Length; + ULONG Line; + + /* Tokenize dialog box message */ + MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); + + /* Iterate through message lines */ + Line = 0; + while(MsgLine) + { + /* Determine line length */ + Length = RtlWideStringLength(Message, 0); + + /* Write line in the dialog box */ + BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); + BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); + BlConsolePrint(L"%S", MsgLine); + + /* Check if message line is shorter than the dialog box working area */ + if(Length < Handle->Width - 4) + { + /* Fill the rest of the line with spaces */ + for(Index = Length; Index < Handle->Width - 4; Index++) + { + BlConsolePrint(L" "); + } + } + + /* Get next line */ + MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); + Line++; + } +} + /** * Draws a progress bar component in the dialog box. * @@ -466,99 +672,9 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, -/** - * Displays a red error dialog box with the specified caption and message. - * - * @param Caption - * Supplies a caption string put on the dialog box. - * - * @param Message - * Supplies a message string put on the dialog box. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlDisplayErrorDialog(IN PWCHAR Caption, - IN PWCHAR Message) -{ - XTBL_DIALOG_HANDLE Handle; - EFI_INPUT_KEY Key; - UINT_PTR Index; - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogButton(&Handle); - - /* Initialize key stroke */ - Key.ScanCode = 0; - Key.UnicodeChar = 0; - - /* Wait until ENTER or ESC key is pressed */ - while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) - { - /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); - } - - /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); -} - -XTCDECL -VOID -BlDisplayInfoDialog(IN PWCHAR Caption, - IN PWCHAR Message) -{ - XTBL_DIALOG_HANDLE Handle; - EFI_INPUT_KEY Key; - UINT_PTR Index; - - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogButton(&Handle); - - /* Initialize key stroke */ - Key.ScanCode = 0; - Key.UnicodeChar = 0; - - /* Wait until ENTER or ESC key is pressed */ - while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) - { - /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); - } - - /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); -} +// TODO: FIX, this is completely broken XTCDECL VOID BlDisplayInputDialog(IN PWCHAR Caption, @@ -725,61 +841,3 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); BlClearConsoleScreen(); } - -XTCDECL -XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN UCHAR Percentage) -{ - XTBL_DIALOG_HANDLE Handle; - - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogProgressBar(&Handle, Percentage); - - /* Return dialog handle */ - return Handle; -} - -// TODO: Common routine for printing text on dialog window -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message, - IN UCHAR Percentage) -{ - SIZE_T Index, Length; - - /* Check if message needs an update */ - if(Message != NULL) - { - /* Determine message length */ - Length = RtlWideStringLength(Message, 0); - - /* Update message in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2); - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlConsolePrint(L"%S", Message); - - if(Length < Handle->Width - 4) - { - for(Index = Length; Index < Handle->Width - 4; Index++) - { - BlConsolePrint(L" "); - } - } - } - - /* Update progress bar */ - BlpDrawDialogProgressBar(Handle, Percentage); -}