3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Set the current coordinates of the cursor position.
14 @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
15 @param Column The position to set the cursor to.
16 @param Row The position to set the cursor to.
17 @param LineLength Length of a line.
18 @param TotalRow Total row of a screen.
19 @param Str Point to the string.
20 @param StrPos The position of the string.
21 @param Len The length of the string.
27 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
,
39 Function waits for a given event to fire, or for an optional timeout to expire.
41 @param Event - The event to wait for
42 @param Timeout - An optional timeout value in 100 ns units.
44 @retval EFI_SUCCESS - Event fired before Timeout expired.
45 @retval EFI_TIME_OUT - Timout expired before Event fired..
52 IN UINT64 Timeout OPTIONAL
58 EFI_EVENT WaitList
[2];
62 // Create a timer event
64 Status
= gBS
->CreateEvent (EVT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
65 if (!EFI_ERROR (Status
)) {
67 // Set the timer event
76 // Wait for the original event or the timer
79 WaitList
[1] = TimerEvent
;
80 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
81 gBS
->CloseEvent (TimerEvent
);
84 // If the timer expired, change the return to timed out
86 if (!EFI_ERROR (Status
) && Index
== 1) {
92 // No timeout... just wait on the event
94 Status
= gBS
->WaitForEvent (1, &Event
, &Index
);
95 ASSERT (!EFI_ERROR (Status
));
104 Move the cursor position one character backward.
106 @param LineLength Length of a line. Get it by calling QueryMode
107 @param Column Current column of the cursor position
108 @param Row Current row of the cursor position
113 ConMoveCursorBackward (
115 IN OUT UINTN
*Column
,
119 ASSERT (Column
!= NULL
);
120 ASSERT (Row
!= NULL
);
122 // If current column is 0, move to the last column of the previous line,
123 // otherwise, just decrement column.
126 (*Column
) = LineLength
- 1;
141 Move the cursor position one character backward.
143 @param LineLength Length of a line. Get it by calling QueryMode
144 @param TotalRow Total row of a screen, get by calling QueryMode
145 @param Column Current column of the cursor position
146 @param Row Current row of the cursor position
151 ConMoveCursorForward (
154 IN OUT UINTN
*Column
,
158 ASSERT (Column
!= NULL
);
159 ASSERT (Row
!= NULL
);
161 // If current column is at line end, move to the first column of the nest
162 // line, otherwise, just increment column.
165 if (*Column
>= LineLength
) {
167 if ((*Row
) < TotalRow
- 1) {
173 CHAR16 mBackupSpace
[EFI_DEBUG_INPUS_BUFFER_SIZE
];
174 CHAR16 mInputBufferHistory
[EFI_DEBUG_INPUS_BUFFER_SIZE
];
180 @param Prompt The prompt string.
181 @param InStr Point to the input string.
182 @param StrLength The max length of string user can input.
188 IN CHAR16
*Prompt OPTIONAL
,
193 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
194 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*ConIn
;
216 ConOut
= gST
->ConOut
;
219 ASSERT (ConOut
!= NULL
);
220 ASSERT (ConIn
!= NULL
);
221 ASSERT (InStr
!= NULL
);
223 if (Prompt
!= NULL
) {
224 ConOut
->OutputString (ConOut
, Prompt
);
227 // Read a line from the console
238 // If buffer is not large enough to hold a CHAR16, do nothing.
244 // Get the screen setting and the current cursor location
246 StartColumn
= ConOut
->Mode
->CursorColumn
;
247 Column
= StartColumn
;
248 Row
= ConOut
->Mode
->CursorRow
;
249 ConOut
->QueryMode (ConOut
, ConOut
->Mode
->Mode
, &LineLength
, &TotalRow
);
250 if (LineLength
== 0) {
254 SetMem (InStr
, StrLength
* sizeof (CHAR16
), 0);
260 WaitForSingleEvent (ConIn
->WaitForKey
, 0);
261 ConIn
->ReadKeyStroke (ConIn
, &Key
);
263 switch (Key
.UnicodeChar
) {
264 case CHAR_CARRIAGE_RETURN
:
266 // All done, print a newline at the end of the string
268 TailRow
= Row
+ (Len
- StrPos
+ Column
) / LineLength
;
269 TailColumn
= (Len
- StrPos
+ Column
) % LineLength
;
276 // If not move back beyond string beginning, move all characters behind
277 // the current position one character forward
282 CopyMem (InStr
+ StrPos
, InStr
+ StrPos
+ 1, sizeof (CHAR16
) * (Len
- StrPos
));
285 // Adjust the current column and row
287 ConMoveCursorBackward (LineLength
, &Column
, &Row
);
294 if (Key
.UnicodeChar
>= ' ') {
296 // If we are at the buffer's end, drop the key
298 if (Len
== StrLength
- 1 && (InsertMode
|| StrPos
== Len
)) {
302 // If in insert mode, move all characters behind the current position
303 // one character backward to make space for this character. Then store
307 for (Index
= Len
; Index
> StrPos
; Index
-= 1) {
308 InStr
[Index
] = InStr
[Index
- 1];
312 InStr
[StrPos
] = Key
.UnicodeChar
;
321 switch (Key
.ScanCode
) {
324 // Move characters behind current position one character forward
329 CopyMem (InStr
+ StrPos
, InStr
+ StrPos
+ 1, sizeof (CHAR16
) * (Len
- StrPos
));
337 // Adjust current cursor position
341 ConMoveCursorBackward (LineLength
, &Column
, &Row
);
347 // Adjust current cursor position
351 ConMoveCursorForward (LineLength
, TotalRow
, &Column
, &Row
);
357 // Move current cursor position to the beginning of the command line
359 Row
-= (StrPos
+ StartColumn
) / LineLength
;
360 Column
= StartColumn
;
366 // Move current cursor position to the end of the command line
368 TailRow
= Row
+ (Len
- StrPos
+ Column
) / LineLength
;
369 TailColumn
= (Len
- StrPos
+ Column
) % LineLength
;
377 // Prepare to clear the current command line
382 Row
-= (StrPos
+ StartColumn
) / LineLength
;
383 Column
= StartColumn
;
391 // Toggle the SEnvInsertMode flag
393 InsertMode
= (BOOLEAN
)!InsertMode
;
401 CopyMem (InStr
, mInputBufferHistory
, StrLength
* sizeof(CHAR16
));
402 StrPos
= StrLen (mInputBufferHistory
);
407 TailRow
= Row
+ (StrPos
+ StartColumn
) / LineLength
;
408 TailColumn
= (StrPos
+ StartColumn
) % LineLength
;
413 ConOut
->SetCursorPosition (ConOut
, StartColumn
, Row
);
414 for (SubIndex
= 0; SubIndex
< EFI_DEBUG_INPUS_BUFFER_SIZE
- (StartColumn
- EFI_DEBUG_PROMPT_COLUMN
); SubIndex
++) {
415 mBackupSpace
[SubIndex
] = L
' ';
417 EDBPrint (mBackupSpace
);
418 SetMem (mBackupSpace
, (EFI_DEBUG_INPUS_BUFFER_SIZE
- (StartColumn
- EFI_DEBUG_PROMPT_COLUMN
)) * sizeof(CHAR16
), 0);
420 ConOut
->SetCursorPosition (ConOut
, StartColumn
, Row
);
437 CommandStr
= GetCommandNameByKey (Key
);
438 if (CommandStr
!= NULL
) {
439 StrnCpyS (InStr
, StrLength
, CommandStr
, StrLength
- 1);
450 // If we need to update the output do so now
454 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
455 for (SubIndex
= 0; SubIndex
< EFI_DEBUG_INPUS_BUFFER_SIZE
- (Column
- EFI_DEBUG_PROMPT_COLUMN
); SubIndex
++) {
456 mBackupSpace
[SubIndex
] = L
' ';
458 EDBPrint (mBackupSpace
);
459 SetMem (mBackupSpace
, (EFI_DEBUG_INPUS_BUFFER_SIZE
- (Column
- EFI_DEBUG_PROMPT_COLUMN
)) * sizeof(CHAR16
), 0);
460 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
463 EDBPrint (InStr
+ Update
);
464 Len
= StrLen (InStr
);
467 SetMem (InStr
+ Len
, Delete
* sizeof (CHAR16
), 0x00);
477 // After using print to reflect newly updates, if we're not using
478 // BACKSPACE and DELETE, we need to move the cursor position forward,
479 // so adjust row and column here.
481 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
483 // Calulate row and column of the tail of current string
485 TailRow
= Row
+ (Len
- StrPos
+ Column
+ OutputLength
) / LineLength
;
486 TailColumn
= (Len
- StrPos
+ Column
+ OutputLength
) % LineLength
;
489 // If the tail of string reaches screen end, screen rolls up, so if
490 // Row does not equal TailRow, Row should be decremented
492 // (if we are recalling commands using UPPER and DOWN key, and if the
493 // old command is too long to fit the screen, TailColumn must be 79.
495 if (TailColumn
== 0 && TailRow
>= TotalRow
&& (UINTN
) Row
!= TailRow
) {
499 // Calculate the cursor position after current operation. If cursor
500 // reaches line end, update both row and column, otherwise, only
501 // column will be changed.
503 if (Column
+ OutputLength
>= LineLength
) {
504 SkipLength
= OutputLength
- (LineLength
- Column
);
506 Row
+= SkipLength
/ LineLength
+ 1;
507 if ((UINTN
) Row
> TotalRow
- 1) {
511 Column
= SkipLength
% LineLength
;
513 Column
+= OutputLength
;
520 // Set the cursor position for this key
522 SetCursorPosition (ConOut
, Column
, Row
, LineLength
, TotalRow
, InStr
, StrPos
, Len
);
525 CopyMem (mInputBufferHistory
, InStr
, StrLength
* sizeof(CHAR16
));
528 // Return the data to the caller
534 Set the current coordinates of the cursor position.
536 @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
537 @param Column The position to set the cursor to.
538 @param Row The position to set the cursor to.
539 @param LineLength Length of a line.
540 @param TotalRow Total row of a screen.
541 @param Str Point to the string.
542 @param StrPos The position of the string.
543 @param Len The length of the string.
549 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
,
561 ASSERT (ConOut
!= NULL
);
562 ASSERT (Str
!= NULL
);
566 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
570 if (Len
- StrPos
> Column
* Row
) {
571 Backup
= *(Str
+ StrPos
+ Column
* Row
);
572 *(Str
+ StrPos
+ Column
* Row
) = 0;
575 EDBPrint (L
"%s", Str
+ StrPos
);
576 if (Len
- StrPos
> Column
* Row
) {
577 *(Str
+ StrPos
+ Column
* Row
) = Backup
;
580 ConOut
->SetCursorPosition (ConOut
, 0, 0);
601 if (!mDebuggerPrivate
.EnablePageBreak
) {
605 gST
->ConOut
->OutputString (gST
->ConOut
, L
"Press ENTER to continue, 'q' to exit:");
609 // Wait for user input
615 WaitForSingleEvent (gST
->ConIn
->WaitForKey
, 0);
616 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
619 // handle control keys
621 if (Key
.UnicodeChar
== CHAR_NULL
) {
622 if (Key
.ScanCode
== SCAN_ESC
) {
623 gST
->ConOut
->OutputString (gST
->ConOut
, L
"\r\n");
631 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
632 gST
->ConOut
->OutputString (gST
->ConOut
, L
"\r\n");
638 Str
[1] = Key
.UnicodeChar
;
639 if (Str
[1] == CHAR_BACKSPACE
) {
643 gST
->ConOut
->OutputString (gST
->ConOut
, Str
);
645 if ((Str
[1] == L
'q') || (Str
[1] == L
'Q')) {
651 Str
[0] = CHAR_BACKSPACE
;
658 Print a Unicode string to the output device.
660 @param Format A Null-terminated Unicode format string.
661 @param ... The variable argument list that contains pointers to Null-
662 terminated Unicode strings to be printed
668 IN CONST CHAR16
*Format
,
674 CHAR16 Buffer
[EFI_DEBUG_MAX_PRINT_BUFFER
];
676 VA_START (Marker
, Format
);
677 Return
= UnicodeVSPrint (Buffer
, sizeof (Buffer
), Format
, Marker
);
680 if (gST
->ConOut
!= NULL
) {
682 // To be extra safe make sure ConOut has been initialized
684 gST
->ConOut
->OutputString (gST
->ConOut
, Buffer
);
691 Print a Unicode string to the output buffer.
693 @param Buffer A pointer to the output buffer for the produced Null-terminated
695 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
696 @param Format A Null-terminated Unicode format string.
697 @param ... The variable argument list that contains pointers to Null-
698 terminated Unicode strings to be printed
706 IN CONST CHAR16
*Format
,
713 ASSERT (BufferSize
> 0);
715 VA_START (Marker
, Format
);
716 Return
= UnicodeVSPrint (Buffer
, (UINTN
)BufferSize
, Format
, Marker
);
723 Print a Unicode string to the output buffer with specified offset..
725 @param Buffer A pointer to the output buffer for the produced Null-terminated
727 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
728 @param Offset The offset of the buffer.
729 @param Format A Null-terminated Unicode format string.
730 @param ... The variable argument list that contains pointers to Null-
731 terminated Unicode strings to be printed
736 EDBSPrintWithOffset (
740 IN CONST CHAR16
*Format
,
747 ASSERT (BufferSize
- (Offset
* sizeof(CHAR16
)) > 0);
749 VA_START (Marker
, Format
);
750 Return
= UnicodeVSPrint (Buffer
+ Offset
, (UINTN
)(BufferSize
- (Offset
* sizeof(CHAR16
))), Format
, Marker
);