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