]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
MdeModulePkg Terminal: Add text mode for PcdConOutColumn/Row
[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 >= TERMINAL_MAX_MODE) {
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 In this driver, we support text mode 80x25 (mode 0),
396 80x50 (mode 1), 100x31 (mode 2).
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 @retval EFI_DEVICE_ERROR
406
407 **/
408 EFI_STATUS
409 EFIAPI
410 TerminalConOutQueryMode (
411 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
412 IN UINTN ModeNumber,
413 OUT UINTN *Columns,
414 OUT UINTN *Rows
415 )
416 {
417 if (This->Mode->MaxMode > TERMINAL_MAX_MODE) {
418 return EFI_DEVICE_ERROR;
419 }
420
421 if (ModeNumber == 0) {
422 *Columns = MODE0_COLUMN_COUNT;
423 *Rows = MODE0_ROW_COUNT;
424 return EFI_SUCCESS;
425 } else if (ModeNumber == 1) {
426 *Columns = MODE1_COLUMN_COUNT;
427 *Rows = MODE1_ROW_COUNT;
428 return EFI_SUCCESS;
429 } else if (ModeNumber == 2) {
430 *Columns = MODE2_COLUMN_COUNT;
431 *Rows = MODE2_ROW_COUNT;
432 return EFI_SUCCESS;
433 } else if (ModeNumber == 3) {
434 *Columns = (UINTN) PcdGet32 (PcdConOutColumn);
435 if (*Columns == 0) {
436 *Columns = MODE0_COLUMN_COUNT;
437 }
438 *Rows = (UINTN) PcdGet32 (PcdConOutRow);
439 if (*Rows == 0) {
440 *Rows = MODE0_ROW_COUNT;
441 }
442 return EFI_SUCCESS;
443 }
444
445 return EFI_UNSUPPORTED;
446 }
447
448
449 /**
450 Implements EFI_SIMPLE_TEXT_OUT.SetMode().
451
452 Set the terminal to a specified display mode.
453 In this driver, we only support mode 0.
454
455 @param This Indicates the calling context.
456 @param ModeNumber The text mode to set.
457
458 @retval EFI_SUCCESS The requested text mode is set.
459 @retval EFI_DEVICE_ERROR The requested text mode cannot be set
460 because of serial device error.
461 @retval EFI_UNSUPPORTED The text mode number is not valid.
462
463 **/
464 EFI_STATUS
465 EFIAPI
466 TerminalConOutSetMode (
467 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
468 IN UINTN ModeNumber
469 )
470 {
471 EFI_STATUS Status;
472 TERMINAL_DEV *TerminalDevice;
473
474 //
475 // get Terminal device data structure pointer.
476 //
477 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
478
479 if (ModeNumber >= TERMINAL_MAX_MODE) {
480 return EFI_UNSUPPORTED;
481 }
482
483 //
484 // Set the current mode
485 //
486 This->Mode->Mode = (INT32) ModeNumber;
487
488 This->ClearScreen (This);
489
490 TerminalDevice->OutputEscChar = TRUE;
491 Status = This->OutputString (This, mSetModeString);
492 TerminalDevice->OutputEscChar = FALSE;
493
494 if (EFI_ERROR (Status)) {
495 return EFI_DEVICE_ERROR;
496 }
497
498 This->Mode->Mode = (INT32) ModeNumber;
499
500 Status = This->ClearScreen (This);
501 if (EFI_ERROR (Status)) {
502 return EFI_DEVICE_ERROR;
503 }
504
505 return EFI_SUCCESS;
506
507 }
508
509
510 /**
511 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().
512
513 @param This Indicates the calling context.
514 @param Attribute The attribute to set. Only bit0..6 are valid, all other bits
515 are undefined and must be zero.
516
517 @retval EFI_SUCCESS The requested attribute is set.
518 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.
519 @retval EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.
520
521 **/
522 EFI_STATUS
523 EFIAPI
524 TerminalConOutSetAttribute (
525 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
526 IN UINTN Attribute
527 )
528 {
529 UINT8 ForegroundControl;
530 UINT8 BackgroundControl;
531 UINT8 BrightControl;
532 INT32 SavedColumn;
533 INT32 SavedRow;
534 EFI_STATUS Status;
535 TERMINAL_DEV *TerminalDevice;
536
537 SavedColumn = 0;
538 SavedRow = 0;
539
540 //
541 // get Terminal device data structure pointer.
542 //
543 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
544
545 //
546 // only the bit0..6 of the Attribute is valid
547 //
548 if ((Attribute | 0x7f) != 0x7f) {
549 return EFI_UNSUPPORTED;
550 }
551
552 //
553 // Skip outputting the command string for the same attribute
554 // It improves the terminal performance significantly
555 //
556 if (This->Mode->Attribute == (INT32) Attribute) {
557 return EFI_SUCCESS;
558 }
559
560 //
561 // convert Attribute value to terminal emulator
562 // understandable foreground color
563 //
564 switch (Attribute & 0x07) {
565
566 case EFI_BLACK:
567 ForegroundControl = 30;
568 break;
569
570 case EFI_BLUE:
571 ForegroundControl = 34;
572 break;
573
574 case EFI_GREEN:
575 ForegroundControl = 32;
576 break;
577
578 case EFI_CYAN:
579 ForegroundControl = 36;
580 break;
581
582 case EFI_RED:
583 ForegroundControl = 31;
584 break;
585
586 case EFI_MAGENTA:
587 ForegroundControl = 35;
588 break;
589
590 case EFI_BROWN:
591 ForegroundControl = 33;
592 break;
593
594 default:
595
596 case EFI_LIGHTGRAY:
597 ForegroundControl = 37;
598 break;
599
600 }
601 //
602 // bit4 of the Attribute indicates bright control
603 // of terminal emulator.
604 //
605 BrightControl = (UINT8) ((Attribute >> 3) & 1);
606
607 //
608 // convert Attribute value to terminal emulator
609 // understandable background color.
610 //
611 switch ((Attribute >> 4) & 0x07) {
612
613 case EFI_BLACK:
614 BackgroundControl = 40;
615 break;
616
617 case EFI_BLUE:
618 BackgroundControl = 44;
619 break;
620
621 case EFI_GREEN:
622 BackgroundControl = 42;
623 break;
624
625 case EFI_CYAN:
626 BackgroundControl = 46;
627 break;
628
629 case EFI_RED:
630 BackgroundControl = 41;
631 break;
632
633 case EFI_MAGENTA:
634 BackgroundControl = 45;
635 break;
636
637 case EFI_BROWN:
638 BackgroundControl = 43;
639 break;
640
641 default:
642
643 case EFI_LIGHTGRAY:
644 BackgroundControl = 47;
645 break;
646 }
647 //
648 // terminal emulator's control sequence to set attributes
649 //
650 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);
651 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));
652 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));
653 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));
654 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));
655
656 //
657 // save current column and row
658 // for future scrolling back use.
659 //
660 SavedColumn = This->Mode->CursorColumn;
661 SavedRow = This->Mode->CursorRow;
662
663 TerminalDevice->OutputEscChar = TRUE;
664 Status = This->OutputString (This, mSetAttributeString);
665 TerminalDevice->OutputEscChar = FALSE;
666
667 if (EFI_ERROR (Status)) {
668 return EFI_DEVICE_ERROR;
669 }
670 //
671 // scroll back to saved cursor position.
672 //
673 This->Mode->CursorColumn = SavedColumn;
674 This->Mode->CursorRow = SavedRow;
675
676 This->Mode->Attribute = (INT32) Attribute;
677
678 return EFI_SUCCESS;
679
680 }
681
682
683 /**
684 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
685 It clears the ANSI terminal's display to the
686 currently selected background color.
687
688 @param This Indicates the calling context.
689
690 @retval EFI_SUCCESS The operation completed successfully.
691 @retval EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.
692 @retval EFI_UNSUPPORTED The terminal is not in a valid display mode.
693
694 **/
695 EFI_STATUS
696 EFIAPI
697 TerminalConOutClearScreen (
698 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
699 )
700 {
701 EFI_STATUS Status;
702 TERMINAL_DEV *TerminalDevice;
703
704 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
705
706 //
707 // control sequence for clear screen request
708 //
709 TerminalDevice->OutputEscChar = TRUE;
710 Status = This->OutputString (This, mClearScreenString);
711 TerminalDevice->OutputEscChar = FALSE;
712
713 if (EFI_ERROR (Status)) {
714 return EFI_DEVICE_ERROR;
715 }
716
717 Status = This->SetCursorPosition (This, 0, 0);
718
719 return Status;
720 }
721
722
723 /**
724 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().
725
726 @param This Indicates the calling context.
727 @param Column The row to set cursor to.
728 @param Row The column to set cursor to.
729
730 @retval EFI_SUCCESS The operation completed successfully.
731 @retval EFI_DEVICE_ERROR The request fails due to serial port error.
732 @retval EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position
733 is invalid for current mode.
734
735 **/
736 EFI_STATUS
737 EFIAPI
738 TerminalConOutSetCursorPosition (
739 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
740 IN UINTN Column,
741 IN UINTN Row
742 )
743 {
744 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
745 UINTN MaxColumn;
746 UINTN MaxRow;
747 EFI_STATUS Status;
748 TERMINAL_DEV *TerminalDevice;
749
750 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
751
752 //
753 // get current mode
754 //
755 Mode = This->Mode;
756
757 //
758 // get geometry of current mode
759 //
760 Status = This->QueryMode (
761 This,
762 Mode->Mode,
763 &MaxColumn,
764 &MaxRow
765 );
766 if (EFI_ERROR (Status)) {
767 return EFI_UNSUPPORTED;
768 }
769
770 if (Column >= MaxColumn || Row >= MaxRow) {
771 return EFI_UNSUPPORTED;
772 }
773 //
774 // control sequence to move the cursor
775 //
776 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));
777 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));
778 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));
779 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));
780
781 TerminalDevice->OutputEscChar = TRUE;
782 Status = This->OutputString (This, mSetCursorPositionString);
783 TerminalDevice->OutputEscChar = FALSE;
784
785 if (EFI_ERROR (Status)) {
786 return EFI_DEVICE_ERROR;
787 }
788 //
789 // update current cursor position
790 // in the Mode data structure.
791 //
792 Mode->CursorColumn = (INT32) Column;
793 Mode->CursorRow = (INT32) Row;
794
795 return EFI_SUCCESS;
796 }
797
798
799 /**
800 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
801
802 In this driver, the cursor cannot be hidden.
803
804 @param This Indicates the calling context.
805 @param Visible If TRUE, the cursor is set to be visible,
806 If FALSE, the cursor is set to be invisible.
807
808 @retval EFI_SUCCESS The request is valid.
809 @retval EFI_UNSUPPORTED The terminal does not support cursor hidden.
810
811 **/
812 EFI_STATUS
813 EFIAPI
814 TerminalConOutEnableCursor (
815 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
816 IN BOOLEAN Visible
817 )
818 {
819 if (!Visible) {
820 return EFI_UNSUPPORTED;
821 }
822
823 return EFI_SUCCESS;
824 }
825
826
827 /**
828 Detects if a Unicode char is for Box Drawing text graphics.
829
830 @param Graphic Unicode char to test.
831 @param PcAnsi Optional pointer to return PCANSI equivalent of
832 Graphic.
833 @param Ascii Optional pointer to return ASCII equivalent of
834 Graphic.
835
836 @retval TRUE If Graphic is a supported Unicode Box Drawing character.
837
838 **/
839 BOOLEAN
840 TerminalIsValidTextGraphics (
841 IN CHAR16 Graphic,
842 OUT CHAR8 *PcAnsi, OPTIONAL
843 OUT CHAR8 *Ascii OPTIONAL
844 )
845 {
846 UNICODE_TO_CHAR *Table;
847
848 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
849 //
850 // Unicode drawing code charts are all in the 0x25xx range,
851 // arrows are 0x21xx
852 //
853 return FALSE;
854 }
855
856 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
857 if (Graphic == Table->Unicode) {
858 if (PcAnsi != NULL) {
859 *PcAnsi = Table->PcAnsi;
860 }
861
862 if (Ascii != NULL) {
863 *Ascii = Table->Ascii;
864 }
865
866 return TRUE;
867 }
868 }
869
870 return FALSE;
871 }
872
873 /**
874 Detects if a valid ASCII char.
875
876 @param Ascii An ASCII character.
877
878 @retval TRUE If it is a valid ASCII character.
879 @retval FALSE If it is not a valid ASCII character.
880
881 **/
882 BOOLEAN
883 TerminalIsValidAscii (
884 IN CHAR16 Ascii
885 )
886 {
887 //
888 // valid ascii code lies in the extent of 0x20 ~ 0x7f
889 //
890 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
891 return TRUE;
892 }
893
894 return FALSE;
895 }
896
897 /**
898 Detects if a valid EFI control character.
899
900 @param CharC An input EFI Control character.
901
902 @retval TRUE If it is a valid EFI control character.
903 @retval FALSE If it is not a valid EFI control character.
904
905 **/
906 BOOLEAN
907 TerminalIsValidEfiCntlChar (
908 IN CHAR16 CharC
909 )
910 {
911 //
912 // only support four control characters.
913 //
914 if (CharC == CHAR_NULL ||
915 CharC == CHAR_BACKSPACE ||
916 CharC == CHAR_LINEFEED ||
917 CharC == CHAR_CARRIAGE_RETURN ||
918 CharC == CHAR_TAB
919 ) {
920 return TRUE;
921 }
922
923 return FALSE;
924 }