]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
1. Sync the latest network stack. Add NetLibCreateIPv4DPathNode () in netlib library.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConOut.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 TerminalConOut.c
15
16 Abstract:
17
18
19 Revision History
20 --*/
21
22 #include "Terminal.h"
23
24 //
25 // This list is used to define the valid extend chars.
26 // It also provides a mapping from Unicode to PCANSI or
27 // ASCII. The ASCII mapping we just made up.
28 //
29 //
30 STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
31 { BOXDRAW_HORIZONTAL, 0xc4, L'-' },
32 { BOXDRAW_VERTICAL, 0xb3, L'|' },
33 { BOXDRAW_DOWN_RIGHT, 0xda, L'/' },
34 { BOXDRAW_DOWN_LEFT, 0xbf, L'\\' },
35 { BOXDRAW_UP_RIGHT, 0xc0, L'\\' },
36 { BOXDRAW_UP_LEFT, 0xd9, L'/' },
37 { BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|' },
38 { BOXDRAW_VERTICAL_LEFT, 0xb4, L'|' },
39 { BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+' },
40 { BOXDRAW_UP_HORIZONTAL, 0xc1, L'+' },
41 { BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+' },
42 { BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-' },
43 { BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|' },
44 { BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/' },
45 { BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/' },
46 { BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/' },
47 { BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\' },
48 { BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\' },
49 { BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\' },
50 { BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\' },
51 { BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\' },
52 { BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\' },
53 { BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/' },
54 { BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/' },
55 { BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/' },
56 { BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|' },
57 { BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|' },
58 { BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|' },
59 { BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|' },
60 { BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|' },
61 { BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|' },
62 { BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+' },
63 { BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+' },
64 { BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+' },
65 { BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+' },
66 { BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+' },
67 { BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+' },
68 { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' },
69 { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' },
70 { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' },
71
72 { BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*' },
73 { BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+' },
74
75 { GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, L'^' },
76 { GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, L'>' },
77 { GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, L'v' },
78 { GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, L'<' },
79
80 { ARROW_LEFT, 0x3c, L'<' },
81 { ARROW_UP, 0x18, L'^' },
82 { ARROW_RIGHT, 0x3e, L'>' },
83 { ARROW_DOWN, 0x19, L'v' },
84
85 { 0x0000, 0x00, L'\0' }
86 };
87
88 CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 };
89 CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };
90 CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 };
91 CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 };
92
93 //
94 // Body of the ConOut functions
95 //
96 EFI_STATUS
97 EFIAPI
98 TerminalConOutReset (
99 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
100 IN BOOLEAN ExtendedVerification
101 )
102 /*++
103 Routine Description:
104
105 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().
106 If ExtendeVerification is TRUE, then perform dependent serial device reset,
107 and set display mode to mode 0.
108 If ExtendedVerification is FALSE, only set display mode to mode 0.
109
110 Arguments:
111
112 This - Indicates the calling context.
113
114 ExtendedVerification - Indicates that the driver may perform a more exhaustive
115 verification operation of the device during reset.
116
117 Returns:
118
119 EFI_SUCCESS
120 The reset operation succeeds.
121
122 EFI_DEVICE_ERROR
123 The terminal is not functioning correctly or the serial port reset fails.
124
125 --*/
126 {
127 EFI_STATUS Status;
128 TERMINAL_DEV *TerminalDevice;
129
130 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
131
132 //
133 // Perform a more exhaustive reset by resetting the serial port.
134 //
135 if (ExtendedVerification) {
136 //
137 // Report progress code here
138 //
139 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
140 EFI_PROGRESS_CODE,
141 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),
142 TerminalDevice->DevicePath
143 );
144
145 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
146 if (EFI_ERROR (Status)) {
147 //
148 // Report error code here
149 //
150 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
151 EFI_ERROR_CODE | EFI_ERROR_MINOR,
152 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),
153 TerminalDevice->DevicePath
154 );
155
156 return Status;
157 }
158 }
159
160 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
161
162 Status = This->SetMode (This, 0);
163
164 return Status;
165 }
166
167 EFI_STATUS
168 EFIAPI
169 TerminalConOutOutputString (
170 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
171 IN CHAR16 *WString
172 )
173 /*++
174 Routine Description:
175
176 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
177 The Unicode string will be converted to terminal expressible data stream
178 and send to terminal via serial port.
179
180
181 Arguments:
182
183 This - Indicates the calling context.
184
185 WString - The Null-terminated Unicode string to be displayed on
186 the terminal screen.
187
188 Returns:
189
190 EFI_SUCCESS
191 The string is output successfully.
192
193 EFI_DEVICE_ERROR
194 The serial port fails to send the string out.
195
196 EFI_WARN_UNKNOWN_GLYPH
197 Indicates that some of the characters in the Unicode string could not
198 be rendered and are skipped.
199
200 EFI_UNSUPPORTED
201
202 --*/
203 {
204 TERMINAL_DEV *TerminalDevice;
205 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
206 UINTN MaxColumn;
207 UINTN MaxRow;
208 UINTN Length;
209 UTF8_CHAR Utf8Char;
210 CHAR8 GraphicChar;
211 CHAR8 AsciiChar;
212 EFI_STATUS Status;
213 UINT8 ValidBytes;
214 //
215 // flag used to indicate whether condition happens which will cause
216 // return EFI_WARN_UNKNOWN_GLYPH
217 //
218 BOOLEAN Warning;
219
220 ValidBytes = 0;
221 Warning = FALSE;
222
223 //
224 // get Terminal device data structure pointer.
225 //
226 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
227
228 //
229 // get current display mode
230 // Terminal driver only support mode 0
231 //
232 Mode = This->Mode;
233 if (Mode->Mode != 0) {
234 return EFI_UNSUPPORTED;
235 }
236
237 This->QueryMode (
238 This,
239 Mode->Mode,
240 &MaxColumn,
241 &MaxRow
242 );
243
244 for (; *WString != CHAR_NULL; WString++) {
245
246 switch (TerminalDevice->TerminalType) {
247
248 case PcAnsiType:
249 case VT100Type:
250 case VT100PlusType:
251
252 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
253 //
254 // If it's not a graphic character convert Unicode to ASCII.
255 //
256 GraphicChar = (CHAR8) *WString;
257
258 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {
259 //
260 // when this driver use the OutputString to output control string,
261 // TerminalDevice->OutputEscChar is set to let the Esc char
262 // to be output to the terminal emulation software.
263 //
264 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {
265 GraphicChar = 27;
266 } else {
267 GraphicChar = '?';
268 Warning = TRUE;
269 }
270 }
271
272 AsciiChar = GraphicChar;
273
274 }
275
276 if (TerminalDevice->TerminalType != PcAnsiType) {
277 GraphicChar = AsciiChar;
278 }
279
280 Length = 1;
281
282 Status = TerminalDevice->SerialIo->Write (
283 TerminalDevice->SerialIo,
284 &Length,
285 &GraphicChar
286 );
287
288 if (EFI_ERROR (Status)) {
289 goto OutputError;
290 }
291
292 break;
293
294 case VTUTF8Type:
295 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);
296 Length = ValidBytes;
297 Status = TerminalDevice->SerialIo->Write (
298 TerminalDevice->SerialIo,
299 &Length,
300 (UINT8 *) &Utf8Char
301 );
302 if (EFI_ERROR (Status)) {
303 goto OutputError;
304 }
305 break;
306 }
307 //
308 // Update cursor position.
309 //
310 switch (*WString) {
311
312 case CHAR_BACKSPACE:
313 if (Mode->CursorColumn > 0) {
314 Mode->CursorColumn--;
315 }
316 break;
317
318 case CHAR_LINEFEED:
319 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
320 Mode->CursorRow++;
321 }
322 break;
323
324 case CHAR_CARRIAGE_RETURN:
325 Mode->CursorColumn = 0;
326 break;
327
328 default:
329 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {
330
331 Mode->CursorColumn++;
332
333 } else {
334
335 Mode->CursorColumn = 0;
336 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
337 Mode->CursorRow++;
338 }
339
340 }
341 break;
342
343 };
344
345 }
346
347 if (Warning) {
348 return EFI_WARN_UNKNOWN_GLYPH;
349 }
350
351 return EFI_SUCCESS;
352
353 OutputError:
354 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
355 EFI_ERROR_CODE | EFI_ERROR_MINOR,
356 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError),
357 TerminalDevice->DevicePath
358 );
359
360 return EFI_DEVICE_ERROR;
361 }
362
363 EFI_STATUS
364 EFIAPI
365 TerminalConOutTestString (
366 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
367 IN CHAR16 *WString
368 )
369 /*++
370 Routine Description:
371
372 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().
373 If one of the characters in the *Wstring is
374 neither valid Unicode drawing characters,
375 not ASCII code, then this function will return
376 EFI_UNSUPPORTED.
377
378
379 Arguments:
380
381 This - Indicates the calling context.
382
383 WString - The Null-terminated Unicode string to be tested.
384
385 Returns:
386
387 EFI_SUCCESS
388 The terminal is capable of rendering the output string.
389
390 EFI_UNSUPPORTED
391 Some of the characters in the Unicode string cannot be rendered.
392
393 --*/
394 {
395 TERMINAL_DEV *TerminalDevice;
396 EFI_STATUS Status;
397
398 //
399 // get Terminal device data structure pointer.
400 //
401 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
402
403 switch (TerminalDevice->TerminalType) {
404
405 case PcAnsiType:
406 case VT100Type:
407 case VT100PlusType:
408 Status = AnsiTestString (TerminalDevice, WString);
409 break;
410
411 case VTUTF8Type:
412 Status = VTUTF8TestString (TerminalDevice, WString);
413 break;
414
415 default:
416 Status = EFI_UNSUPPORTED;
417 break;
418 }
419
420 return Status;
421 }
422
423 EFI_STATUS
424 EFIAPI
425 TerminalConOutQueryMode (
426 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
427 IN UINTN ModeNumber,
428 OUT UINTN *Columns,
429 OUT UINTN *Rows
430 )
431 /*++
432 Routine Description:
433
434 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
435 It returns information for an available text mode
436 that the terminal supports.
437 In this driver, we only support text mode 80x25, which is
438 defined as mode 0.
439
440
441 Arguments:
442
443 *This
444 Indicates the calling context.
445
446 ModeNumber
447 The mode number to return information on.
448
449 Columns
450 The returned columns of the requested mode.
451
452 Rows
453 The returned rows of the requested mode.
454
455 Returns:
456
457 EFI_SUCCESS
458 The requested mode information is returned.
459
460 EFI_UNSUPPORTED
461 The mode number is not valid.
462
463 EFI_DEVICE_ERROR
464
465 --*/
466 {
467 if (This->Mode->MaxMode > 1) {
468 return EFI_DEVICE_ERROR;
469 }
470
471 if (ModeNumber == 0) {
472
473 *Columns = MODE0_COLUMN_COUNT;
474 *Rows = MODE0_ROW_COUNT;
475
476 return EFI_SUCCESS;
477 }
478
479 return EFI_UNSUPPORTED;
480 }
481
482 EFI_STATUS
483 EFIAPI
484 TerminalConOutSetMode (
485 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
486 IN UINTN ModeNumber
487 )
488 /*++
489 Routine Description:
490
491 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
492 Set the terminal to a specified display mode.
493 In this driver, we only support mode 0.
494
495 Arguments:
496
497 This
498 Indicates the calling context.
499
500 ModeNumber
501 The text mode to set.
502
503 Returns:
504
505 EFI_SUCCESS
506 The requested text mode is set.
507
508 EFI_DEVICE_ERROR
509 The requested text mode cannot be set because of serial device error.
510
511 EFI_UNSUPPORTED
512 The text mode number is not valid.
513
514 --*/
515 {
516 EFI_STATUS Status;
517 TERMINAL_DEV *TerminalDevice;
518
519 //
520 // get Terminal device data structure pointer.
521 //
522 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
523
524 if (ModeNumber != 0) {
525 return EFI_UNSUPPORTED;
526 }
527
528 This->Mode->Mode = 0;
529
530 This->ClearScreen (This);
531
532 TerminalDevice->OutputEscChar = TRUE;
533 Status = This->OutputString (This, mSetModeString);
534 TerminalDevice->OutputEscChar = FALSE;
535
536 if (EFI_ERROR (Status)) {
537 return EFI_DEVICE_ERROR;
538 }
539
540 This->Mode->Mode = 0;
541
542 Status = This->ClearScreen (This);
543 if (EFI_ERROR (Status)) {
544 return EFI_DEVICE_ERROR;
545 }
546
547 return EFI_SUCCESS;
548
549 }
550
551 EFI_STATUS
552 EFIAPI
553 TerminalConOutSetAttribute (
554 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
555 IN UINTN Attribute
556 )
557 /*++
558 Routine Description:
559
560 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
561
562 Arguments:
563
564 This
565 Indicates the calling context.
566
567 Attribute
568 The attribute to set. Only bit0..6 are valid, all other bits
569 are undefined and must be zero.
570
571 Returns:
572
573 EFI_SUCCESS
574 The requested attribute is set.
575
576 EFI_DEVICE_ERROR
577 The requested attribute cannot be set due to serial port error.
578
579 EFI_UNSUPPORTED
580 The attribute requested is not defined by EFI spec.
581
582 --*/
583 {
584 UINT8 ForegroundControl;
585 UINT8 BackgroundControl;
586 UINT8 BrightControl;
587 INT32 SavedColumn;
588 INT32 SavedRow;
589 EFI_STATUS Status;
590 TERMINAL_DEV *TerminalDevice;
591
592 SavedColumn = 0;
593 SavedRow = 0;
594
595 //
596 // get Terminal device data structure pointer.
597 //
598 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
599
600 //
601 // only the bit0..6 of the Attribute is valid
602 //
603 if ((Attribute | 0x7f) != 0x7f) {
604 return EFI_UNSUPPORTED;
605 }
606 //
607 // convert Attribute value to terminal emulator
608 // understandable foreground color
609 //
610 switch (Attribute & 0x07) {
611
612 case EFI_BLACK:
613 ForegroundControl = 30;
614 break;
615
616 case EFI_BLUE:
617 ForegroundControl = 34;
618 break;
619
620 case EFI_GREEN:
621 ForegroundControl = 32;
622 break;
623
624 case EFI_CYAN:
625 ForegroundControl = 36;
626 break;
627
628 case EFI_RED:
629 ForegroundControl = 31;
630 break;
631
632 case EFI_MAGENTA:
633 ForegroundControl = 35;
634 break;
635
636 case EFI_BROWN:
637 ForegroundControl = 33;
638 break;
639
640 default:
641
642 case EFI_LIGHTGRAY:
643 ForegroundControl = 37;
644 break;
645
646 }
647 //
648 // bit4 of the Attribute indicates bright control
649 // of terminal emulator.
650 //
651 BrightControl = (UINT8) ((Attribute >> 3) & 1);
652
653 //
654 // convert Attribute value to terminal emulator
655 // understandable background color.
656 //
657 switch ((Attribute >> 4) & 0x07) {
658
659 case EFI_BLACK:
660 BackgroundControl = 40;
661 break;
662
663 case EFI_BLUE:
664 BackgroundControl = 44;
665 break;
666
667 case EFI_GREEN:
668 BackgroundControl = 42;
669 break;
670
671 case EFI_CYAN:
672 BackgroundControl = 46;
673 break;
674
675 case EFI_RED:
676 BackgroundControl = 41;
677 break;
678
679 case EFI_MAGENTA:
680 BackgroundControl = 45;
681 break;
682
683 case EFI_BROWN:
684 BackgroundControl = 43;
685 break;
686
687 default:
688
689 case EFI_LIGHTGRAY:
690 BackgroundControl = 47;
691 break;
692 }
693 //
694 // terminal emulator's control sequence to set attributes
695 //
696 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);
697 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));
698 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));
699 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));
700 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));
701
702 //
703 // save current column and row
704 // for future scrolling back use.
705 //
706 SavedColumn = This->Mode->CursorColumn;
707 SavedRow = This->Mode->CursorRow;
708
709 TerminalDevice->OutputEscChar = TRUE;
710 Status = This->OutputString (This, mSetAttributeString);
711 TerminalDevice->OutputEscChar = FALSE;
712
713 if (EFI_ERROR (Status)) {
714 return EFI_DEVICE_ERROR;
715 }
716 //
717 // scroll back to saved cursor position.
718 //
719 This->Mode->CursorColumn = SavedColumn;
720 This->Mode->CursorRow = SavedRow;
721
722 This->Mode->Attribute = (INT32) Attribute;
723
724 return EFI_SUCCESS;
725
726 }
727
728 EFI_STATUS
729 EFIAPI
730 TerminalConOutClearScreen (
731 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
732 )
733 /*++
734 Routine Description:
735
736 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
737 It clears the ANSI terminal's display to the
738 currently selected background color.
739
740
741 Arguments:
742
743 This
744 Indicates the calling context.
745
746 Returns:
747
748 EFI_SUCCESS
749 The operation completed successfully.
750
751 EFI_DEVICE_ERROR
752 The terminal screen cannot be cleared due to serial port error.
753
754 EFI_UNSUPPORTED
755 The terminal is not in a valid display mode.
756
757 --*/
758 {
759 EFI_STATUS Status;
760 TERMINAL_DEV *TerminalDevice;
761
762 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
763
764 //
765 // control sequence for clear screen request
766 //
767 TerminalDevice->OutputEscChar = TRUE;
768 Status = This->OutputString (This, mClearScreenString);
769 TerminalDevice->OutputEscChar = FALSE;
770
771 if (EFI_ERROR (Status)) {
772 return EFI_DEVICE_ERROR;
773 }
774
775 Status = This->SetCursorPosition (This, 0, 0);
776
777 return Status;
778 }
779
780 EFI_STATUS
781 EFIAPI
782 TerminalConOutSetCursorPosition (
783 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
784 IN UINTN Column,
785 IN UINTN Row
786 )
787 /*++
788 Routine Description:
789
790 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
791
792 Arguments:
793
794 This
795 Indicates the calling context.
796
797 Column
798 The row to set cursor to.
799
800 Row
801 The column to set cursor to.
802
803 Returns:
804
805 EFI_SUCCESS
806 The operation completed successfully.
807
808 EFI_DEVICE_ERROR
809 The request fails due to serial port error.
810
811 EFI_UNSUPPORTED
812 The terminal is not in a valid text mode, or the cursor position
813 is invalid for current mode.
814
815 --*/
816 {
817 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
818 UINTN MaxColumn;
819 UINTN MaxRow;
820 EFI_STATUS Status;
821 TERMINAL_DEV *TerminalDevice;
822
823 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
824
825 //
826 // get current mode
827 //
828 Mode = This->Mode;
829
830 //
831 // get geometry of current mode
832 //
833 Status = This->QueryMode (
834 This,
835 Mode->Mode,
836 &MaxColumn,
837 &MaxRow
838 );
839 if (EFI_ERROR (Status)) {
840 return EFI_UNSUPPORTED;
841 }
842
843 if (Column >= MaxColumn || Row >= MaxRow) {
844 return EFI_UNSUPPORTED;
845 }
846 //
847 // control sequence to move the cursor
848 //
849 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));
850 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));
851 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));
852 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));
853
854 TerminalDevice->OutputEscChar = TRUE;
855 Status = This->OutputString (This, mSetCursorPositionString);
856 TerminalDevice->OutputEscChar = FALSE;
857
858 if (EFI_ERROR (Status)) {
859 return EFI_DEVICE_ERROR;
860 }
861 //
862 // update current cursor position
863 // in the Mode data structure.
864 //
865 Mode->CursorColumn = (INT32) Column;
866 Mode->CursorRow = (INT32) Row;
867
868 return EFI_SUCCESS;
869 }
870
871 EFI_STATUS
872 EFIAPI
873 TerminalConOutEnableCursor (
874 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
875 IN BOOLEAN Visible
876 )
877 /*++
878 Routine Description:
879
880 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
881 In this driver, the cursor cannot be hidden.
882
883 Arguments:
884
885 This
886 Indicates the calling context.
887
888 Visible
889 If TRUE, the cursor is set to be visible,
890 If FALSE, the cursor is set to be invisible.
891
892 Returns:
893
894 EFI_SUCCESS
895 The request is valid.
896
897 EFI_UNSUPPORTED
898 The terminal does not support cursor hidden.
899
900 --*/
901 {
902 if (!Visible) {
903 return EFI_UNSUPPORTED;
904 }
905
906 return EFI_SUCCESS;
907 }
908
909 BOOLEAN
910 TerminalIsValidTextGraphics (
911 IN CHAR16 Graphic,
912 OUT CHAR8 *PcAnsi, OPTIONAL
913 OUT CHAR8 *Ascii OPTIONAL
914 )
915 /*++
916
917 Routine Description:
918
919 Detects if a Unicode char is for Box Drawing text graphics.
920
921 Arguments:
922
923 Graphic - Unicode char to test.
924
925 PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
926
927 Ascii - Optional pointer to return ASCII equivalent of Graphic.
928
929 Returns:
930
931 TRUE if Graphic is a supported Unicode Box Drawing character.
932
933 --*/
934 {
935 UNICODE_TO_CHAR *Table;
936
937 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
938 //
939 // Unicode drawing code charts are all in the 0x25xx range,
940 // arrows are 0x21xx
941 //
942 return FALSE;
943 }
944
945 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
946 if (Graphic == Table->Unicode) {
947 if (PcAnsi != NULL) {
948 *PcAnsi = Table->PcAnsi;
949 }
950
951 if (Ascii != NULL) {
952 *Ascii = Table->Ascii;
953 }
954
955 return TRUE;
956 }
957 }
958
959 return FALSE;
960 }
961
962 BOOLEAN
963 TerminalIsValidAscii (
964 IN CHAR16 Ascii
965 )
966 {
967 //
968 // valid ascii code lies in the extent of 0x20 ~ 0x7f
969 //
970 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
971 return TRUE;
972 }
973
974 return FALSE;
975 }
976
977 BOOLEAN
978 TerminalIsValidEfiCntlChar (
979 IN CHAR16 CharC
980 )
981 {
982 //
983 // only support four control characters.
984 //
985 if (CharC == CHAR_NULL ||
986 CharC == CHAR_BACKSPACE ||
987 CharC == CHAR_LINEFEED ||
988 CharC == CHAR_CARRIAGE_RETURN ||
989 CharC == CHAR_TAB
990 ) {
991 return TRUE;
992 }
993
994 return FALSE;
995 }