diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c')
| -rw-r--r-- | MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c | 1540 |
1 files changed, 770 insertions, 770 deletions
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c index 9844cf8505..6f7f16c672 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c @@ -1,770 +1,770 @@ -/** @file
-
-Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-
-**/
-
-#include "Edb.h"
-
-/**
- Set the current coordinates of the cursor position.
-
- @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
- @param Column The position to set the cursor to.
- @param Row The position to set the cursor to.
- @param LineLength Length of a line.
- @param TotalRow Total row of a screen.
- @param Str Point to the string.
- @param StrPos The position of the string.
- @param Len The length of the string.
-
-**/
-VOID
-EFIAPI
-SetCursorPosition (
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,
- IN UINTN Column,
- IN INTN Row,
- IN UINTN LineLength,
- IN UINTN TotalRow,
- IN CHAR16 *Str,
- IN UINTN StrPos,
- IN UINTN Len
- );
-
-/**
-
- Function waits for a given event to fire, or for an optional timeout to expire.
-
- @param Event - The event to wait for
- @param Timeout - An optional timeout value in 100 ns units.
-
- @retval EFI_SUCCESS - Event fired before Timeout expired.
- @retval EFI_TIME_OUT - Timout expired before Event fired..
-
-**/
-EFI_STATUS
-EFIAPI
-WaitForSingleEvent (
- IN EFI_EVENT Event,
- IN UINT64 Timeout OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- EFI_EVENT TimerEvent;
- EFI_EVENT WaitList[2];
-
- if (Timeout != 0) {
- //
- // Create a timer event
- //
- Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
- if (!EFI_ERROR (Status)) {
- //
- // Set the timer event
- //
- gBS->SetTimer (
- TimerEvent,
- TimerRelative,
- Timeout
- );
-
- //
- // Wait for the original event or the timer
- //
- WaitList[0] = Event;
- WaitList[1] = TimerEvent;
- Status = gBS->WaitForEvent (2, WaitList, &Index);
- gBS->CloseEvent (TimerEvent);
-
- //
- // If the timer expired, change the return to timed out
- //
- if (!EFI_ERROR (Status) && (Index == 1)) {
- Status = EFI_TIMEOUT;
- }
- }
- } else {
- //
- // No timeout... just wait on the event
- //
- Status = gBS->WaitForEvent (1, &Event, &Index);
- ASSERT (!EFI_ERROR (Status));
- ASSERT (Index == 0);
- }
-
- return Status;
-}
-
-/**
-
- Move the cursor position one character backward.
-
- @param LineLength Length of a line. Get it by calling QueryMode
- @param Column Current column of the cursor position
- @param Row Current row of the cursor position
-
-**/
-VOID
-EFIAPI
-ConMoveCursorBackward (
- IN UINTN LineLength,
- IN OUT UINTN *Column,
- IN OUT UINTN *Row
- )
-{
- ASSERT (Column != NULL);
- ASSERT (Row != NULL);
- //
- // If current column is 0, move to the last column of the previous line,
- // otherwise, just decrement column.
- //
- if (*Column == 0) {
- (*Column) = LineLength - 1;
- //
- // if (*Row > 0) {
- //
- (*Row)--;
- //
- // }
- //
- } else {
- (*Column)--;
- }
-}
-
-/**
-
- Move the cursor position one character backward.
-
- @param LineLength Length of a line. Get it by calling QueryMode
- @param TotalRow Total row of a screen, get by calling QueryMode
- @param Column Current column of the cursor position
- @param Row Current row of the cursor position
-
-**/
-VOID
-EFIAPI
-ConMoveCursorForward (
- IN UINTN LineLength,
- IN UINTN TotalRow,
- IN OUT UINTN *Column,
- IN OUT UINTN *Row
- )
-{
- ASSERT (Column != NULL);
- ASSERT (Row != NULL);
- //
- // If current column is at line end, move to the first column of the nest
- // line, otherwise, just increment column.
- //
- (*Column)++;
- if (*Column >= LineLength) {
- (*Column) = 0;
- if ((*Row) < TotalRow - 1) {
- (*Row)++;
- }
- }
-}
-
-CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE];
-CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE];
-
-/**
-
- Get user input.
-
- @param Prompt The prompt string.
- @param InStr Point to the input string.
- @param StrLength The max length of string user can input.
-
-**/
-VOID
-EFIAPI
-Input (
- IN CHAR16 *Prompt OPTIONAL,
- OUT CHAR16 *InStr,
- IN UINTN StrLength
- )
-{
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
- BOOLEAN Done;
- UINTN Column;
- UINTN Row;
- UINTN StartColumn;
- UINTN Update;
- UINTN Delete;
- UINTN Len;
- UINTN StrPos;
- UINTN Index;
- UINTN LineLength;
- UINTN TotalRow;
- UINTN SkipLength;
- UINTN OutputLength;
- UINTN TailRow;
- UINTN TailColumn;
- EFI_INPUT_KEY Key;
- BOOLEAN InsertMode;
- BOOLEAN NeedAdjust;
- UINTN SubIndex;
- CHAR16 *CommandStr;
-
- ConOut = gST->ConOut;
- ConIn = gST->ConIn;
-
- ASSERT (ConOut != NULL);
- ASSERT (ConIn != NULL);
- ASSERT (InStr != NULL);
-
- if (Prompt != NULL) {
- ConOut->OutputString (ConOut, Prompt);
- }
-
- //
- // Read a line from the console
- //
- Len = 0;
- StrPos = 0;
- OutputLength = 0;
- Update = 0;
- Delete = 0;
- InsertMode = TRUE;
- NeedAdjust = FALSE;
-
- //
- // If buffer is not large enough to hold a CHAR16, do nothing.
- //
- if (StrLength < 1) {
- return;
- }
-
- //
- // Get the screen setting and the current cursor location
- //
- StartColumn = ConOut->Mode->CursorColumn;
- Column = StartColumn;
- Row = ConOut->Mode->CursorRow;
- ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow);
- if (LineLength == 0) {
- return;
- }
-
- SetMem (InStr, StrLength * sizeof (CHAR16), 0);
- Done = FALSE;
- do {
- //
- // Read a key
- //
- WaitForSingleEvent (ConIn->WaitForKey, 0);
- ConIn->ReadKeyStroke (ConIn, &Key);
-
- switch (Key.UnicodeChar) {
- case CHAR_CARRIAGE_RETURN:
- //
- // All done, print a newline at the end of the string
- //
- TailRow = Row + (Len - StrPos + Column) / LineLength;
- TailColumn = (Len - StrPos + Column) % LineLength;
- Done = TRUE;
- break;
-
- case CHAR_BACKSPACE:
- if (StrPos != 0) {
- //
- // If not move back beyond string beginning, move all characters behind
- // the current position one character forward
- //
- StrPos -= 1;
- Update = StrPos;
- Delete = 1;
- CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
-
- //
- // Adjust the current column and row
- //
- ConMoveCursorBackward (LineLength, &Column, &Row);
-
- NeedAdjust = TRUE;
- }
-
- break;
-
- default:
- if (Key.UnicodeChar >= ' ') {
- //
- // If we are at the buffer's end, drop the key
- //
- if ((Len == StrLength - 1) && (InsertMode || (StrPos == Len))) {
- break;
- }
-
- //
- // If in insert mode, move all characters behind the current position
- // one character backward to make space for this character. Then store
- // the character.
- //
- if (InsertMode) {
- for (Index = Len; Index > StrPos; Index -= 1) {
- InStr[Index] = InStr[Index - 1];
- }
- }
-
- InStr[StrPos] = Key.UnicodeChar;
- Update = StrPos;
-
- StrPos += 1;
- OutputLength = 1;
- }
-
- break;
-
- case 0:
- switch (Key.ScanCode) {
- case SCAN_DELETE:
- //
- // Move characters behind current position one character forward
- //
- if (Len != 0) {
- Update = StrPos;
- Delete = 1;
- CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
-
- NeedAdjust = TRUE;
- }
-
- break;
-
- case SCAN_LEFT:
- //
- // Adjust current cursor position
- //
- if (StrPos != 0) {
- StrPos -= 1;
- ConMoveCursorBackward (LineLength, &Column, &Row);
- }
-
- break;
-
- case SCAN_RIGHT:
- //
- // Adjust current cursor position
- //
- if (StrPos < Len) {
- StrPos += 1;
- ConMoveCursorForward (LineLength, TotalRow, &Column, &Row);
- }
-
- break;
-
- case SCAN_HOME:
- //
- // Move current cursor position to the beginning of the command line
- //
- Row -= (StrPos + StartColumn) / LineLength;
- Column = StartColumn;
- StrPos = 0;
- break;
-
- case SCAN_END:
- //
- // Move current cursor position to the end of the command line
- //
- TailRow = Row + (Len - StrPos + Column) / LineLength;
- TailColumn = (Len - StrPos + Column) % LineLength;
- Row = TailRow;
- Column = TailColumn;
- StrPos = Len;
- break;
-
- case SCAN_ESC:
- //
- // Prepare to clear the current command line
- //
- InStr[0] = 0;
- Update = 0;
- Delete = Len;
- Row -= (StrPos + StartColumn) / LineLength;
- Column = StartColumn;
- OutputLength = 0;
-
- NeedAdjust = TRUE;
- break;
-
- case SCAN_INSERT:
- //
- // Toggle the SEnvInsertMode flag
- //
- InsertMode = (BOOLEAN) !InsertMode;
- break;
-
- case SCAN_UP:
- case SCAN_DOWN:
- //
- // show history
- //
- CopyMem (InStr, mInputBufferHistory, StrLength * sizeof (CHAR16));
- StrPos = StrLen (mInputBufferHistory);
- Update = 0;
- Delete = 0;
- OutputLength = 0;
-
- TailRow = Row + (StrPos + StartColumn) / LineLength;
- TailColumn = (StrPos + StartColumn) % LineLength;
- Row = TailRow;
- Column = TailColumn;
- NeedAdjust = FALSE;
-
- ConOut->SetCursorPosition (ConOut, StartColumn, Row);
- for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
- mBackupSpace[SubIndex] = L' ';
- }
-
- EDBPrint (mBackupSpace);
- SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0);
-
- ConOut->SetCursorPosition (ConOut, StartColumn, Row);
- Len = StrPos;
-
- break;
-
- case SCAN_F1:
- case SCAN_F2:
- case SCAN_F3:
- case SCAN_F4:
- case SCAN_F5:
- case SCAN_F6:
- case SCAN_F7:
- case SCAN_F8:
- case SCAN_F9:
- case SCAN_F10:
- case SCAN_F11:
- case SCAN_F12:
- CommandStr = GetCommandNameByKey (Key);
- if (CommandStr != NULL) {
- StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1);
- return;
- }
-
- break;
- }
- }
-
- if (Done) {
- break;
- }
-
- //
- // If we need to update the output do so now
- //
- if (Update != -1) {
- if (NeedAdjust) {
- ConOut->SetCursorPosition (ConOut, Column, Row);
- for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
- mBackupSpace[SubIndex] = L' ';
- }
-
- EDBPrint (mBackupSpace);
- SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0);
- ConOut->SetCursorPosition (ConOut, Column, Row);
- NeedAdjust = FALSE;
- }
-
- EDBPrint (InStr + Update);
- Len = StrLen (InStr);
-
- if (Delete != 0) {
- SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00);
- }
-
- if (StrPos > Len) {
- StrPos = Len;
- }
-
- Update = (UINTN)-1;
-
- //
- // After using print to reflect newly updates, if we're not using
- // BACKSPACE and DELETE, we need to move the cursor position forward,
- // so adjust row and column here.
- //
- if ((Key.UnicodeChar != CHAR_BACKSPACE) && !((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_DELETE))) {
- //
- // Calulate row and column of the tail of current string
- //
- TailRow = Row + (Len - StrPos + Column + OutputLength) / LineLength;
- TailColumn = (Len - StrPos + Column + OutputLength) % LineLength;
-
- //
- // If the tail of string reaches screen end, screen rolls up, so if
- // Row does not equal TailRow, Row should be decremented
- //
- // (if we are recalling commands using UPPER and DOWN key, and if the
- // old command is too long to fit the screen, TailColumn must be 79.
- //
- if ((TailColumn == 0) && (TailRow >= TotalRow) && ((UINTN)Row != TailRow)) {
- Row--;
- }
-
- //
- // Calculate the cursor position after current operation. If cursor
- // reaches line end, update both row and column, otherwise, only
- // column will be changed.
- //
- if (Column + OutputLength >= LineLength) {
- SkipLength = OutputLength - (LineLength - Column);
-
- Row += SkipLength / LineLength + 1;
- if ((UINTN)Row > TotalRow - 1) {
- Row = TotalRow - 1;
- }
-
- Column = SkipLength % LineLength;
- } else {
- Column += OutputLength;
- }
- }
-
- Delete = 0;
- }
-
- //
- // Set the cursor position for this key
- //
- SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len);
- } while (!Done);
-
- CopyMem (mInputBufferHistory, InStr, StrLength * sizeof (CHAR16));
-
- //
- // Return the data to the caller
- //
- return;
-}
-
-/**
- Set the current coordinates of the cursor position.
-
- @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
- @param Column The position to set the cursor to.
- @param Row The position to set the cursor to.
- @param LineLength Length of a line.
- @param TotalRow Total row of a screen.
- @param Str Point to the string.
- @param StrPos The position of the string.
- @param Len The length of the string.
-
-**/
-VOID
-EFIAPI
-SetCursorPosition (
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,
- IN UINTN Column,
- IN INTN Row,
- IN UINTN LineLength,
- IN UINTN TotalRow,
- IN CHAR16 *Str,
- IN UINTN StrPos,
- IN UINTN Len
- )
-{
- CHAR16 Backup;
-
- ASSERT (ConOut != NULL);
- ASSERT (Str != NULL);
-
- Backup = 0;
- if (Row >= 0) {
- ConOut->SetCursorPosition (ConOut, Column, Row);
- return;
- }
-
- if (Len - StrPos > Column * Row) {
- Backup = *(Str + StrPos + Column * Row);
- *(Str + StrPos + Column * Row) = 0;
- }
-
- EDBPrint (L"%s", Str + StrPos);
- if (Len - StrPos > Column * Row) {
- *(Str + StrPos + Column * Row) = Backup;
- }
-
- ConOut->SetCursorPosition (ConOut, 0, 0);
-}
-
-/**
-
- SetPageBreak.
-
-**/
-BOOLEAN
-EFIAPI
-SetPageBreak (
- VOID
- )
-{
- EFI_INPUT_KEY Key;
- CHAR16 Str[3];
- BOOLEAN OmitPrint;
-
- //
- // Check
- //
- if (!mDebuggerPrivate.EnablePageBreak) {
- return FALSE;
- }
-
- gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:");
-
- OmitPrint = FALSE;
- //
- // Wait for user input
- //
- Str[0] = ' ';
- Str[1] = 0;
- Str[2] = 0;
- for ( ; ;) {
- WaitForSingleEvent (gST->ConIn->WaitForKey, 0);
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- //
- // handle control keys
- //
- if (Key.UnicodeChar == CHAR_NULL) {
- if (Key.ScanCode == SCAN_ESC) {
- gST->ConOut->OutputString (gST->ConOut, L"\r\n");
- OmitPrint = TRUE;
- break;
- }
-
- continue;
- }
-
- if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
- gST->ConOut->OutputString (gST->ConOut, L"\r\n");
- break;
- }
-
- //
- // Echo input
- //
- Str[1] = Key.UnicodeChar;
- if (Str[1] == CHAR_BACKSPACE) {
- continue;
- }
-
- gST->ConOut->OutputString (gST->ConOut, Str);
-
- if ((Str[1] == L'q') || (Str[1] == L'Q')) {
- OmitPrint = TRUE;
- } else {
- OmitPrint = FALSE;
- }
-
- Str[0] = CHAR_BACKSPACE;
- }
-
- return OmitPrint;
-}
-
-/**
- Print a Unicode string to the output device.
-
- @param Format A Null-terminated Unicode format string.
- @param ... The variable argument list that contains pointers to Null-
- terminated Unicode strings to be printed
-
-**/
-UINTN
-EFIAPI
-EDBPrint (
- IN CONST CHAR16 *Format,
- ...
- )
-{
- UINTN Return;
- VA_LIST Marker;
- CHAR16 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];
-
- VA_START (Marker, Format);
- Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);
- VA_END (Marker);
-
- if (gST->ConOut != NULL) {
- //
- // To be extra safe make sure ConOut has been initialized
- //
- gST->ConOut->OutputString (gST->ConOut, Buffer);
- }
-
- return Return;
-}
-
-/**
- Print a Unicode string to the output buffer.
-
- @param Buffer A pointer to the output buffer for the produced Null-terminated
- Unicode string.
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
- @param Format A Null-terminated Unicode format string.
- @param ... The variable argument list that contains pointers to Null-
- terminated Unicode strings to be printed
-
-**/
-UINTN
-EFIAPI
-EDBSPrint (
- OUT CHAR16 *Buffer,
- IN INTN BufferSize,
- IN CONST CHAR16 *Format,
- ...
- )
-{
- UINTN Return;
- VA_LIST Marker;
-
- ASSERT (BufferSize > 0);
-
- VA_START (Marker, Format);
- Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker);
- VA_END (Marker);
-
- return Return;
-}
-
-/**
- Print a Unicode string to the output buffer with specified offset..
-
- @param Buffer A pointer to the output buffer for the produced Null-terminated
- Unicode string.
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
- @param Offset The offset of the buffer.
- @param Format A Null-terminated Unicode format string.
- @param ... The variable argument list that contains pointers to Null-
- terminated Unicode strings to be printed
-
-**/
-UINTN
-EFIAPI
-EDBSPrintWithOffset (
- OUT CHAR16 *Buffer,
- IN INTN BufferSize,
- IN UINTN Offset,
- IN CONST CHAR16 *Format,
- ...
- )
-{
- UINTN Return;
- VA_LIST Marker;
-
- ASSERT (BufferSize - (Offset * sizeof (CHAR16)) > 0);
-
- VA_START (Marker, Format);
- Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof (CHAR16))), Format, Marker);
- VA_END (Marker);
-
- return Return;
-}
+/** @file + +Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "Edb.h" + +/** + Set the current coordinates of the cursor position. + + @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. + @param Column The position to set the cursor to. + @param Row The position to set the cursor to. + @param LineLength Length of a line. + @param TotalRow Total row of a screen. + @param Str Point to the string. + @param StrPos The position of the string. + @param Len The length of the string. + +**/ +VOID +EFIAPI +SetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, + IN UINTN Column, + IN INTN Row, + IN UINTN LineLength, + IN UINTN TotalRow, + IN CHAR16 *Str, + IN UINTN StrPos, + IN UINTN Len + ); + +/** + + Function waits for a given event to fire, or for an optional timeout to expire. + + @param Event - The event to wait for + @param Timeout - An optional timeout value in 100 ns units. + + @retval EFI_SUCCESS - Event fired before Timeout expired. + @retval EFI_TIME_OUT - Timout expired before Event fired.. + +**/ +EFI_STATUS +EFIAPI +WaitForSingleEvent ( + IN EFI_EVENT Event, + IN UINT64 Timeout OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_EVENT TimerEvent; + EFI_EVENT WaitList[2]; + + if (Timeout != 0) { + // + // Create a timer event + // + Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent); + if (!EFI_ERROR (Status)) { + // + // Set the timer event + // + gBS->SetTimer ( + TimerEvent, + TimerRelative, + Timeout + ); + + // + // Wait for the original event or the timer + // + WaitList[0] = Event; + WaitList[1] = TimerEvent; + Status = gBS->WaitForEvent (2, WaitList, &Index); + gBS->CloseEvent (TimerEvent); + + // + // If the timer expired, change the return to timed out + // + if (!EFI_ERROR (Status) && (Index == 1)) { + Status = EFI_TIMEOUT; + } + } + } else { + // + // No timeout... just wait on the event + // + Status = gBS->WaitForEvent (1, &Event, &Index); + ASSERT (!EFI_ERROR (Status)); + ASSERT (Index == 0); + } + + return Status; +} + +/** + + Move the cursor position one character backward. + + @param LineLength Length of a line. Get it by calling QueryMode + @param Column Current column of the cursor position + @param Row Current row of the cursor position + +**/ +VOID +EFIAPI +ConMoveCursorBackward ( + IN UINTN LineLength, + IN OUT UINTN *Column, + IN OUT UINTN *Row + ) +{ + ASSERT (Column != NULL); + ASSERT (Row != NULL); + // + // If current column is 0, move to the last column of the previous line, + // otherwise, just decrement column. + // + if (*Column == 0) { + (*Column) = LineLength - 1; + // + // if (*Row > 0) { + // + (*Row)--; + // + // } + // + } else { + (*Column)--; + } +} + +/** + + Move the cursor position one character backward. + + @param LineLength Length of a line. Get it by calling QueryMode + @param TotalRow Total row of a screen, get by calling QueryMode + @param Column Current column of the cursor position + @param Row Current row of the cursor position + +**/ +VOID +EFIAPI +ConMoveCursorForward ( + IN UINTN LineLength, + IN UINTN TotalRow, + IN OUT UINTN *Column, + IN OUT UINTN *Row + ) +{ + ASSERT (Column != NULL); + ASSERT (Row != NULL); + // + // If current column is at line end, move to the first column of the nest + // line, otherwise, just increment column. + // + (*Column)++; + if (*Column >= LineLength) { + (*Column) = 0; + if ((*Row) < TotalRow - 1) { + (*Row)++; + } + } +} + +CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE]; +CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE]; + +/** + + Get user input. + + @param Prompt The prompt string. + @param InStr Point to the input string. + @param StrLength The max length of string user can input. + +**/ +VOID +EFIAPI +Input ( + IN CHAR16 *Prompt OPTIONAL, + OUT CHAR16 *InStr, + IN UINTN StrLength + ) +{ + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; + BOOLEAN Done; + UINTN Column; + UINTN Row; + UINTN StartColumn; + UINTN Update; + UINTN Delete; + UINTN Len; + UINTN StrPos; + UINTN Index; + UINTN LineLength; + UINTN TotalRow; + UINTN SkipLength; + UINTN OutputLength; + UINTN TailRow; + UINTN TailColumn; + EFI_INPUT_KEY Key; + BOOLEAN InsertMode; + BOOLEAN NeedAdjust; + UINTN SubIndex; + CHAR16 *CommandStr; + + ConOut = gST->ConOut; + ConIn = gST->ConIn; + + ASSERT (ConOut != NULL); + ASSERT (ConIn != NULL); + ASSERT (InStr != NULL); + + if (Prompt != NULL) { + ConOut->OutputString (ConOut, Prompt); + } + + // + // Read a line from the console + // + Len = 0; + StrPos = 0; + OutputLength = 0; + Update = 0; + Delete = 0; + InsertMode = TRUE; + NeedAdjust = FALSE; + + // + // If buffer is not large enough to hold a CHAR16, do nothing. + // + if (StrLength < 1) { + return; + } + + // + // Get the screen setting and the current cursor location + // + StartColumn = ConOut->Mode->CursorColumn; + Column = StartColumn; + Row = ConOut->Mode->CursorRow; + ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow); + if (LineLength == 0) { + return; + } + + SetMem (InStr, StrLength * sizeof (CHAR16), 0); + Done = FALSE; + do { + // + // Read a key + // + WaitForSingleEvent (ConIn->WaitForKey, 0); + ConIn->ReadKeyStroke (ConIn, &Key); + + switch (Key.UnicodeChar) { + case CHAR_CARRIAGE_RETURN: + // + // All done, print a newline at the end of the string + // + TailRow = Row + (Len - StrPos + Column) / LineLength; + TailColumn = (Len - StrPos + Column) % LineLength; + Done = TRUE; + break; + + case CHAR_BACKSPACE: + if (StrPos != 0) { + // + // If not move back beyond string beginning, move all characters behind + // the current position one character forward + // + StrPos -= 1; + Update = StrPos; + Delete = 1; + CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos)); + + // + // Adjust the current column and row + // + ConMoveCursorBackward (LineLength, &Column, &Row); + + NeedAdjust = TRUE; + } + + break; + + default: + if (Key.UnicodeChar >= ' ') { + // + // If we are at the buffer's end, drop the key + // + if ((Len == StrLength - 1) && (InsertMode || (StrPos == Len))) { + break; + } + + // + // If in insert mode, move all characters behind the current position + // one character backward to make space for this character. Then store + // the character. + // + if (InsertMode) { + for (Index = Len; Index > StrPos; Index -= 1) { + InStr[Index] = InStr[Index - 1]; + } + } + + InStr[StrPos] = Key.UnicodeChar; + Update = StrPos; + + StrPos += 1; + OutputLength = 1; + } + + break; + + case 0: + switch (Key.ScanCode) { + case SCAN_DELETE: + // + // Move characters behind current position one character forward + // + if (Len != 0) { + Update = StrPos; + Delete = 1; + CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos)); + + NeedAdjust = TRUE; + } + + break; + + case SCAN_LEFT: + // + // Adjust current cursor position + // + if (StrPos != 0) { + StrPos -= 1; + ConMoveCursorBackward (LineLength, &Column, &Row); + } + + break; + + case SCAN_RIGHT: + // + // Adjust current cursor position + // + if (StrPos < Len) { + StrPos += 1; + ConMoveCursorForward (LineLength, TotalRow, &Column, &Row); + } + + break; + + case SCAN_HOME: + // + // Move current cursor position to the beginning of the command line + // + Row -= (StrPos + StartColumn) / LineLength; + Column = StartColumn; + StrPos = 0; + break; + + case SCAN_END: + // + // Move current cursor position to the end of the command line + // + TailRow = Row + (Len - StrPos + Column) / LineLength; + TailColumn = (Len - StrPos + Column) % LineLength; + Row = TailRow; + Column = TailColumn; + StrPos = Len; + break; + + case SCAN_ESC: + // + // Prepare to clear the current command line + // + InStr[0] = 0; + Update = 0; + Delete = Len; + Row -= (StrPos + StartColumn) / LineLength; + Column = StartColumn; + OutputLength = 0; + + NeedAdjust = TRUE; + break; + + case SCAN_INSERT: + // + // Toggle the SEnvInsertMode flag + // + InsertMode = (BOOLEAN) !InsertMode; + break; + + case SCAN_UP: + case SCAN_DOWN: + // + // show history + // + CopyMem (InStr, mInputBufferHistory, StrLength * sizeof (CHAR16)); + StrPos = StrLen (mInputBufferHistory); + Update = 0; + Delete = 0; + OutputLength = 0; + + TailRow = Row + (StrPos + StartColumn) / LineLength; + TailColumn = (StrPos + StartColumn) % LineLength; + Row = TailRow; + Column = TailColumn; + NeedAdjust = FALSE; + + ConOut->SetCursorPosition (ConOut, StartColumn, Row); + for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) { + mBackupSpace[SubIndex] = L' '; + } + + EDBPrint (mBackupSpace); + SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0); + + ConOut->SetCursorPosition (ConOut, StartColumn, Row); + Len = StrPos; + + break; + + case SCAN_F1: + case SCAN_F2: + case SCAN_F3: + case SCAN_F4: + case SCAN_F5: + case SCAN_F6: + case SCAN_F7: + case SCAN_F8: + case SCAN_F9: + case SCAN_F10: + case SCAN_F11: + case SCAN_F12: + CommandStr = GetCommandNameByKey (Key); + if (CommandStr != NULL) { + StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1); + return; + } + + break; + } + } + + if (Done) { + break; + } + + // + // If we need to update the output do so now + // + if (Update != -1) { + if (NeedAdjust) { + ConOut->SetCursorPosition (ConOut, Column, Row); + for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) { + mBackupSpace[SubIndex] = L' '; + } + + EDBPrint (mBackupSpace); + SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0); + ConOut->SetCursorPosition (ConOut, Column, Row); + NeedAdjust = FALSE; + } + + EDBPrint (InStr + Update); + Len = StrLen (InStr); + + if (Delete != 0) { + SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00); + } + + if (StrPos > Len) { + StrPos = Len; + } + + Update = (UINTN)-1; + + // + // After using print to reflect newly updates, if we're not using + // BACKSPACE and DELETE, we need to move the cursor position forward, + // so adjust row and column here. + // + if ((Key.UnicodeChar != CHAR_BACKSPACE) && !((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_DELETE))) { + // + // Calulate row and column of the tail of current string + // + TailRow = Row + (Len - StrPos + Column + OutputLength) / LineLength; + TailColumn = (Len - StrPos + Column + OutputLength) % LineLength; + + // + // If the tail of string reaches screen end, screen rolls up, so if + // Row does not equal TailRow, Row should be decremented + // + // (if we are recalling commands using UPPER and DOWN key, and if the + // old command is too long to fit the screen, TailColumn must be 79. + // + if ((TailColumn == 0) && (TailRow >= TotalRow) && ((UINTN)Row != TailRow)) { + Row--; + } + + // + // Calculate the cursor position after current operation. If cursor + // reaches line end, update both row and column, otherwise, only + // column will be changed. + // + if (Column + OutputLength >= LineLength) { + SkipLength = OutputLength - (LineLength - Column); + + Row += SkipLength / LineLength + 1; + if ((UINTN)Row > TotalRow - 1) { + Row = TotalRow - 1; + } + + Column = SkipLength % LineLength; + } else { + Column += OutputLength; + } + } + + Delete = 0; + } + + // + // Set the cursor position for this key + // + SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len); + } while (!Done); + + CopyMem (mInputBufferHistory, InStr, StrLength * sizeof (CHAR16)); + + // + // Return the data to the caller + // + return; +} + +/** + Set the current coordinates of the cursor position. + + @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. + @param Column The position to set the cursor to. + @param Row The position to set the cursor to. + @param LineLength Length of a line. + @param TotalRow Total row of a screen. + @param Str Point to the string. + @param StrPos The position of the string. + @param Len The length of the string. + +**/ +VOID +EFIAPI +SetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, + IN UINTN Column, + IN INTN Row, + IN UINTN LineLength, + IN UINTN TotalRow, + IN CHAR16 *Str, + IN UINTN StrPos, + IN UINTN Len + ) +{ + CHAR16 Backup; + + ASSERT (ConOut != NULL); + ASSERT (Str != NULL); + + Backup = 0; + if (Row >= 0) { + ConOut->SetCursorPosition (ConOut, Column, Row); + return; + } + + if (Len - StrPos > Column * Row) { + Backup = *(Str + StrPos + Column * Row); + *(Str + StrPos + Column * Row) = 0; + } + + EDBPrint (L"%s", Str + StrPos); + if (Len - StrPos > Column * Row) { + *(Str + StrPos + Column * Row) = Backup; + } + + ConOut->SetCursorPosition (ConOut, 0, 0); +} + +/** + + SetPageBreak. + +**/ +BOOLEAN +EFIAPI +SetPageBreak ( + VOID + ) +{ + EFI_INPUT_KEY Key; + CHAR16 Str[3]; + BOOLEAN OmitPrint; + + // + // Check + // + if (!mDebuggerPrivate.EnablePageBreak) { + return FALSE; + } + + gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:"); + + OmitPrint = FALSE; + // + // Wait for user input + // + Str[0] = ' '; + Str[1] = 0; + Str[2] = 0; + for ( ; ;) { + WaitForSingleEvent (gST->ConIn->WaitForKey, 0); + gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + + // + // handle control keys + // + if (Key.UnicodeChar == CHAR_NULL) { + if (Key.ScanCode == SCAN_ESC) { + gST->ConOut->OutputString (gST->ConOut, L"\r\n"); + OmitPrint = TRUE; + break; + } + + continue; + } + + if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + gST->ConOut->OutputString (gST->ConOut, L"\r\n"); + break; + } + + // + // Echo input + // + Str[1] = Key.UnicodeChar; + if (Str[1] == CHAR_BACKSPACE) { + continue; + } + + gST->ConOut->OutputString (gST->ConOut, Str); + + if ((Str[1] == L'q') || (Str[1] == L'Q')) { + OmitPrint = TRUE; + } else { + OmitPrint = FALSE; + } + + Str[0] = CHAR_BACKSPACE; + } + + return OmitPrint; +} + +/** + Print a Unicode string to the output device. + + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBPrint ( + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + CHAR16 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER]; + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker); + VA_END (Marker); + + if (gST->ConOut != NULL) { + // + // To be extra safe make sure ConOut has been initialized + // + gST->ConOut->OutputString (gST->ConOut, Buffer); + } + + return Return; +} + +/** + Print a Unicode string to the output buffer. + + @param Buffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBSPrint ( + OUT CHAR16 *Buffer, + IN INTN BufferSize, + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + + ASSERT (BufferSize > 0); + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker); + VA_END (Marker); + + return Return; +} + +/** + Print a Unicode string to the output buffer with specified offset.. + + @param Buffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param Offset The offset of the buffer. + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBSPrintWithOffset ( + OUT CHAR16 *Buffer, + IN INTN BufferSize, + IN UINTN Offset, + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + + ASSERT (BufferSize - (Offset * sizeof (CHAR16)) > 0); + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof (CHAR16))), Format, Marker); + VA_END (Marker); + + return Return; +} |
