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