]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
Clean codes per ECC for TerminalDxe module.
[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
90 /**
91 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().
92 If ExtendeVerification is TRUE, then perform dependent serial device reset,
93 and set display mode to mode 0.
94 If ExtendedVerification is FALSE, only set display mode to mode 0.
95
96 @param This Indicates the calling context.
97 @param ExtendedVerification Indicates that the driver may perform a more
98 exhaustive verification operation of the device
99 during reset.
100
101 @return EFI_SUCCESS
102 @return The reset operation succeeds.
103 @return EFI_DEVICE_ERROR
104 @return The terminal is not functioning correctly or the serial port reset fails.
105
106 **/
107 EFI_STATUS
108 EFIAPI
109 TerminalConOutReset (
110 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
111 IN BOOLEAN ExtendedVerification
112 )
113 {
114 EFI_STATUS Status;
115 TERMINAL_DEV *TerminalDevice;
116
117 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
118
119 //
120 // Perform a more exhaustive reset by resetting the serial port.
121 //
122 if (ExtendedVerification) {
123 //
124 // Report progress code here
125 //
126 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
127 EFI_PROGRESS_CODE,
128 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),
129 TerminalDevice->DevicePath
130 );
131
132 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
133 if (EFI_ERROR (Status)) {
134 //
135 // Report error code here
136 //
137 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
138 EFI_ERROR_CODE | EFI_ERROR_MINOR,
139 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),
140 TerminalDevice->DevicePath
141 );
142
143 return Status;
144 }
145 }
146
147 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));
148
149 Status = This->SetMode (This, 0);
150
151 return Status;
152 }
153
154
155 /**
156 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
157 The Unicode string will be converted to terminal expressible data stream
158 and send to terminal via serial port.
159
160 @param This Indicates the calling context.
161 @param WString The Null-terminated Unicode string to be displayed
162 on the terminal screen.
163
164 @return EFI_SUCCESS The string is output successfully.
165 @return EFI_DEVICE_ERROR The serial port fails to send the string out.
166 @return EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not
167 be rendered and are skipped.
168 @return EFI_UNSUPPORTED
169
170 **/
171 EFI_STATUS
172 EFIAPI
173 TerminalConOutOutputString (
174 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
175 IN CHAR16 *WString
176 )
177 {
178 TERMINAL_DEV *TerminalDevice;
179 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
180 UINTN MaxColumn;
181 UINTN MaxRow;
182 UINTN Length;
183 UTF8_CHAR Utf8Char;
184 CHAR8 GraphicChar;
185 CHAR8 AsciiChar;
186 EFI_STATUS Status;
187 UINT8 ValidBytes;
188 //
189 // flag used to indicate whether condition happens which will cause
190 // return EFI_WARN_UNKNOWN_GLYPH
191 //
192 BOOLEAN Warning;
193
194 ValidBytes = 0;
195 Warning = FALSE;
196
197 //
198 // get Terminal device data structure pointer.
199 //
200 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
201
202 //
203 // Get current display mode
204 //
205 Mode = This->Mode;
206
207 if (Mode->Mode > 2) {
208 return EFI_UNSUPPORTED;
209 }
210
211 This->QueryMode (
212 This,
213 Mode->Mode,
214 &MaxColumn,
215 &MaxRow
216 );
217
218 for (; *WString != CHAR_NULL; WString++) {
219
220 switch (TerminalDevice->TerminalType) {
221
222 case PCANSITYPE:
223 case VT100TYPE:
224 case VT100PLUSTYPE:
225
226 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
227 //
228 // If it's not a graphic character convert Unicode to ASCII.
229 //
230 GraphicChar = (CHAR8) *WString;
231
232 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {
233 //
234 // when this driver use the OutputString to output control string,
235 // TerminalDevice->OutputEscChar is set to let the Esc char
236 // to be output to the terminal emulation software.
237 //
238 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {
239 GraphicChar = 27;
240 } else {
241 GraphicChar = '?';
242 Warning = TRUE;
243 }
244 }
245
246 AsciiChar = GraphicChar;
247
248 }
249
250 if (TerminalDevice->TerminalType != PCANSITYPE) {
251 GraphicChar = AsciiChar;
252 }
253
254 Length = 1;
255
256 Status = TerminalDevice->SerialIo->Write (
257 TerminalDevice->SerialIo,
258 &Length,
259 &GraphicChar
260 );
261
262 if (EFI_ERROR (Status)) {
263 goto OutputError;
264 }
265
266 break;
267
268 case VTUTF8TYPE:
269 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);
270 Length = ValidBytes;
271 Status = TerminalDevice->SerialIo->Write (
272 TerminalDevice->SerialIo,
273 &Length,
274 (UINT8 *) &Utf8Char
275 );
276 if (EFI_ERROR (Status)) {
277 goto OutputError;
278 }
279 break;
280 }
281 //
282 // Update cursor position.
283 //
284 switch (*WString) {
285
286 case CHAR_BACKSPACE:
287 if (Mode->CursorColumn > 0) {
288 Mode->CursorColumn--;
289 }
290 break;
291
292 case CHAR_LINEFEED:
293 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
294 Mode->CursorRow++;
295 }
296 break;
297
298 case CHAR_CARRIAGE_RETURN:
299 Mode->CursorColumn = 0;
300 break;
301
302 default:
303 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {
304
305 Mode->CursorColumn++;
306
307 } else {
308
309 Mode->CursorColumn = 0;
310 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
311 Mode->CursorRow++;
312 }
313
314 }
315 break;
316
317 };
318
319 }
320
321 if (Warning) {
322 return EFI_WARN_UNKNOWN_GLYPH;
323 }
324
325 return EFI_SUCCESS;
326
327 OutputError:
328 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
329 EFI_ERROR_CODE | EFI_ERROR_MINOR,
330 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError),
331 TerminalDevice->DevicePath
332 );
333
334 return EFI_DEVICE_ERROR;
335 }
336
337
338 /**
339 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().
340 If one of the characters in the *Wstring is
341 neither valid Unicode drawing characters,
342 not ASCII code, then this function will return
343 EFI_UNSUPPORTED.
344
345 @param This Indicates the calling context.
346 @param WString The Null-terminated Unicode string to be tested.
347
348 @return EFI_SUCCESS The terminal is capable of rendering the output string.
349 @return EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.
350
351 **/
352 EFI_STATUS
353 EFIAPI
354 TerminalConOutTestString (
355 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
356 IN CHAR16 *WString
357 )
358 {
359 TERMINAL_DEV *TerminalDevice;
360 EFI_STATUS Status;
361
362 //
363 // get Terminal device data structure pointer.
364 //
365 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
366
367 switch (TerminalDevice->TerminalType) {
368
369 case PCANSITYPE:
370 case VT100TYPE:
371 case VT100PLUSTYPE:
372 Status = AnsiTestString (TerminalDevice, WString);
373 break;
374
375 case VTUTF8TYPE:
376 Status = VTUTF8TestString (TerminalDevice, WString);
377 break;
378
379 default:
380 Status = EFI_UNSUPPORTED;
381 break;
382 }
383
384 return Status;
385 }
386
387
388 /**
389 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
390 It returns information for an available text mode
391 that the terminal supports.
392 In this driver, we support text mode 80x25 (mode 0),
393 80x50 (mode 1), 100x31 (mode 2).
394
395 @param This Indicates the calling context.
396 @param ModeNumber The mode number to return information on.
397 @param Columns The returned columns of the requested mode.
398 @param Rows The returned rows of the requested mode.
399
400 @return EFI_SUCCESS The requested mode information is returned.
401 @return EFI_UNSUPPORTED The mode number is not valid.
402 @return EFI_DEVICE_ERROR
403
404 **/
405 EFI_STATUS
406 EFIAPI
407 TerminalConOutQueryMode (
408 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
409 IN UINTN ModeNumber,
410 OUT UINTN *Columns,
411 OUT UINTN *Rows
412 )
413 {
414 if (This->Mode->MaxMode > 3) {
415 return EFI_DEVICE_ERROR;
416 }
417
418 if (ModeNumber == 0) {
419 *Columns = MODE0_COLUMN_COUNT;
420 *Rows = MODE0_ROW_COUNT;
421 return EFI_SUCCESS;
422 } else if (ModeNumber == 1) {
423 *Columns = MODE1_COLUMN_COUNT;
424 *Rows = MODE1_ROW_COUNT;
425 return EFI_SUCCESS;
426 } else if (ModeNumber == 2) {
427 *Columns = MODE2_COLUMN_COUNT;
428 *Rows = MODE2_ROW_COUNT;
429 return EFI_SUCCESS;
430 }
431
432 return EFI_UNSUPPORTED;
433 }
434
435
436 /**
437 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
438 Set the terminal to a specified display mode.
439 In this driver, we only support mode 0.
440
441 @param This Indicates the calling context.
442 @param ModeNumber The text mode to set.
443
444 @return EFI_SUCCESS The requested text mode is set.
445 @return EFI_DEVICE_ERROR The requested text mode cannot be set
446 because of serial device error.
447 @return EFI_UNSUPPORTED The text mode number is not valid.
448
449 **/
450 EFI_STATUS
451 EFIAPI
452 TerminalConOutSetMode (
453 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
454 IN UINTN ModeNumber
455 )
456 {
457 EFI_STATUS Status;
458 TERMINAL_DEV *TerminalDevice;
459
460 //
461 // get Terminal device data structure pointer.
462 //
463 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
464
465 if (ModeNumber > 2) {
466 return EFI_UNSUPPORTED;
467 }
468
469 //
470 // Set the current mode
471 //
472 This->Mode->Mode = (INT32) ModeNumber;
473
474 This->ClearScreen (This);
475
476 TerminalDevice->OutputEscChar = TRUE;
477 Status = This->OutputString (This, mSetModeString);
478 TerminalDevice->OutputEscChar = FALSE;
479
480 if (EFI_ERROR (Status)) {
481 return EFI_DEVICE_ERROR;
482 }
483
484 This->Mode->Mode = (INT32) ModeNumber;
485
486 Status = This->ClearScreen (This);
487 if (EFI_ERROR (Status)) {
488 return EFI_DEVICE_ERROR;
489 }
490
491 return EFI_SUCCESS;
492
493 }
494
495
496 /**
497 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
498
499 @param This Indicates the calling context.
500 @param Attribute The attribute to set. Only bit0..6 are valid, all other bits
501 are undefined and must be zero.
502
503 @return EFI_SUCCESS The requested attribute is set.
504 @return EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
505 @return EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
506
507 **/
508 EFI_STATUS
509 EFIAPI
510 TerminalConOutSetAttribute (
511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
512 IN UINTN Attribute
513 )
514 {
515 UINT8 ForegroundControl;
516 UINT8 BackgroundControl;
517 UINT8 BrightControl;
518 INT32 SavedColumn;
519 INT32 SavedRow;
520 EFI_STATUS Status;
521 TERMINAL_DEV *TerminalDevice;
522
523 SavedColumn = 0;
524 SavedRow = 0;
525
526 //
527 // get Terminal device data structure pointer.
528 //
529 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
530
531 //
532 // only the bit0..6 of the Attribute is valid
533 //
534 if ((Attribute | 0x7f) != 0x7f) {
535 return EFI_UNSUPPORTED;
536 }
537
538 //
539 // Skip outputting the command string for the same attribute
540 // It improves the terminal performance siginificantly
541 //
542 if (This->Mode->Attribute == (INT32) Attribute) {
543 return EFI_SUCCESS;
544 }
545
546 //
547 // convert Attribute value to terminal emulator
548 // understandable foreground color
549 //
550 switch (Attribute & 0x07) {
551
552 case EFI_BLACK:
553 ForegroundControl = 30;
554 break;
555
556 case EFI_BLUE:
557 ForegroundControl = 34;
558 break;
559
560 case EFI_GREEN:
561 ForegroundControl = 32;
562 break;
563
564 case EFI_CYAN:
565 ForegroundControl = 36;
566 break;
567
568 case EFI_RED:
569 ForegroundControl = 31;
570 break;
571
572 case EFI_MAGENTA:
573 ForegroundControl = 35;
574 break;
575
576 case EFI_BROWN:
577 ForegroundControl = 33;
578 break;
579
580 default:
581
582 case EFI_LIGHTGRAY:
583 ForegroundControl = 37;
584 break;
585
586 }
587 //
588 // bit4 of the Attribute indicates bright control
589 // of terminal emulator.
590 //
591 BrightControl = (UINT8) ((Attribute >> 3) & 1);
592
593 //
594 // convert Attribute value to terminal emulator
595 // understandable background color.
596 //
597 switch ((Attribute >> 4) & 0x07) {
598
599 case EFI_BLACK:
600 BackgroundControl = 40;
601 break;
602
603 case EFI_BLUE:
604 BackgroundControl = 44;
605 break;
606
607 case EFI_GREEN:
608 BackgroundControl = 42;
609 break;
610
611 case EFI_CYAN:
612 BackgroundControl = 46;
613 break;
614
615 case EFI_RED:
616 BackgroundControl = 41;
617 break;
618
619 case EFI_MAGENTA:
620 BackgroundControl = 45;
621 break;
622
623 case EFI_BROWN:
624 BackgroundControl = 43;
625 break;
626
627 default:
628
629 case EFI_LIGHTGRAY:
630 BackgroundControl = 47;
631 break;
632 }
633 //
634 // terminal emulator's control sequence to set attributes
635 //
636 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);
637 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));
638 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));
639 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));
640 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));
641
642 //
643 // save current column and row
644 // for future scrolling back use.
645 //
646 SavedColumn = This->Mode->CursorColumn;
647 SavedRow = This->Mode->CursorRow;
648
649 TerminalDevice->OutputEscChar = TRUE;
650 Status = This->OutputString (This, mSetAttributeString);
651 TerminalDevice->OutputEscChar = FALSE;
652
653 if (EFI_ERROR (Status)) {
654 return EFI_DEVICE_ERROR;
655 }
656 //
657 // scroll back to saved cursor position.
658 //
659 This->Mode->CursorColumn = SavedColumn;
660 This->Mode->CursorRow = SavedRow;
661
662 This->Mode->Attribute = (INT32) Attribute;
663
664 return EFI_SUCCESS;
665
666 }
667
668
669 /**
670 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
671 It clears the ANSI terminal's display to the
672 currently selected background color.
673
674 @param This Indicates the calling context.
675
676 @return EFI_SUCCESS The operation completed successfully.
677 @return EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
678 @return EFI_UNSUPPORTED The terminal is not in a valid display mode.
679
680 **/
681 EFI_STATUS
682 EFIAPI
683 TerminalConOutClearScreen (
684 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
685 )
686 {
687 EFI_STATUS Status;
688 TERMINAL_DEV *TerminalDevice;
689
690 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
691
692 //
693 // control sequence for clear screen request
694 //
695 TerminalDevice->OutputEscChar = TRUE;
696 Status = This->OutputString (This, mClearScreenString);
697 TerminalDevice->OutputEscChar = FALSE;
698
699 if (EFI_ERROR (Status)) {
700 return EFI_DEVICE_ERROR;
701 }
702
703 Status = This->SetCursorPosition (This, 0, 0);
704
705 return Status;
706 }
707
708
709 /**
710 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
711
712 @param This Indicates the calling context.
713 @param Column The row to set cursor to.
714 @param Row The column to set cursor to.
715
716 @return EFI_SUCCESS The operation completed successfully.
717 @return EFI_DEVICE_ERROR The request fails due to serial port error.
718 @return EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position
719 is invalid for current mode.
720
721 **/
722 EFI_STATUS
723 EFIAPI
724 TerminalConOutSetCursorPosition (
725 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
726 IN UINTN Column,
727 IN UINTN Row
728 )
729 {
730 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
731 UINTN MaxColumn;
732 UINTN MaxRow;
733 EFI_STATUS Status;
734 TERMINAL_DEV *TerminalDevice;
735
736 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
737
738 //
739 // get current mode
740 //
741 Mode = This->Mode;
742
743 //
744 // get geometry of current mode
745 //
746 Status = This->QueryMode (
747 This,
748 Mode->Mode,
749 &MaxColumn,
750 &MaxRow
751 );
752 if (EFI_ERROR (Status)) {
753 return EFI_UNSUPPORTED;
754 }
755
756 if (Column >= MaxColumn || Row >= MaxRow) {
757 return EFI_UNSUPPORTED;
758 }
759 //
760 // control sequence to move the cursor
761 //
762 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));
763 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));
764 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));
765 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));
766
767 TerminalDevice->OutputEscChar = TRUE;
768 Status = This->OutputString (This, mSetCursorPositionString);
769 TerminalDevice->OutputEscChar = FALSE;
770
771 if (EFI_ERROR (Status)) {
772 return EFI_DEVICE_ERROR;
773 }
774 //
775 // update current cursor position
776 // in the Mode data structure.
777 //
778 Mode->CursorColumn = (INT32) Column;
779 Mode->CursorRow = (INT32) Row;
780
781 return EFI_SUCCESS;
782 }
783
784
785 /**
786 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
787 In this driver, the cursor cannot be hidden.
788
789 @param This Indicates the calling context.
790 @param Visible If TRUE, the cursor is set to be visible,
791 If FALSE, the cursor is set to be invisible.
792
793 @return EFI_SUCCESS The request is valid.
794 @return EFI_UNSUPPORTED The terminal does not support cursor hidden.
795
796 **/
797 EFI_STATUS
798 EFIAPI
799 TerminalConOutEnableCursor (
800 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
801 IN BOOLEAN Visible
802 )
803 {
804 if (!Visible) {
805 return EFI_UNSUPPORTED;
806 }
807
808 return EFI_SUCCESS;
809 }
810
811
812 /**
813 Detects if a Unicode char is for Box Drawing text graphics.
814
815 @param Graphic Unicode char to test.
816 @param PcAnsi Optional pointer to return PCANSI equivalent of
817 Graphic.
818 @param Ascii Optional pointer to return ASCII equivalent of
819 Graphic.
820
821 @return TRUE If Graphic is a supported Unicode Box Drawing character.
822
823 **/
824 BOOLEAN
825 TerminalIsValidTextGraphics (
826 IN CHAR16 Graphic,
827 OUT CHAR8 *PcAnsi, OPTIONAL
828 OUT CHAR8 *Ascii OPTIONAL
829 )
830 {
831 UNICODE_TO_CHAR *Table;
832
833 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
834 //
835 // Unicode drawing code charts are all in the 0x25xx range,
836 // arrows are 0x21xx
837 //
838 return FALSE;
839 }
840
841 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
842 if (Graphic == Table->Unicode) {
843 if (PcAnsi != NULL) {
844 *PcAnsi = Table->PcAnsi;
845 }
846
847 if (Ascii != NULL) {
848 *Ascii = Table->Ascii;
849 }
850
851 return TRUE;
852 }
853 }
854
855 return FALSE;
856 }
857
858 BOOLEAN
859 TerminalIsValidAscii (
860 IN CHAR16 Ascii
861 )
862 {
863 //
864 // valid ascii code lies in the extent of 0x20 ~ 0x7f
865 //
866 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
867 return TRUE;
868 }
869
870 return FALSE;
871 }
872
873 BOOLEAN
874 TerminalIsValidEfiCntlChar (
875 IN CHAR16 CharC
876 )
877 {
878 //
879 // only support four control characters.
880 //
881 if (CharC == CHAR_NULL ||
882 CharC == CHAR_BACKSPACE ||
883 CharC == CHAR_LINEFEED ||
884 CharC == CHAR_CARRIAGE_RETURN ||
885 CharC == CHAR_TAB
886 ) {
887 return TRUE;
888 }
889
890 return FALSE;
891 }