]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
1. Sync the tracker for supporting the ModeNumber larger than 2.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConOut.c
CommitLineData
95276127 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 TerminalConOut.c\r
15 \r
16Abstract: \r
17 \r
18\r
19Revision History\r
20--*/\r
21\r
95276127 22#include "Terminal.h"\r
23\r
95276127 24//\r
25// This list is used to define the valid extend chars.\r
26// It also provides a mapping from Unicode to PCANSI or\r
27// ASCII. The ASCII mapping we just made up.\r
28//\r
29//\r
30STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {\r
31 { BOXDRAW_HORIZONTAL, 0xc4, L'-' }, \r
32 { BOXDRAW_VERTICAL, 0xb3, L'|' },\r
33 { BOXDRAW_DOWN_RIGHT, 0xda, L'/' },\r
34 { BOXDRAW_DOWN_LEFT, 0xbf, L'\\' },\r
35 { BOXDRAW_UP_RIGHT, 0xc0, L'\\' },\r
36 { BOXDRAW_UP_LEFT, 0xd9, L'/' },\r
37 { BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|' },\r
38 { BOXDRAW_VERTICAL_LEFT, 0xb4, L'|' },\r
39 { BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+' },\r
40 { BOXDRAW_UP_HORIZONTAL, 0xc1, L'+' },\r
41 { BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+' },\r
42 { BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-' },\r
43 { BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|' },\r
44 { BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/' },\r
45 { BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/' },\r
46 { BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/' },\r
47 { BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\' },\r
48 { BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\' },\r
49 { BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\' },\r
50 { BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\' },\r
51 { BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\' },\r
52 { BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\' },\r
53 { BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/' },\r
54 { BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/' },\r
55 { BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/' },\r
56 { BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|' },\r
57 { BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|' },\r
58 { BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|' },\r
59 { BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|' },\r
60 { BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|' },\r
61 { BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|' },\r
62 { BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+' },\r
63 { BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+' },\r
64 { BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+' },\r
65 { BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+' },\r
66 { BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+' },\r
67 { BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+' },\r
68 { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' },\r
69 { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' },\r
70 { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' },\r
71\r
72 { BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*' },\r
73 { BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+' },\r
74\r
75 { GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, L'^' },\r
76 { GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, L'>' },\r
77 { GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, L'v' },\r
78 { GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, L'<' },\r
79\r
80 { ARROW_LEFT, 0x3c, L'<' },\r
81 { ARROW_UP, 0x18, L'^' },\r
82 { ARROW_RIGHT, 0x3e, L'>' },\r
83 { ARROW_DOWN, 0x19, L'v' },\r
84\r
85 { 0x0000, 0x00, L'\0' }\r
86};\r
87\r
88CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 };\r
89CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };\r
90CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 };\r
91CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 };\r
92\r
93//\r
94// Body of the ConOut functions\r
95//\r
96EFI_STATUS\r
97EFIAPI\r
98TerminalConOutReset (\r
99 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
100 IN BOOLEAN ExtendedVerification\r
101 )\r
102/*++\r
103 Routine Description:\r
104 \r
105 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().\r
106 If ExtendeVerification is TRUE, then perform dependent serial device reset,\r
107 and set display mode to mode 0.\r
108 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
109 \r
110 Arguments:\r
111 \r
112 This - Indicates the calling context.\r
113 \r
114 ExtendedVerification - Indicates that the driver may perform a more exhaustive\r
115 verification operation of the device during reset.\r
116 \r
117 Returns:\r
118 \r
119 EFI_SUCCESS\r
120 The reset operation succeeds. \r
121 \r
122 EFI_DEVICE_ERROR\r
123 The terminal is not functioning correctly or the serial port reset fails.\r
124 \r
125--*/\r
126{\r
127 EFI_STATUS Status;\r
128 TERMINAL_DEV *TerminalDevice;\r
129\r
130 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
131\r
132 //\r
133 // Perform a more exhaustive reset by resetting the serial port.\r
134 //\r
135 if (ExtendedVerification) {\r
136 //\r
137 // Report progress code here\r
138 //\r
139 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
140 EFI_PROGRESS_CODE,\r
97a079ed 141 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),\r
95276127 142 TerminalDevice->DevicePath\r
143 );\r
144\r
145 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);\r
146 if (EFI_ERROR (Status)) {\r
147 //\r
148 // Report error code here\r
149 //\r
150 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
151 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
97a079ed 152 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
95276127 153 TerminalDevice->DevicePath\r
154 );\r
155\r
156 return Status;\r
157 }\r
158 }\r
159\r
160 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
161\r
162 Status = This->SetMode (This, 0);\r
163\r
164 return Status;\r
165}\r
166\r
167EFI_STATUS\r
168EFIAPI\r
169TerminalConOutOutputString (\r
170 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
171 IN CHAR16 *WString\r
172 )\r
173/*++\r
174 Routine Description:\r
175 \r
176 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().\r
177 The Unicode string will be converted to terminal expressible data stream\r
178 and send to terminal via serial port.\r
179 \r
180 \r
181 Arguments:\r
182 \r
183 This - Indicates the calling context.\r
184 \r
185 WString - The Null-terminated Unicode string to be displayed on \r
186 the terminal screen.\r
187 \r
188 Returns:\r
189 \r
190 EFI_SUCCESS\r
191 The string is output successfully. \r
192 \r
193 EFI_DEVICE_ERROR\r
194 The serial port fails to send the string out.\r
195 \r
196 EFI_WARN_UNKNOWN_GLYPH\r
197 Indicates that some of the characters in the Unicode string could not \r
198 be rendered and are skipped. \r
199 \r
200 EFI_UNSUPPORTED\r
201 \r
202--*/\r
203{\r
204 TERMINAL_DEV *TerminalDevice;\r
205 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
206 UINTN MaxColumn;\r
207 UINTN MaxRow;\r
208 UINTN Length;\r
209 UTF8_CHAR Utf8Char;\r
210 CHAR8 GraphicChar;\r
211 CHAR8 AsciiChar;\r
212 EFI_STATUS Status;\r
213 UINT8 ValidBytes;\r
214 //\r
215 // flag used to indicate whether condition happens which will cause\r
216 // return EFI_WARN_UNKNOWN_GLYPH\r
217 //\r
218 BOOLEAN Warning;\r
219\r
220 ValidBytes = 0;\r
221 Warning = FALSE;\r
222\r
223 //\r
224 // get Terminal device data structure pointer.\r
225 //\r
226 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
227\r
228 //\r
3012ce5c 229 // Get current display mode\r
95276127 230 //\r
231 Mode = This->Mode;\r
3012ce5c 232 \r
7347d5d6 233 if (Mode->Mode > 2) {\r
95276127 234 return EFI_UNSUPPORTED;\r
235 }\r
236\r
237 This->QueryMode (\r
238 This,\r
239 Mode->Mode,\r
240 &MaxColumn,\r
241 &MaxRow\r
242 );\r
243\r
244 for (; *WString != CHAR_NULL; WString++) {\r
245\r
246 switch (TerminalDevice->TerminalType) {\r
247\r
248 case PcAnsiType:\r
249 case VT100Type:\r
250 case VT100PlusType:\r
251\r
252 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {\r
253 //\r
254 // If it's not a graphic character convert Unicode to ASCII.\r
255 //\r
256 GraphicChar = (CHAR8) *WString;\r
257\r
258 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {\r
259 //\r
260 // when this driver use the OutputString to output control string,\r
261 // TerminalDevice->OutputEscChar is set to let the Esc char\r
262 // to be output to the terminal emulation software.\r
263 //\r
264 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {\r
265 GraphicChar = 27;\r
266 } else {\r
267 GraphicChar = '?';\r
268 Warning = TRUE;\r
269 }\r
270 }\r
271\r
272 AsciiChar = GraphicChar;\r
273\r
274 }\r
275\r
276 if (TerminalDevice->TerminalType != PcAnsiType) {\r
277 GraphicChar = AsciiChar;\r
278 }\r
279\r
280 Length = 1;\r
281\r
282 Status = TerminalDevice->SerialIo->Write (\r
283 TerminalDevice->SerialIo,\r
284 &Length,\r
285 &GraphicChar\r
286 );\r
287\r
288 if (EFI_ERROR (Status)) {\r
289 goto OutputError;\r
290 }\r
291\r
292 break;\r
293\r
294 case VTUTF8Type:\r
295 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);\r
296 Length = ValidBytes;\r
297 Status = TerminalDevice->SerialIo->Write (\r
298 TerminalDevice->SerialIo,\r
299 &Length,\r
300 (UINT8 *) &Utf8Char\r
301 );\r
302 if (EFI_ERROR (Status)) {\r
303 goto OutputError;\r
304 }\r
305 break;\r
306 }\r
307 //\r
308 // Update cursor position.\r
309 //\r
310 switch (*WString) {\r
311\r
312 case CHAR_BACKSPACE:\r
313 if (Mode->CursorColumn > 0) {\r
314 Mode->CursorColumn--;\r
315 }\r
316 break;\r
317\r
318 case CHAR_LINEFEED:\r
319 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
320 Mode->CursorRow++;\r
321 }\r
322 break;\r
323\r
324 case CHAR_CARRIAGE_RETURN:\r
325 Mode->CursorColumn = 0;\r
326 break;\r
327\r
328 default:\r
329 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {\r
330\r
331 Mode->CursorColumn++;\r
332\r
333 } else {\r
334\r
335 Mode->CursorColumn = 0;\r
336 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
337 Mode->CursorRow++;\r
338 }\r
339\r
340 }\r
341 break;\r
342\r
343 };\r
344\r
345 }\r
346\r
347 if (Warning) {\r
348 return EFI_WARN_UNKNOWN_GLYPH;\r
349 }\r
350\r
351 return EFI_SUCCESS;\r
352\r
353OutputError:\r
354 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
355 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
97a079ed 356 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError),\r
95276127 357 TerminalDevice->DevicePath\r
358 );\r
359\r
360 return EFI_DEVICE_ERROR;\r
361}\r
362\r
363EFI_STATUS\r
364EFIAPI\r
365TerminalConOutTestString (\r
366 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
367 IN CHAR16 *WString\r
368 )\r
369/*++\r
370 Routine Description:\r
371 \r
372 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().\r
373 If one of the characters in the *Wstring is\r
374 neither valid Unicode drawing characters,\r
375 not ASCII code, then this function will return\r
376 EFI_UNSUPPORTED.\r
377 \r
378 \r
379 Arguments:\r
380 \r
381 This - Indicates the calling context.\r
382 \r
383 WString - The Null-terminated Unicode string to be tested.\r
384 \r
385 Returns:\r
386 \r
387 EFI_SUCCESS\r
388 The terminal is capable of rendering the output string. \r
389 \r
390 EFI_UNSUPPORTED\r
391 Some of the characters in the Unicode string cannot be rendered. \r
392 \r
393--*/\r
394{\r
395 TERMINAL_DEV *TerminalDevice;\r
396 EFI_STATUS Status;\r
397\r
398 //\r
399 // get Terminal device data structure pointer.\r
400 //\r
401 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
402\r
403 switch (TerminalDevice->TerminalType) {\r
404\r
405 case PcAnsiType:\r
406 case VT100Type:\r
407 case VT100PlusType:\r
408 Status = AnsiTestString (TerminalDevice, WString);\r
409 break;\r
410\r
411 case VTUTF8Type:\r
412 Status = VTUTF8TestString (TerminalDevice, WString);\r
413 break;\r
414\r
415 default:\r
416 Status = EFI_UNSUPPORTED;\r
417 break;\r
418 }\r
419\r
420 return Status;\r
421}\r
422\r
423EFI_STATUS\r
424EFIAPI\r
425TerminalConOutQueryMode (\r
426 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
427 IN UINTN ModeNumber,\r
428 OUT UINTN *Columns,\r
429 OUT UINTN *Rows\r
430 )\r
431/*++\r
432 Routine Description:\r
433 \r
7347d5d6 434 Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.QueryMode().\r
95276127 435 It returns information for an available text mode\r
436 that the terminal supports.\r
7347d5d6 437 In this driver, we support text mode 80x25 (mode 0),\r
438 80x50 (mode 1), 100x31 (mode 2).\r
95276127 439 \r
440 \r
441 Arguments:\r
442 \r
443 *This\r
444 Indicates the calling context.\r
445 \r
446 ModeNumber\r
447 The mode number to return information on.\r
448 \r
449 Columns\r
450 The returned columns of the requested mode.\r
451 \r
452 Rows\r
453 The returned rows of the requested mode. \r
454 \r
455 Returns:\r
456 \r
457 EFI_SUCCESS\r
458 The requested mode information is returned. \r
459 \r
460 EFI_UNSUPPORTED\r
461 The mode number is not valid. \r
462 \r
463 EFI_DEVICE_ERROR\r
464 \r
465--*/\r
466{\r
7347d5d6 467 if (This->Mode->MaxMode > 3) {\r
95276127 468 return EFI_DEVICE_ERROR;\r
469 }\r
470\r
471 if (ModeNumber == 0) {\r
95276127 472 *Columns = MODE0_COLUMN_COUNT;\r
473 *Rows = MODE0_ROW_COUNT;\r
3012ce5c 474 return EFI_SUCCESS;\r
475 } else if (ModeNumber == 1) { \r
476 *Columns = MODE1_COLUMN_COUNT;\r
477 *Rows = MODE1_ROW_COUNT;\r
95276127 478 return EFI_SUCCESS;\r
7347d5d6 479 } else if (ModeNumber == 2) {\r
480 *Columns = MODE2_COLUMN_COUNT;\r
481 *Rows = MODE2_ROW_COUNT;\r
482 return EFI_SUCCESS;\r
95276127 483 }\r
484\r
485 return EFI_UNSUPPORTED;\r
486}\r
487\r
488EFI_STATUS\r
489EFIAPI\r
490TerminalConOutSetMode (\r
491 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
492 IN UINTN ModeNumber\r
493 )\r
494/*++\r
495 Routine Description:\r
496 \r
497 Implements EFI_SIMPLE_TEXT_OUT.SetMode().\r
498 Set the terminal to a specified display mode.\r
499 In this driver, we only support mode 0. \r
500 \r
501 Arguments:\r
502 \r
503 This\r
504 Indicates the calling context.\r
505 \r
506 ModeNumber\r
507 The text mode to set.\r
508 \r
509 Returns:\r
510 \r
511 EFI_SUCCESS\r
512 The requested text mode is set.\r
513 \r
514 EFI_DEVICE_ERROR\r
515 The requested text mode cannot be set because of serial device error.\r
516 \r
517 EFI_UNSUPPORTED\r
518 The text mode number is not valid. \r
519 \r
520--*/\r
521{\r
522 EFI_STATUS Status;\r
523 TERMINAL_DEV *TerminalDevice;\r
524\r
525 //\r
526 // get Terminal device data structure pointer.\r
527 //\r
528 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
529\r
7347d5d6 530 if (ModeNumber > 2) {\r
95276127 531 return EFI_UNSUPPORTED;\r
532 }\r
3012ce5c 533 \r
534 //\r
535 // Set the current mode\r
536 //\r
537 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 538\r
539 This->ClearScreen (This);\r
540\r
541 TerminalDevice->OutputEscChar = TRUE;\r
542 Status = This->OutputString (This, mSetModeString);\r
543 TerminalDevice->OutputEscChar = FALSE;\r
544\r
545 if (EFI_ERROR (Status)) {\r
546 return EFI_DEVICE_ERROR;\r
547 }\r
548\r
3012ce5c 549 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 550\r
551 Status = This->ClearScreen (This);\r
552 if (EFI_ERROR (Status)) {\r
553 return EFI_DEVICE_ERROR;\r
554 }\r
555\r
556 return EFI_SUCCESS;\r
557\r
558}\r
559\r
560EFI_STATUS\r
561EFIAPI\r
562TerminalConOutSetAttribute (\r
563 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
564 IN UINTN Attribute\r
565 )\r
566/*++\r
567 Routine Description:\r
568 \r
569 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute(). \r
570 \r
571 Arguments:\r
572 \r
573 This\r
574 Indicates the calling context.\r
575 \r
576 Attribute\r
577 The attribute to set. Only bit0..6 are valid, all other bits\r
578 are undefined and must be zero.\r
579 \r
580 Returns:\r
581 \r
582 EFI_SUCCESS\r
583 The requested attribute is set. \r
584 \r
585 EFI_DEVICE_ERROR\r
586 The requested attribute cannot be set due to serial port error.\r
587 \r
588 EFI_UNSUPPORTED\r
589 The attribute requested is not defined by EFI spec. \r
590 \r
591--*/\r
592{\r
593 UINT8 ForegroundControl;\r
594 UINT8 BackgroundControl;\r
595 UINT8 BrightControl;\r
596 INT32 SavedColumn;\r
597 INT32 SavedRow;\r
598 EFI_STATUS Status;\r
599 TERMINAL_DEV *TerminalDevice;\r
600\r
601 SavedColumn = 0;\r
602 SavedRow = 0;\r
603\r
604 //\r
605 // get Terminal device data structure pointer.\r
606 //\r
607 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
608\r
609 //\r
610 // only the bit0..6 of the Attribute is valid\r
611 //\r
612 if ((Attribute | 0x7f) != 0x7f) {\r
613 return EFI_UNSUPPORTED;\r
614 }\r
615 //\r
616 // convert Attribute value to terminal emulator\r
617 // understandable foreground color\r
618 //\r
619 switch (Attribute & 0x07) {\r
620\r
621 case EFI_BLACK:\r
622 ForegroundControl = 30;\r
623 break;\r
624\r
625 case EFI_BLUE:\r
626 ForegroundControl = 34;\r
627 break;\r
628\r
629 case EFI_GREEN:\r
630 ForegroundControl = 32;\r
631 break;\r
632\r
633 case EFI_CYAN:\r
634 ForegroundControl = 36;\r
635 break;\r
636\r
637 case EFI_RED:\r
638 ForegroundControl = 31;\r
639 break;\r
640\r
641 case EFI_MAGENTA:\r
642 ForegroundControl = 35;\r
643 break;\r
644\r
645 case EFI_BROWN:\r
646 ForegroundControl = 33;\r
647 break;\r
648\r
649 default:\r
650\r
651 case EFI_LIGHTGRAY:\r
652 ForegroundControl = 37;\r
653 break;\r
654\r
655 }\r
656 //\r
657 // bit4 of the Attribute indicates bright control\r
658 // of terminal emulator.\r
659 //\r
660 BrightControl = (UINT8) ((Attribute >> 3) & 1);\r
661\r
662 //\r
663 // convert Attribute value to terminal emulator\r
664 // understandable background color.\r
665 //\r
666 switch ((Attribute >> 4) & 0x07) {\r
667\r
668 case EFI_BLACK:\r
669 BackgroundControl = 40;\r
670 break;\r
671\r
672 case EFI_BLUE:\r
673 BackgroundControl = 44;\r
674 break;\r
675\r
676 case EFI_GREEN:\r
677 BackgroundControl = 42;\r
678 break;\r
679\r
680 case EFI_CYAN:\r
681 BackgroundControl = 46;\r
682 break;\r
683\r
684 case EFI_RED:\r
685 BackgroundControl = 41;\r
686 break;\r
687\r
688 case EFI_MAGENTA:\r
689 BackgroundControl = 45;\r
690 break;\r
691\r
692 case EFI_BROWN:\r
693 BackgroundControl = 43;\r
694 break;\r
695\r
696 default:\r
697\r
698 case EFI_LIGHTGRAY:\r
699 BackgroundControl = 47;\r
700 break;\r
701 }\r
702 //\r
703 // terminal emulator's control sequence to set attributes\r
704 //\r
705 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);\r
706 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));\r
707 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));\r
708 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));\r
709 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));\r
710\r
711 //\r
712 // save current column and row\r
713 // for future scrolling back use.\r
714 //\r
715 SavedColumn = This->Mode->CursorColumn;\r
716 SavedRow = This->Mode->CursorRow;\r
717\r
718 TerminalDevice->OutputEscChar = TRUE;\r
719 Status = This->OutputString (This, mSetAttributeString);\r
720 TerminalDevice->OutputEscChar = FALSE;\r
721\r
722 if (EFI_ERROR (Status)) {\r
723 return EFI_DEVICE_ERROR;\r
724 }\r
725 //\r
726 // scroll back to saved cursor position.\r
727 //\r
728 This->Mode->CursorColumn = SavedColumn;\r
729 This->Mode->CursorRow = SavedRow;\r
730\r
731 This->Mode->Attribute = (INT32) Attribute;\r
732\r
733 return EFI_SUCCESS;\r
734\r
735}\r
736\r
737EFI_STATUS\r
738EFIAPI\r
739TerminalConOutClearScreen (\r
740 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
741 )\r
742/*++\r
743 Routine Description:\r
744 \r
745 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().\r
746 It clears the ANSI terminal's display to the \r
747 currently selected background color.\r
748 \r
749 \r
750 Arguments:\r
751 \r
752 This\r
753 Indicates the calling context.\r
754\r
755 Returns:\r
756 \r
757 EFI_SUCCESS\r
758 The operation completed successfully.\r
759 \r
760 EFI_DEVICE_ERROR\r
761 The terminal screen cannot be cleared due to serial port error. \r
762 \r
763 EFI_UNSUPPORTED\r
764 The terminal is not in a valid display mode. \r
765 \r
766--*/\r
767{\r
768 EFI_STATUS Status;\r
769 TERMINAL_DEV *TerminalDevice;\r
770\r
771 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
772\r
773 //\r
774 // control sequence for clear screen request\r
775 //\r
776 TerminalDevice->OutputEscChar = TRUE;\r
777 Status = This->OutputString (This, mClearScreenString);\r
778 TerminalDevice->OutputEscChar = FALSE;\r
779\r
780 if (EFI_ERROR (Status)) {\r
781 return EFI_DEVICE_ERROR;\r
782 }\r
783\r
784 Status = This->SetCursorPosition (This, 0, 0);\r
785\r
786 return Status;\r
787}\r
788\r
789EFI_STATUS\r
790EFIAPI\r
791TerminalConOutSetCursorPosition (\r
792 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
793 IN UINTN Column,\r
794 IN UINTN Row\r
795 )\r
796/*++\r
797 Routine Description:\r
798 \r
799 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition(). \r
800 \r
801 Arguments:\r
802 \r
803 This\r
804 Indicates the calling context.\r
805 \r
806 Column\r
807 The row to set cursor to.\r
808 \r
809 Row\r
810 The column to set cursor to. \r
811\r
812 Returns:\r
813 \r
814 EFI_SUCCESS\r
815 The operation completed successfully.\r
816 \r
817 EFI_DEVICE_ERROR\r
818 The request fails due to serial port error. \r
819 \r
820 EFI_UNSUPPORTED\r
821 The terminal is not in a valid text mode, or the cursor position\r
822 is invalid for current mode. \r
823 \r
824--*/\r
825{\r
826 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
827 UINTN MaxColumn;\r
828 UINTN MaxRow;\r
829 EFI_STATUS Status;\r
830 TERMINAL_DEV *TerminalDevice;\r
831\r
832 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
833\r
834 //\r
835 // get current mode\r
836 //\r
837 Mode = This->Mode;\r
838\r
839 //\r
840 // get geometry of current mode\r
841 //\r
842 Status = This->QueryMode (\r
843 This,\r
844 Mode->Mode,\r
845 &MaxColumn,\r
846 &MaxRow\r
847 );\r
848 if (EFI_ERROR (Status)) {\r
849 return EFI_UNSUPPORTED;\r
850 }\r
851\r
852 if (Column >= MaxColumn || Row >= MaxRow) {\r
853 return EFI_UNSUPPORTED;\r
854 }\r
855 //\r
856 // control sequence to move the cursor\r
857 //\r
858 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));\r
859 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));\r
860 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));\r
861 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));\r
862\r
863 TerminalDevice->OutputEscChar = TRUE;\r
864 Status = This->OutputString (This, mSetCursorPositionString);\r
865 TerminalDevice->OutputEscChar = FALSE;\r
866\r
867 if (EFI_ERROR (Status)) {\r
868 return EFI_DEVICE_ERROR;\r
869 }\r
870 //\r
871 // update current cursor position\r
872 // in the Mode data structure.\r
873 //\r
874 Mode->CursorColumn = (INT32) Column;\r
875 Mode->CursorRow = (INT32) Row;\r
876\r
877 return EFI_SUCCESS;\r
878}\r
879\r
880EFI_STATUS\r
881EFIAPI\r
882TerminalConOutEnableCursor (\r
883 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
884 IN BOOLEAN Visible\r
885 )\r
886/*++\r
887 Routine Description:\r
888 \r
889 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
890 In this driver, the cursor cannot be hidden. \r
891 \r
892 Arguments:\r
893 \r
894 This\r
895 Indicates the calling context.\r
896 \r
897 Visible\r
898 If TRUE, the cursor is set to be visible,\r
899 If FALSE, the cursor is set to be invisible. \r
900\r
901 Returns:\r
902 \r
903 EFI_SUCCESS\r
904 The request is valid.\r
905 \r
906 EFI_UNSUPPORTED\r
907 The terminal does not support cursor hidden. \r
908 \r
909--*/\r
910{\r
911 if (!Visible) {\r
912 return EFI_UNSUPPORTED;\r
913 }\r
914\r
915 return EFI_SUCCESS;\r
916}\r
917\r
918BOOLEAN\r
919TerminalIsValidTextGraphics (\r
920 IN CHAR16 Graphic,\r
921 OUT CHAR8 *PcAnsi, OPTIONAL\r
922 OUT CHAR8 *Ascii OPTIONAL\r
923 )\r
924/*++\r
925\r
926Routine Description:\r
927\r
928 Detects if a Unicode char is for Box Drawing text graphics.\r
929\r
930Arguments:\r
931\r
932 Graphic - Unicode char to test.\r
933\r
934 PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.\r
935\r
936 Ascii - Optional pointer to return ASCII equivalent of Graphic.\r
937\r
938Returns:\r
939\r
940 TRUE if Graphic is a supported Unicode Box Drawing character.\r
941\r
942--*/\r
943{\r
944 UNICODE_TO_CHAR *Table;\r
945\r
946 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {\r
947 //\r
948 // Unicode drawing code charts are all in the 0x25xx range,\r
949 // arrows are 0x21xx\r
950 //\r
951 return FALSE;\r
952 }\r
953\r
954 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {\r
955 if (Graphic == Table->Unicode) {\r
956 if (PcAnsi != NULL) {\r
957 *PcAnsi = Table->PcAnsi;\r
958 }\r
959\r
960 if (Ascii != NULL) {\r
961 *Ascii = Table->Ascii;\r
962 }\r
963\r
964 return TRUE;\r
965 }\r
966 }\r
967\r
968 return FALSE;\r
969}\r
970\r
971BOOLEAN\r
972TerminalIsValidAscii (\r
973 IN CHAR16 Ascii\r
974 )\r
975{\r
976 //\r
977 // valid ascii code lies in the extent of 0x20 ~ 0x7f\r
978 //\r
979 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {\r
980 return TRUE;\r
981 }\r
982\r
983 return FALSE;\r
984}\r
985\r
986BOOLEAN\r
987TerminalIsValidEfiCntlChar (\r
988 IN CHAR16 CharC\r
989 )\r
990{\r
991 //\r
992 // only support four control characters.\r
993 //\r
994 if (CharC == CHAR_NULL ||\r
995 CharC == CHAR_BACKSPACE ||\r
996 CharC == CHAR_LINEFEED ||\r
997 CharC == CHAR_CARRIAGE_RETURN ||\r
998 CharC == CHAR_TAB\r
999 ) {\r
1000 return TRUE;\r
1001 }\r
1002\r
1003 return FALSE;\r
1004}\r