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