]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
daa40d894a77ccf731731c1b8fc04d729d85d9e2
[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 STATIC CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 };
82 STATIC CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };
83 STATIC CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 };
84 STATIC 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
93 If ExtendeVerification is TRUE, then perform dependent serial device reset,
94 and set display mode to mode 0.
95 If ExtendedVerification is FALSE, only set display mode to mode 0.
96
97 @param This Indicates the calling context.
98 @param ExtendedVerification Indicates that the driver may perform a more
99 exhaustive verification operation of the device
100 during reset.
101
102 @return EFI_SUCCESS The reset operation succeeds.
103 @return EFI_DEVICE_ERROR The terminal is not functioning correctly or the serial port reset fails.
104
105 **/
106 EFI_STATUS
107 EFIAPI
108 TerminalConOutReset (
109 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
110 IN BOOLEAN ExtendedVerification
111 )
112 {
113 EFI_STATUS Status;
114 TERMINAL_DEV *TerminalDevice;
115
116 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
117
118 //
119 // Perform a more exhaustive reset by resetting the serial port.
120 //
121 if (ExtendedVerification) {
122 //
123 // Report progress code here
124 //
125 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
126 EFI_PROGRESS_CODE,
127 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),
128 TerminalDevice->DevicePath
129 );
130
131 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
132 if (EFI_ERROR (Status)) {
133 //
134 // Report error code here
135 //
136 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
137 EFI_ERROR_CODE | EFI_ERROR_MINOR,
138 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),
139 TerminalDevice->DevicePath
140 );
141
142 return Status;
143 }
144 }
145
146 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));
147
148 Status = This->SetMode (This, 0);
149
150 return Status;
151 }
152
153
154 /**
155 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
156
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 @retval EFI_SUCCESS The string is output successfully.
165 @retval EFI_DEVICE_ERROR The serial port fails to send the string out.
166 @retval EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not
167 be rendered and are skipped.
168 @retval EFI_UNSUPPORTED If current display mode is out of range.
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
341 If one of the characters in the *Wstring is
342 neither valid Unicode drawing characters,
343 not ASCII code, then this function will return
344 EFI_UNSUPPORTED.
345
346 @param This Indicates the calling context.
347 @param WString The Null-terminated Unicode string to be tested.
348
349 @return EFI_SUCCESS The terminal is capable of rendering the output string.
350 @return EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.
351
352 **/
353 EFI_STATUS
354 EFIAPI
355 TerminalConOutTestString (
356 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
357 IN CHAR16 *WString
358 )
359 {
360 TERMINAL_DEV *TerminalDevice;
361 EFI_STATUS Status;
362
363 //
364 // get Terminal device data structure pointer.
365 //
366 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
367
368 switch (TerminalDevice->TerminalType) {
369
370 case PCANSITYPE:
371 case VT100TYPE:
372 case VT100PLUSTYPE:
373 Status = AnsiTestString (TerminalDevice, WString);
374 break;
375
376 case VTUTF8TYPE:
377 Status = VTUTF8TestString (TerminalDevice, WString);
378 break;
379
380 default:
381 Status = EFI_UNSUPPORTED;
382 break;
383 }
384
385 return Status;
386 }
387
388
389 /**
390 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
391
392 It returns information for an available text mode
393 that the terminal supports.
394 In this driver, we support text mode 80x25 (mode 0),
395 80x50 (mode 1), 100x31 (mode 2).
396
397 @param This Indicates the calling context.
398 @param ModeNumber The mode number to return information on.
399 @param Columns The returned columns of the requested mode.
400 @param Rows The returned rows of the requested mode.
401
402 @return EFI_SUCCESS The requested mode information is returned.
403 @return EFI_UNSUPPORTED The mode number is not valid.
404 @return EFI_DEVICE_ERROR
405
406 **/
407 EFI_STATUS
408 EFIAPI
409 TerminalConOutQueryMode (
410 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
411 IN UINTN ModeNumber,
412 OUT UINTN *Columns,
413 OUT UINTN *Rows
414 )
415 {
416 if (This->Mode->MaxMode > 3) {
417 return EFI_DEVICE_ERROR;
418 }
419
420 if (ModeNumber == 0) {
421 *Columns = MODE0_COLUMN_COUNT;
422 *Rows = MODE0_ROW_COUNT;
423 return EFI_SUCCESS;
424 } else if (ModeNumber == 1) {
425 *Columns = MODE1_COLUMN_COUNT;
426 *Rows = MODE1_ROW_COUNT;
427 return EFI_SUCCESS;
428 } else if (ModeNumber == 2) {
429 *Columns = MODE2_COLUMN_COUNT;
430 *Rows = MODE2_ROW_COUNT;
431 return EFI_SUCCESS;
432 }
433
434 return EFI_UNSUPPORTED;
435 }
436
437
438 /**
439 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
440
441 Set the terminal to a specified display mode.
442 In this driver, we only support mode 0.
443
444 @param This Indicates the calling context.
445 @param ModeNumber The text mode to set.
446
447 @return EFI_SUCCESS The requested text mode is set.
448 @return EFI_DEVICE_ERROR The requested text mode cannot be set
449 because of serial device error.
450 @return EFI_UNSUPPORTED The text mode number is not valid.
451
452 **/
453 EFI_STATUS
454 EFIAPI
455 TerminalConOutSetMode (
456 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
457 IN UINTN ModeNumber
458 )
459 {
460 EFI_STATUS Status;
461 TERMINAL_DEV *TerminalDevice;
462
463 //
464 // get Terminal device data structure pointer.
465 //
466 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
467
468 if (ModeNumber > 2) {
469 return EFI_UNSUPPORTED;
470 }
471
472 //
473 // Set the current mode
474 //
475 This->Mode->Mode = (INT32) ModeNumber;
476
477 This->ClearScreen (This);
478
479 TerminalDevice->OutputEscChar = TRUE;
480 Status = This->OutputString (This, mSetModeString);
481 TerminalDevice->OutputEscChar = FALSE;
482
483 if (EFI_ERROR (Status)) {
484 return EFI_DEVICE_ERROR;
485 }
486
487 This->Mode->Mode = (INT32) ModeNumber;
488
489 Status = This->ClearScreen (This);
490 if (EFI_ERROR (Status)) {
491 return EFI_DEVICE_ERROR;
492 }
493
494 return EFI_SUCCESS;
495
496 }
497
498
499 /**
500 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
501
502 @param This Indicates the calling context.
503 @param Attribute The attribute to set. Only bit0..6 are valid, all other bits
504 are undefined and must be zero.
505
506 @return EFI_SUCCESS The requested attribute is set.
507 @return EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
508 @return EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
509
510 **/
511 EFI_STATUS
512 EFIAPI
513 TerminalConOutSetAttribute (
514 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
515 IN UINTN Attribute
516 )
517 {
518 UINT8 ForegroundControl;
519 UINT8 BackgroundControl;
520 UINT8 BrightControl;
521 INT32 SavedColumn;
522 INT32 SavedRow;
523 EFI_STATUS Status;
524 TERMINAL_DEV *TerminalDevice;
525
526 SavedColumn = 0;
527 SavedRow = 0;
528
529 //
530 // get Terminal device data structure pointer.
531 //
532 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
533
534 //
535 // only the bit0..6 of the Attribute is valid
536 //
537 if ((Attribute | 0x7f) != 0x7f) {
538 return EFI_UNSUPPORTED;
539 }
540
541 //
542 // Skip outputting the command string for the same attribute
543 // It improves the terminal performance siginificantly
544 //
545 if (This->Mode->Attribute == (INT32) Attribute) {
546 return EFI_SUCCESS;
547 }
548
549 //
550 // convert Attribute value to terminal emulator
551 // understandable foreground color
552 //
553 switch (Attribute & 0x07) {
554
555 case EFI_BLACK:
556 ForegroundControl = 30;
557 break;
558
559 case EFI_BLUE:
560 ForegroundControl = 34;
561 break;
562
563 case EFI_GREEN:
564 ForegroundControl = 32;
565 break;
566
567 case EFI_CYAN:
568 ForegroundControl = 36;
569 break;
570
571 case EFI_RED:
572 ForegroundControl = 31;
573 break;
574
575 case EFI_MAGENTA:
576 ForegroundControl = 35;
577 break;
578
579 case EFI_BROWN:
580 ForegroundControl = 33;
581 break;
582
583 default:
584
585 case EFI_LIGHTGRAY:
586 ForegroundControl = 37;
587 break;
588
589 }
590 //
591 // bit4 of the Attribute indicates bright control
592 // of terminal emulator.
593 //
594 BrightControl = (UINT8) ((Attribute >> 3) & 1);
595
596 //
597 // convert Attribute value to terminal emulator
598 // understandable background color.
599 //
600 switch ((Attribute >> 4) & 0x07) {
601
602 case EFI_BLACK:
603 BackgroundControl = 40;
604 break;
605
606 case EFI_BLUE:
607 BackgroundControl = 44;
608 break;
609
610 case EFI_GREEN:
611 BackgroundControl = 42;
612 break;
613
614 case EFI_CYAN:
615 BackgroundControl = 46;
616 break;
617
618 case EFI_RED:
619 BackgroundControl = 41;
620 break;
621
622 case EFI_MAGENTA:
623 BackgroundControl = 45;
624 break;
625
626 case EFI_BROWN:
627 BackgroundControl = 43;
628 break;
629
630 default:
631
632 case EFI_LIGHTGRAY:
633 BackgroundControl = 47;
634 break;
635 }
636 //
637 // terminal emulator's control sequence to set attributes
638 //
639 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);
640 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));
641 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));
642 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));
643 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));
644
645 //
646 // save current column and row
647 // for future scrolling back use.
648 //
649 SavedColumn = This->Mode->CursorColumn;
650 SavedRow = This->Mode->CursorRow;
651
652 TerminalDevice->OutputEscChar = TRUE;
653 Status = This->OutputString (This, mSetAttributeString);
654 TerminalDevice->OutputEscChar = FALSE;
655
656 if (EFI_ERROR (Status)) {
657 return EFI_DEVICE_ERROR;
658 }
659 //
660 // scroll back to saved cursor position.
661 //
662 This->Mode->CursorColumn = SavedColumn;
663 This->Mode->CursorRow = SavedRow;
664
665 This->Mode->Attribute = (INT32) Attribute;
666
667 return EFI_SUCCESS;
668
669 }
670
671
672 /**
673 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
674 It clears the ANSI terminal's display to the
675 currently selected background color.
676
677 @param This Indicates the calling context.
678
679 @return EFI_SUCCESS The operation completed successfully.
680 @return EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
681 @return EFI_UNSUPPORTED The terminal is not in a valid display mode.
682
683 **/
684 EFI_STATUS
685 EFIAPI
686 TerminalConOutClearScreen (
687 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
688 )
689 {
690 EFI_STATUS Status;
691 TERMINAL_DEV *TerminalDevice;
692
693 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
694
695 //
696 // control sequence for clear screen request
697 //
698 TerminalDevice->OutputEscChar = TRUE;
699 Status = This->OutputString (This, mClearScreenString);
700 TerminalDevice->OutputEscChar = FALSE;
701
702 if (EFI_ERROR (Status)) {
703 return EFI_DEVICE_ERROR;
704 }
705
706 Status = This->SetCursorPosition (This, 0, 0);
707
708 return Status;
709 }
710
711
712 /**
713 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
714
715 @param This Indicates the calling context.
716 @param Column The row to set cursor to.
717 @param Row The column to set cursor to.
718
719 @return EFI_SUCCESS The operation completed successfully.
720 @return EFI_DEVICE_ERROR The request fails due to serial port error.
721 @return EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position
722 is invalid for current mode.
723
724 **/
725 EFI_STATUS
726 EFIAPI
727 TerminalConOutSetCursorPosition (
728 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
729 IN UINTN Column,
730 IN UINTN Row
731 )
732 {
733 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
734 UINTN MaxColumn;
735 UINTN MaxRow;
736 EFI_STATUS Status;
737 TERMINAL_DEV *TerminalDevice;
738
739 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
740
741 //
742 // get current mode
743 //
744 Mode = This->Mode;
745
746 //
747 // get geometry of current mode
748 //
749 Status = This->QueryMode (
750 This,
751 Mode->Mode,
752 &MaxColumn,
753 &MaxRow
754 );
755 if (EFI_ERROR (Status)) {
756 return EFI_UNSUPPORTED;
757 }
758
759 if (Column >= MaxColumn || Row >= MaxRow) {
760 return EFI_UNSUPPORTED;
761 }
762 //
763 // control sequence to move the cursor
764 //
765 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));
766 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));
767 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));
768 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));
769
770 TerminalDevice->OutputEscChar = TRUE;
771 Status = This->OutputString (This, mSetCursorPositionString);
772 TerminalDevice->OutputEscChar = FALSE;
773
774 if (EFI_ERROR (Status)) {
775 return EFI_DEVICE_ERROR;
776 }
777 //
778 // update current cursor position
779 // in the Mode data structure.
780 //
781 Mode->CursorColumn = (INT32) Column;
782 Mode->CursorRow = (INT32) Row;
783
784 return EFI_SUCCESS;
785 }
786
787
788 /**
789 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
790
791 In this driver, the cursor cannot be hidden.
792
793 @param This Indicates the calling context.
794 @param Visible If TRUE, the cursor is set to be visible,
795 If FALSE, the cursor is set to be invisible.
796
797 @return EFI_SUCCESS The request is valid.
798 @return EFI_UNSUPPORTED The terminal does not support cursor hidden.
799
800 **/
801 EFI_STATUS
802 EFIAPI
803 TerminalConOutEnableCursor (
804 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
805 IN BOOLEAN Visible
806 )
807 {
808 if (!Visible) {
809 return EFI_UNSUPPORTED;
810 }
811
812 return EFI_SUCCESS;
813 }
814
815
816 /**
817 Detects if a Unicode char is for Box Drawing text graphics.
818
819 @param Graphic Unicode char to test.
820 @param PcAnsi Optional pointer to return PCANSI equivalent of
821 Graphic.
822 @param Ascii Optional pointer to return ASCII equivalent of
823 Graphic.
824
825 @return TRUE If Graphic is a supported Unicode Box Drawing character.
826
827 **/
828 BOOLEAN
829 TerminalIsValidTextGraphics (
830 IN CHAR16 Graphic,
831 OUT CHAR8 *PcAnsi, OPTIONAL
832 OUT CHAR8 *Ascii OPTIONAL
833 )
834 {
835 UNICODE_TO_CHAR *Table;
836
837 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
838 //
839 // Unicode drawing code charts are all in the 0x25xx range,
840 // arrows are 0x21xx
841 //
842 return FALSE;
843 }
844
845 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
846 if (Graphic == Table->Unicode) {
847 if (PcAnsi != NULL) {
848 *PcAnsi = Table->PcAnsi;
849 }
850
851 if (Ascii != NULL) {
852 *Ascii = Table->Ascii;
853 }
854
855 return TRUE;
856 }
857 }
858
859 return FALSE;
860 }
861
862 /**
863 Detects if a valid ASCII char.
864
865 @param Ascii An ASCII character.
866
867 @retval TRUE If it is a valid ASCII character.
868 @retval FALSE If it is not a valid ASCII character.
869
870 **/
871 BOOLEAN
872 TerminalIsValidAscii (
873 IN CHAR16 Ascii
874 )
875 {
876 //
877 // valid ascii code lies in the extent of 0x20 ~ 0x7f
878 //
879 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
880 return TRUE;
881 }
882
883 return FALSE;
884 }
885
886 /**
887 Detects if a valid EFI control character.
888
889 @param CharC An input EFI Control character.
890
891 @retval TRUE If it is a valid EFI control character.
892 @retval FALSE If it is not a valid EFI control character.
893
894 **/
895 BOOLEAN
896 TerminalIsValidEfiCntlChar (
897 IN CHAR16 CharC
898 )
899 {
900 //
901 // only support four control characters.
902 //
903 if (CharC == CHAR_NULL ||
904 CharC == CHAR_BACKSPACE ||
905 CharC == CHAR_LINEFEED ||
906 CharC == CHAR_CARRIAGE_RETURN ||
907 CharC == CHAR_TAB
908 ) {
909 return TRUE;
910 }
911
912 return FALSE;
913 }