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