Let BlDisplayInputDialog() work on a copy of input text and save it only on ENTER key press
All checks were successful
Builds / ExectOS (amd64) (push) Successful in 27s
Builds / ExectOS (i686) (push) Successful in 25s

This commit is contained in:
Rafal Kupiec 2024-01-02 11:31:45 +01:00
parent 39208ac1cd
commit 5425abb19f
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
2 changed files with 222 additions and 170 deletions

View File

@ -60,6 +60,12 @@ VOID
BlDisplayInfoDialog(IN PWCHAR Caption, BlDisplayInfoDialog(IN PWCHAR Caption,
IN PWCHAR Message); IN PWCHAR Message);
XTCDECL
VOID
BlDisplayInputDialog(IN PWCHAR Caption,
IN PWCHAR Message,
IN OUT PWCHAR *InputFieldText);
XTCDECL XTCDECL
XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE
BlDisplayProgressDialog(IN PWCHAR Caption, BlDisplayProgressDialog(IN PWCHAR Caption,

View File

@ -369,6 +369,222 @@ BlDisplayInfoDialog(IN PWCHAR Caption,
BlClearConsoleScreen(); BlClearConsoleScreen();
} }
/**
* Displays a blue informational dialog box with the specified caption and message and an input field.
*
* @param Caption
* Specifies a caption string put on the dialog box.
*
* @param Message
* Specifies a message string put on the dialog box.
*
* @param InputFieldText
* Specifies a pointer to the input field text that will be edited.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlDisplayInputDialog(IN PWCHAR Caption,
IN PWCHAR Message,
IN PWCHAR *InputFieldText)
{
SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition;
XTBL_DIALOG_HANDLE Handle;
PWCHAR InputFieldBuffer;
SIZE_T BufferLength;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
UINT_PTR Index;
/* Set dialog window attributes */
Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON;
/* Determine dialog window size and position */
BlpDetermineDialogBoxSize(&Handle, Message);
/* Disable cursor and draw dialog box */
BlDisableConsoleCursor();
BlpDrawDialogBox(&Handle, Caption, Message);
/* Draw inactive button */
BlpDrawDialogButton(&Handle);
/* Draw active input field */
BlpDrawDialogInputField(&Handle, *InputFieldText);
/* Initialize key stroke */
Key.ScanCode = 0;
Key.UnicodeChar = 0;
/* Get initial input text length and allocate a buffer */
BufferLength = RtlWideStringLength(*InputFieldText, 0);
Status = BlMemoryAllocatePool(BufferLength * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print error message and return */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer.");
return;
}
/* Copy input text into edit buffer */
RtlCopyMemory(InputFieldBuffer, *InputFieldText, BufferLength * sizeof(WCHAR));
InputFieldBuffer[BufferLength] = L'\0';
/* Determine input field length */
InputFieldLength = BufferLength;
if(InputFieldLength > Handle.Width - 8)
{
InputFieldLength = Handle.Width - 8;
}
/* Start at first character */
TextPosition = 0;
BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4);
/* Wait until ENTER or ESC key is pressed */
while(TRUE)
{
/* Wait for key press and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index);
BlReadKeyStroke(&Key);
BlResetConsoleInputBuffer();
/* Check key press scan code */
if(Key.ScanCode == 0x17)
{
/* ESC key pressed, return */
break;
}
else if(Key.UnicodeChar == 0x09)
{
/* TAB key pressed, toggle input field and button */
Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT);
Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON);
}
else if(Key.ScanCode == 0x03)
{
/* RIGHT key pressed, move cursor forward */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength)
{
TextPosition++;
}
}
else if(Key.ScanCode == 0x04)
{
/* LEFT key pressed, move cursor back */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0)
{
TextPosition--;
}
}
else if(Key.ScanCode == 0x05)
{
/* HOME key pressed, move cursor to the beginning */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
TextPosition = 0;
}
}
else if(Key.ScanCode == 0x06)
{
/* END key pressed, move cursor to the end */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
TextPosition = InputFieldLength;
}
}
else if(Key.ScanCode == 0x08)
{
/* DELETE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
if(InputFieldLength > 0 && TextPosition < InputFieldLength)
{
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0;
}
}
}
else if(Key.UnicodeChar == 0x08)
{
/* BACKSPACE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength)
{
TextPosition--;
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0;
}
}
}
else if(Key.UnicodeChar == 0x0D)
{
/* ENTER key pressed, allocate memory for updated input text */
BufferLength = RtlWideStringLength(InputFieldBuffer, 0);
BlMemoryFreePool(*InputFieldText);
Status = BlMemoryAllocatePool(BufferLength * sizeof(WCHAR), (PVOID *)*InputFieldText);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory, print error message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to save input data.");
break;
}
/* Copy edit buffer into original buffer */
RtlZeroMemory(InputFieldText, BufferLength * sizeof(WCHAR));
RtlCopyMemory(*InputFieldText, InputFieldBuffer, BufferLength * sizeof(WCHAR));
break;
}
else
{
/* Other key pressed, add character to the buffer */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0)
{
RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition,
(InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldBuffer[TextPosition] = Key.UnicodeChar;
TextPosition++;
InputFieldLength++;
InputFieldBuffer[InputFieldLength] = 0;
}
}
if(TextPosition > (Handle.Width - 9))
{
TextIndex = TextPosition - (Handle.Width - 9);
TextCursorPosition = Handle.Width - 9;
}
else
{
TextIndex = 0;
TextCursorPosition = TextPosition;
}
/* Redraw input field and button */
BlpDrawDialogButton(&Handle);
BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]);
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4);
}
}
/* 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. * Displays a blue informational dialog box with the specified caption and message and a progress bar.
* *
@ -1060,173 +1276,3 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
BlDisableConsoleCursor(); BlDisableConsoleCursor();
BlConsoleWrite(ProgressBar); BlConsoleWrite(ProgressBar);
} }
// TODO: FIX, this is completely broken
XTCDECL
VOID
BlDisplayInputDialog(IN PWCHAR Caption,
IN PWCHAR Message,
IN PWCHAR InputFieldBuffer)
{
XTBL_DIALOG_HANDLE Handle;
SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition;
EFI_INPUT_KEY Key;
UINT_PTR Index;
/* Set dialog window attributes */
Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON;
/* Determine dialog window size and position */
BlpDetermineDialogBoxSize(&Handle, Message);
/* Disable cursor and draw dialog box */
BlDisableConsoleCursor();
BlpDrawDialogBox(&Handle, Caption, Message);
/* Draw inactive button */
BlpDrawDialogButton(&Handle);
/* Draw active input field */
BlpDrawDialogInputField(&Handle, InputFieldBuffer);
/* Initialize key stroke */
Key.ScanCode = 0;
Key.UnicodeChar = 0;
/* Determine input field length */
InputFieldLength = RtlWideStringLength(InputFieldBuffer, 0);
if(InputFieldLength > Handle.Width - 8)
{
InputFieldLength = Handle.Width - 8;
}
/* Start at first character */
TextPosition = 0;
BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4);
/* Wait until ENTER or ESC key is pressed */
while(TRUE)
{
/* Wait for key press and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index);
BlReadKeyStroke(&Key);
BlResetConsoleInputBuffer();
/* Check key press scan code */
if(Key.ScanCode == 0x17)
{
/* ESC key pressed, return */
break;
}
else if(Key.UnicodeChar == 0x09)
{
/* TAB key pressed, toggle input field and button */
Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT);
Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON);
}
else if(Key.ScanCode == 0x03)
{
/* RIGHT key pressed, move cursor forward */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength)
{
TextPosition++;
}
}
else if(Key.ScanCode == 0x04)
{
/* LEFT key pressed, move cursor back */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0)
{
TextPosition--;
}
}
else if(Key.ScanCode == 0x05)
{
/* HOME key pressed, move cursor to the beginning */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
TextPosition = 0;
}
}
else if(Key.ScanCode == 0x06)
{
/* END key pressed, move cursor to the end */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
TextPosition = InputFieldLength;
}
}
else if(Key.ScanCode == 0x08)
{
/* DELETE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
if(InputFieldLength > 0 && TextPosition < InputFieldLength)
{
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0;
}
}
}
else if(Key.UnicodeChar == 0x08)
{
/* BACKSPACE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength)
{
TextPosition--;
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0;
}
}
}
else if(Key.UnicodeChar == 0x0D)
{
/* ENTER key pressed */
}
else
{
/* Other key pressed, add character to the buffer */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0)
{
RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldBuffer[TextPosition] = Key.UnicodeChar;
TextPosition++;
InputFieldLength++;
InputFieldBuffer[InputFieldLength] = 0;
}
}
if(TextPosition > (Handle.Width - 9))
{
TextIndex = TextPosition - (Handle.Width - 9);
TextCursorPosition = Handle.Width - 9;
}
else
{
TextIndex = 0;
TextCursorPosition = TextPosition;
}
/* Redraw input field and button */
BlpDrawDialogButton(&Handle);
BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]);
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{
BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4);
}
}
/* Clear screen to remove dialog box */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
BlClearConsoleScreen();
}