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