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
);
228 // Read a line from the console
239 // If buffer is not large enough to hold a CHAR16, do nothing.
246 // Get the screen setting and the current cursor location
248 StartColumn
= ConOut
->Mode
->CursorColumn
;
249 Column
= StartColumn
;
250 Row
= ConOut
->Mode
->CursorRow
;
251 ConOut
->QueryMode (ConOut
, ConOut
->Mode
->Mode
, &LineLength
, &TotalRow
);
252 if (LineLength
== 0) {
256 SetMem (InStr
, StrLength
* sizeof (CHAR16
), 0);
262 WaitForSingleEvent (ConIn
->WaitForKey
, 0);
263 ConIn
->ReadKeyStroke (ConIn
, &Key
);
265 switch (Key
.UnicodeChar
) {
266 case CHAR_CARRIAGE_RETURN
:
268 // All done, print a newline at the end of the string
270 TailRow
= Row
+ (Len
- StrPos
+ Column
) / LineLength
;
271 TailColumn
= (Len
- StrPos
+ Column
) % LineLength
;
278 // If not move back beyond string beginning, move all characters behind
279 // the current position one character forward
284 CopyMem (InStr
+ StrPos
, InStr
+ StrPos
+ 1, sizeof (CHAR16
) * (Len
- StrPos
));
287 // Adjust the current column and row
289 ConMoveCursorBackward (LineLength
, &Column
, &Row
);
297 if (Key
.UnicodeChar
>= ' ') {
299 // If we are at the buffer's end, drop the key
301 if ((Len
== StrLength
- 1) && (InsertMode
|| (StrPos
== Len
))) {
306 // If in insert mode, move all characters behind the current position
307 // one character backward to make space for this character. Then store
311 for (Index
= Len
; Index
> StrPos
; Index
-= 1) {
312 InStr
[Index
] = InStr
[Index
- 1];
316 InStr
[StrPos
] = Key
.UnicodeChar
;
326 switch (Key
.ScanCode
) {
329 // Move characters behind current position one character forward
334 CopyMem (InStr
+ StrPos
, InStr
+ StrPos
+ 1, sizeof (CHAR16
) * (Len
- StrPos
));
343 // Adjust current cursor position
347 ConMoveCursorBackward (LineLength
, &Column
, &Row
);
354 // Adjust current cursor position
358 ConMoveCursorForward (LineLength
, TotalRow
, &Column
, &Row
);
365 // Move current cursor position to the beginning of the command line
367 Row
-= (StrPos
+ StartColumn
) / LineLength
;
368 Column
= StartColumn
;
374 // Move current cursor position to the end of the command line
376 TailRow
= Row
+ (Len
- StrPos
+ Column
) / LineLength
;
377 TailColumn
= (Len
- StrPos
+ Column
) % LineLength
;
385 // Prepare to clear the current command line
390 Row
-= (StrPos
+ StartColumn
) / LineLength
;
391 Column
= StartColumn
;
399 // Toggle the SEnvInsertMode flag
401 InsertMode
= (BOOLEAN
) !InsertMode
;
409 CopyMem (InStr
, mInputBufferHistory
, StrLength
* sizeof (CHAR16
));
410 StrPos
= StrLen (mInputBufferHistory
);
415 TailRow
= Row
+ (StrPos
+ StartColumn
) / LineLength
;
416 TailColumn
= (StrPos
+ StartColumn
) % LineLength
;
421 ConOut
->SetCursorPosition (ConOut
, StartColumn
, Row
);
422 for (SubIndex
= 0; SubIndex
< EFI_DEBUG_INPUS_BUFFER_SIZE
- (StartColumn
- EFI_DEBUG_PROMPT_COLUMN
); SubIndex
++) {
423 mBackupSpace
[SubIndex
] = L
' ';
426 EDBPrint (mBackupSpace
);
427 SetMem (mBackupSpace
, (EFI_DEBUG_INPUS_BUFFER_SIZE
- (StartColumn
- EFI_DEBUG_PROMPT_COLUMN
)) * sizeof (CHAR16
), 0);
429 ConOut
->SetCursorPosition (ConOut
, StartColumn
, Row
);
446 CommandStr
= GetCommandNameByKey (Key
);
447 if (CommandStr
!= NULL
) {
448 StrnCpyS (InStr
, StrLength
, CommandStr
, StrLength
- 1);
461 // If we need to update the output do so now
465 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
466 for (SubIndex
= 0; SubIndex
< EFI_DEBUG_INPUS_BUFFER_SIZE
- (Column
- EFI_DEBUG_PROMPT_COLUMN
); SubIndex
++) {
467 mBackupSpace
[SubIndex
] = L
' ';
470 EDBPrint (mBackupSpace
);
471 SetMem (mBackupSpace
, (EFI_DEBUG_INPUS_BUFFER_SIZE
- (Column
- EFI_DEBUG_PROMPT_COLUMN
)) * sizeof (CHAR16
), 0);
472 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
476 EDBPrint (InStr
+ Update
);
477 Len
= StrLen (InStr
);
480 SetMem (InStr
+ Len
, Delete
* sizeof (CHAR16
), 0x00);
490 // After using print to reflect newly updates, if we're not using
491 // BACKSPACE and DELETE, we need to move the cursor position forward,
492 // so adjust row and column here.
494 if ((Key
.UnicodeChar
!= CHAR_BACKSPACE
) && !((Key
.UnicodeChar
== 0) && (Key
.ScanCode
== SCAN_DELETE
))) {
496 // Calulate row and column of the tail of current string
498 TailRow
= Row
+ (Len
- StrPos
+ Column
+ OutputLength
) / LineLength
;
499 TailColumn
= (Len
- StrPos
+ Column
+ OutputLength
) % LineLength
;
502 // If the tail of string reaches screen end, screen rolls up, so if
503 // Row does not equal TailRow, Row should be decremented
505 // (if we are recalling commands using UPPER and DOWN key, and if the
506 // old command is too long to fit the screen, TailColumn must be 79.
508 if ((TailColumn
== 0) && (TailRow
>= TotalRow
) && ((UINTN
)Row
!= TailRow
)) {
513 // Calculate the cursor position after current operation. If cursor
514 // reaches line end, update both row and column, otherwise, only
515 // column will be changed.
517 if (Column
+ OutputLength
>= LineLength
) {
518 SkipLength
= OutputLength
- (LineLength
- Column
);
520 Row
+= SkipLength
/ LineLength
+ 1;
521 if ((UINTN
)Row
> TotalRow
- 1) {
525 Column
= SkipLength
% LineLength
;
527 Column
+= OutputLength
;
535 // Set the cursor position for this key
537 SetCursorPosition (ConOut
, Column
, Row
, LineLength
, TotalRow
, InStr
, StrPos
, Len
);
540 CopyMem (mInputBufferHistory
, InStr
, StrLength
* sizeof (CHAR16
));
543 // Return the data to the caller
549 Set the current coordinates of the cursor position.
551 @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
552 @param Column The position to set the cursor to.
553 @param Row The position to set the cursor to.
554 @param LineLength Length of a line.
555 @param TotalRow Total row of a screen.
556 @param Str Point to the string.
557 @param StrPos The position of the string.
558 @param Len The length of the string.
564 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
,
576 ASSERT (ConOut
!= NULL
);
577 ASSERT (Str
!= NULL
);
581 ConOut
->SetCursorPosition (ConOut
, Column
, Row
);
585 if (Len
- StrPos
> Column
* Row
) {
586 Backup
= *(Str
+ StrPos
+ Column
* Row
);
587 *(Str
+ StrPos
+ Column
* Row
) = 0;
590 EDBPrint (L
"%s", Str
+ StrPos
);
591 if (Len
- StrPos
> Column
* Row
) {
592 *(Str
+ StrPos
+ Column
* Row
) = Backup
;
595 ConOut
->SetCursorPosition (ConOut
, 0, 0);
616 if (!mDebuggerPrivate
.EnablePageBreak
) {
620 gST
->ConOut
->OutputString (gST
->ConOut
, L
"Press ENTER to continue, 'q' to exit:");
624 // Wait for user input
630 WaitForSingleEvent (gST
->ConIn
->WaitForKey
, 0);
631 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
634 // handle control keys
636 if (Key
.UnicodeChar
== CHAR_NULL
) {
637 if (Key
.ScanCode
== SCAN_ESC
) {
638 gST
->ConOut
->OutputString (gST
->ConOut
, L
"\r\n");
646 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
647 gST
->ConOut
->OutputString (gST
->ConOut
, L
"\r\n");
654 Str
[1] = Key
.UnicodeChar
;
655 if (Str
[1] == CHAR_BACKSPACE
) {
659 gST
->ConOut
->OutputString (gST
->ConOut
, Str
);
661 if ((Str
[1] == L
'q') || (Str
[1] == L
'Q')) {
667 Str
[0] = CHAR_BACKSPACE
;
674 Print a Unicode string to the output device.
676 @param Format A Null-terminated Unicode format string.
677 @param ... The variable argument list that contains pointers to Null-
678 terminated Unicode strings to be printed
684 IN CONST CHAR16
*Format
,
690 CHAR16 Buffer
[EFI_DEBUG_MAX_PRINT_BUFFER
];
692 VA_START (Marker
, Format
);
693 Return
= UnicodeVSPrint (Buffer
, sizeof (Buffer
), Format
, Marker
);
696 if (gST
->ConOut
!= NULL
) {
698 // To be extra safe make sure ConOut has been initialized
700 gST
->ConOut
->OutputString (gST
->ConOut
, Buffer
);
707 Print a Unicode string to the output buffer.
709 @param Buffer A pointer to the output buffer for the produced Null-terminated
711 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
712 @param Format A Null-terminated Unicode format string.
713 @param ... The variable argument list that contains pointers to Null-
714 terminated Unicode strings to be printed
722 IN CONST CHAR16
*Format
,
729 ASSERT (BufferSize
> 0);
731 VA_START (Marker
, Format
);
732 Return
= UnicodeVSPrint (Buffer
, (UINTN
)BufferSize
, Format
, Marker
);
739 Print a Unicode string to the output buffer with specified offset..
741 @param Buffer A pointer to the output buffer for the produced Null-terminated
743 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
744 @param Offset The offset of the buffer.
745 @param Format A Null-terminated Unicode format string.
746 @param ... The variable argument list that contains pointers to Null-
747 terminated Unicode strings to be printed
752 EDBSPrintWithOffset (
756 IN CONST CHAR16
*Format
,
763 ASSERT (BufferSize
- (Offset
* sizeof (CHAR16
)) > 0);
765 VA_START (Marker
, Format
);
766 Return
= UnicodeVSPrint (Buffer
+ Offset
, (UINTN
)(BufferSize
- (Offset
* sizeof (CHAR16
))), Format
, Marker
);