]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
Added some functions header.
[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 The reset operation succeeds.
102 @return EFI_DEVICE_ERROR The terminal is not functioning correctly or the serial port reset fails.
103
104 **/
105 EFI_STATUS
106 EFIAPI
107 TerminalConOutReset (
108 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
109 IN BOOLEAN ExtendedVerification
110 )
111 {
112 EFI_STATUS Status;
113 TERMINAL_DEV *TerminalDevice;
114
115 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
116
117 //
118 // Perform a more exhaustive reset by resetting the serial port.
119 //
120 if (ExtendedVerification) {
121 //
122 // Report progress code here
123 //
124 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
125 EFI_PROGRESS_CODE,
126 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),
127 TerminalDevice->DevicePath
128 );
129
130 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
131 if (EFI_ERROR (Status)) {
132 //
133 // Report error code here
134 //
135 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
136 EFI_ERROR_CODE | EFI_ERROR_MINOR,
137 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),
138 TerminalDevice->DevicePath
139 );
140
141 return Status;
142 }
143 }
144
145 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));
146
147 Status = This->SetMode (This, 0);
148
149 return Status;
150 }
151
152
153 /**
154 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().
155 The Unicode string will be converted to terminal expressible data stream
156 and send to terminal via serial port.
157
158 @param This Indicates the calling context.
159 @param WString The Null-terminated Unicode string to be displayed
160 on the terminal screen.
161
162 @retval EFI_SUCCESS The string is output successfully.
163 @retval EFI_DEVICE_ERROR The serial port fails to send the string out.
164 @retval EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not
165 be rendered and are skipped.
166 @retval EFI_UNSUPPORTED If current display mode is out of range.
167
168 **/
169 EFI_STATUS
170 EFIAPI
171 TerminalConOutOutputString (
172 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
173 IN CHAR16 *WString
174 )
175 {
176 TERMINAL_DEV *TerminalDevice;
177 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
178 UINTN MaxColumn;
179 UINTN MaxRow;
180 UINTN Length;
181 UTF8_CHAR Utf8Char;
182 CHAR8 GraphicChar;
183 CHAR8 AsciiChar;
184 EFI_STATUS Status;
185 UINT8 ValidBytes;
186 //
187 // flag used to indicate whether condition happens which will cause
188 // return EFI_WARN_UNKNOWN_GLYPH
189 //
190 BOOLEAN Warning;
191
192 ValidBytes = 0;
193 Warning = FALSE;
194
195 //
196 // get Terminal device data structure pointer.
197 //
198 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
199
200 //
201 // Get current display mode
202 //
203 Mode = This->Mode;
204
205 if (Mode->Mode > 2) {
206 return EFI_UNSUPPORTED;
207 }
208
209 This->QueryMode (
210 This,
211 Mode->Mode,
212 &MaxColumn,
213 &MaxRow
214 );
215
216 for (; *WString != CHAR_NULL; WString++) {
217
218 switch (TerminalDevice->TerminalType) {
219
220 case PCANSITYPE:
221 case VT100TYPE:
222 case VT100PLUSTYPE:
223
224 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
225 //
226 // If it's not a graphic character convert Unicode to ASCII.
227 //
228 GraphicChar = (CHAR8) *WString;
229
230 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {
231 //
232 // when this driver use the OutputString to output control string,
233 // TerminalDevice->OutputEscChar is set to let the Esc char
234 // to be output to the terminal emulation software.
235 //
236 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {
237 GraphicChar = 27;
238 } else {
239 GraphicChar = '?';
240 Warning = TRUE;
241 }
242 }
243
244 AsciiChar = GraphicChar;
245
246 }
247
248 if (TerminalDevice->TerminalType != PCANSITYPE) {
249 GraphicChar = AsciiChar;
250 }
251
252 Length = 1;
253
254 Status = TerminalDevice->SerialIo->Write (
255 TerminalDevice->SerialIo,
256 &Length,
257 &GraphicChar
258 );
259
260 if (EFI_ERROR (Status)) {
261 goto OutputError;
262 }
263
264 break;
265
266 case VTUTF8TYPE:
267 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);
268 Length = ValidBytes;
269 Status = TerminalDevice->SerialIo->Write (
270 TerminalDevice->SerialIo,
271 &Length,
272 (UINT8 *) &Utf8Char
273 );
274 if (EFI_ERROR (Status)) {
275 goto OutputError;
276 }
277 break;
278 }
279 //
280 // Update cursor position.
281 //
282 switch (*WString) {
283
284 case CHAR_BACKSPACE:
285 if (Mode->CursorColumn > 0) {
286 Mode->CursorColumn--;
287 }
288 break;
289
290 case CHAR_LINEFEED:
291 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
292 Mode->CursorRow++;
293 }
294 break;
295
296 case CHAR_CARRIAGE_RETURN:
297 Mode->CursorColumn = 0;
298 break;
299
300 default:
301 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {
302
303 Mode->CursorColumn++;
304
305 } else {
306
307 Mode->CursorColumn = 0;
308 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
309 Mode->CursorRow++;
310 }
311
312 }
313 break;
314
315 };
316
317 }
318
319 if (Warning) {
320 return EFI_WARN_UNKNOWN_GLYPH;
321 }
322
323 return EFI_SUCCESS;
324
325 OutputError:
326 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
327 EFI_ERROR_CODE | EFI_ERROR_MINOR,
328 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError),
329 TerminalDevice->DevicePath
330 );
331
332 return EFI_DEVICE_ERROR;
333 }
334
335
336 /**
337 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().
338 If one of the characters in the *Wstring is
339 neither valid Unicode drawing characters,
340 not ASCII code, then this function will return
341 EFI_UNSUPPORTED.
342
343 @param This Indicates the calling context.
344 @param WString The Null-terminated Unicode string to be tested.
345
346 @return EFI_SUCCESS The terminal is capable of rendering the output string.
347 @return EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.
348
349 **/
350 EFI_STATUS
351 EFIAPI
352 TerminalConOutTestString (
353 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
354 IN CHAR16 *WString
355 )
356 {
357 TERMINAL_DEV *TerminalDevice;
358 EFI_STATUS Status;
359
360 //
361 // get Terminal device data structure pointer.
362 //
363 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
364
365 switch (TerminalDevice->TerminalType) {
366
367 case PCANSITYPE:
368 case VT100TYPE:
369 case VT100PLUSTYPE:
370 Status = AnsiTestString (TerminalDevice, WString);
371 break;
372
373 case VTUTF8TYPE:
374 Status = VTUTF8TestString (TerminalDevice, WString);
375 break;
376
377 default:
378 Status = EFI_UNSUPPORTED;
379 break;
380 }
381
382 return Status;
383 }
384
385
386 /**
387 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().
388 It returns information for an available text mode
389 that the terminal supports.
390 In this driver, we support text mode 80x25 (mode 0),
391 80x50 (mode 1), 100x31 (mode 2).
392
393 @param This Indicates the calling context.
394 @param ModeNumber The mode number to return information on.
395 @param Columns The returned columns of the requested mode.
396 @param Rows The returned rows of the requested mode.
397
398 @return EFI_SUCCESS The requested mode information is returned.
399 @return EFI_UNSUPPORTED The mode number is not valid.
400 @return EFI_DEVICE_ERROR
401
402 **/
403 EFI_STATUS
404 EFIAPI
405 TerminalConOutQueryMode (
406 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
407 IN UINTN ModeNumber,
408 OUT UINTN *Columns,
409 OUT UINTN *Rows
410 )
411 {
412 if (This->Mode->MaxMode > 3) {
413 return EFI_DEVICE_ERROR;
414 }
415
416 if (ModeNumber == 0) {
417 *Columns = MODE0_COLUMN_COUNT;
418 *Rows = MODE0_ROW_COUNT;
419 return EFI_SUCCESS;
420 } else if (ModeNumber == 1) {
421 *Columns = MODE1_COLUMN_COUNT;
422 *Rows = MODE1_ROW_COUNT;
423 return EFI_SUCCESS;
424 } else if (ModeNumber == 2) {
425 *Columns = MODE2_COLUMN_COUNT;
426 *Rows = MODE2_ROW_COUNT;
427 return EFI_SUCCESS;
428 }
429
430 return EFI_UNSUPPORTED;
431 }
432
433
434 /**
435 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
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 @return EFI_SUCCESS The requested text mode is set.
443 @return EFI_DEVICE_ERROR The requested text mode cannot be set
444 because of serial device error.
445 @return EFI_UNSUPPORTED The text mode number is not valid.
446
447 **/
448 EFI_STATUS
449 EFIAPI
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 > 2) {
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 @return EFI_SUCCESS The requested attribute is set.
502 @return EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
503 @return EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
504
505 **/
506 EFI_STATUS
507 EFIAPI
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 siginificantly
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 @return EFI_SUCCESS The operation completed successfully.
675 @return EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
676 @return EFI_UNSUPPORTED The terminal is not in a valid display mode.
677
678 **/
679 EFI_STATUS
680 EFIAPI
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 @return EFI_SUCCESS The operation completed successfully.
715 @return EFI_DEVICE_ERROR The request fails due to serial port error.
716 @return 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
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 In this driver, the cursor cannot be hidden.
786
787 @param This Indicates the calling context.
788 @param Visible If TRUE, the cursor is set to be visible,
789 If FALSE, the cursor is set to be invisible.
790
791 @return EFI_SUCCESS The request is valid.
792 @return EFI_UNSUPPORTED The terminal does not support cursor hidden.
793
794 **/
795 EFI_STATUS
796 EFIAPI
797 TerminalConOutEnableCursor (
798 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
799 IN BOOLEAN Visible
800 )
801 {
802 if (!Visible) {
803 return EFI_UNSUPPORTED;
804 }
805
806 return EFI_SUCCESS;
807 }
808
809
810 /**
811 Detects if a Unicode char is for Box Drawing text graphics.
812
813 @param Graphic Unicode char to test.
814 @param PcAnsi Optional pointer to return PCANSI equivalent of
815 Graphic.
816 @param Ascii Optional pointer to return ASCII equivalent of
817 Graphic.
818
819 @return TRUE If Graphic is a supported Unicode Box Drawing character.
820
821 **/
822 BOOLEAN
823 TerminalIsValidTextGraphics (
824 IN CHAR16 Graphic,
825 OUT CHAR8 *PcAnsi, OPTIONAL
826 OUT CHAR8 *Ascii OPTIONAL
827 )
828 {
829 UNICODE_TO_CHAR *Table;
830
831 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
832 //
833 // Unicode drawing code charts are all in the 0x25xx range,
834 // arrows are 0x21xx
835 //
836 return FALSE;
837 }
838
839 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
840 if (Graphic == Table->Unicode) {
841 if (PcAnsi != NULL) {
842 *PcAnsi = Table->PcAnsi;
843 }
844
845 if (Ascii != NULL) {
846 *Ascii = Table->Ascii;
847 }
848
849 return TRUE;
850 }
851 }
852
853 return FALSE;
854 }
855
856 /**
857 Detects if a valid ASCII char.
858
859 @param Ascii An ASCII character.
860
861 @retval TRUE If it is a valid ASCII character.
862 @retval FALSE If it is not a valid ASCII character.
863
864 **/
865 BOOLEAN
866 TerminalIsValidAscii (
867 IN CHAR16 Ascii
868 )
869 {
870 //
871 // valid ascii code lies in the extent of 0x20 ~ 0x7f
872 //
873 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
874 return TRUE;
875 }
876
877 return FALSE;
878 }
879
880 /**
881 Detects if a valid EFI control character.
882
883 @param CharC An input EFI Control character.
884
885 @retval TRUE If it is a valid EFI control character.
886 @retval FALSE If it is not a valid EFI control character.
887
888 **/
889 BOOLEAN
890 TerminalIsValidEfiCntlChar (
891 IN CHAR16 CharC
892 )
893 {
894 //
895 // only support four control characters.
896 //
897 if (CharC == CHAR_NULL ||
898 CharC == CHAR_BACKSPACE ||
899 CharC == CHAR_LINEFEED ||
900 CharC == CHAR_CARRIAGE_RETURN ||
901 CharC == CHAR_TAB
902 ) {
903 return TRUE;
904 }
905
906 return FALSE;
907 }