Let BlDisplayInputDialog() work on a copy of input text and save it only on ENTER key press
This commit is contained in:
parent
39208ac1cd
commit
5425abb19f
@ -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,
|
||||||
|
386
xtldr2/textui.c
386
xtldr2/textui.c
@ -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();
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user