]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
1. Fixed bugs in DxeNetLib to meet consistence with network module DriverBinding...
[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
233 if (Mode->Mode > 1) {\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
434 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().\r
435 It returns information for an available text mode\r
436 that the terminal supports.\r
437 In this driver, we only support text mode 80x25, which is\r
438 defined as mode 0.\r
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
3012ce5c 467 if (This->Mode->MaxMode > 2) {\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
479 }\r
480\r
481 return EFI_UNSUPPORTED;\r
482}\r
483\r
484EFI_STATUS\r
485EFIAPI\r
486TerminalConOutSetMode (\r
487 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
488 IN UINTN ModeNumber\r
489 )\r
490/*++\r
491 Routine Description:\r
492 \r
493 Implements EFI_SIMPLE_TEXT_OUT.SetMode().\r
494 Set the terminal to a specified display mode.\r
495 In this driver, we only support mode 0. \r
496 \r
497 Arguments:\r
498 \r
499 This\r
500 Indicates the calling context.\r
501 \r
502 ModeNumber\r
503 The text mode to set.\r
504 \r
505 Returns:\r
506 \r
507 EFI_SUCCESS\r
508 The requested text mode is set.\r
509 \r
510 EFI_DEVICE_ERROR\r
511 The requested text mode cannot be set because of serial device error.\r
512 \r
513 EFI_UNSUPPORTED\r
514 The text mode number is not valid. \r
515 \r
516--*/\r
517{\r
518 EFI_STATUS Status;\r
519 TERMINAL_DEV *TerminalDevice;\r
520\r
521 //\r
522 // get Terminal device data structure pointer.\r
523 //\r
524 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
525\r
3012ce5c 526 if (ModeNumber > 1) {\r
95276127 527 return EFI_UNSUPPORTED;\r
528 }\r
3012ce5c 529 \r
530 //\r
531 // Set the current mode\r
532 //\r
533 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 534\r
535 This->ClearScreen (This);\r
536\r
537 TerminalDevice->OutputEscChar = TRUE;\r
538 Status = This->OutputString (This, mSetModeString);\r
539 TerminalDevice->OutputEscChar = FALSE;\r
540\r
541 if (EFI_ERROR (Status)) {\r
542 return EFI_DEVICE_ERROR;\r
543 }\r
544\r
3012ce5c 545 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 546\r
547 Status = This->ClearScreen (This);\r
548 if (EFI_ERROR (Status)) {\r
549 return EFI_DEVICE_ERROR;\r
550 }\r
551\r
552 return EFI_SUCCESS;\r
553\r
554}\r
555\r
556EFI_STATUS\r
557EFIAPI\r
558TerminalConOutSetAttribute (\r
559 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
560 IN UINTN Attribute\r
561 )\r
562/*++\r
563 Routine Description:\r
564 \r
565 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute(). \r
566 \r
567 Arguments:\r
568 \r
569 This\r
570 Indicates the calling context.\r
571 \r
572 Attribute\r
573 The attribute to set. Only bit0..6 are valid, all other bits\r
574 are undefined and must be zero.\r
575 \r
576 Returns:\r
577 \r
578 EFI_SUCCESS\r
579 The requested attribute is set. \r
580 \r
581 EFI_DEVICE_ERROR\r
582 The requested attribute cannot be set due to serial port error.\r
583 \r
584 EFI_UNSUPPORTED\r
585 The attribute requested is not defined by EFI spec. \r
586 \r
587--*/\r
588{\r
589 UINT8 ForegroundControl;\r
590 UINT8 BackgroundControl;\r
591 UINT8 BrightControl;\r
592 INT32 SavedColumn;\r
593 INT32 SavedRow;\r
594 EFI_STATUS Status;\r
595 TERMINAL_DEV *TerminalDevice;\r
596\r
597 SavedColumn = 0;\r
598 SavedRow = 0;\r
599\r
600 //\r
601 // get Terminal device data structure pointer.\r
602 //\r
603 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
604\r
605 //\r
606 // only the bit0..6 of the Attribute is valid\r
607 //\r
608 if ((Attribute | 0x7f) != 0x7f) {\r
609 return EFI_UNSUPPORTED;\r
610 }\r
611 //\r
612 // convert Attribute value to terminal emulator\r
613 // understandable foreground color\r
614 //\r
615 switch (Attribute & 0x07) {\r
616\r
617 case EFI_BLACK:\r
618 ForegroundControl = 30;\r
619 break;\r
620\r
621 case EFI_BLUE:\r
622 ForegroundControl = 34;\r
623 break;\r
624\r
625 case EFI_GREEN:\r
626 ForegroundControl = 32;\r
627 break;\r
628\r
629 case EFI_CYAN:\r
630 ForegroundControl = 36;\r
631 break;\r
632\r
633 case EFI_RED:\r
634 ForegroundControl = 31;\r
635 break;\r
636\r
637 case EFI_MAGENTA:\r
638 ForegroundControl = 35;\r
639 break;\r
640\r
641 case EFI_BROWN:\r
642 ForegroundControl = 33;\r
643 break;\r
644\r
645 default:\r
646\r
647 case EFI_LIGHTGRAY:\r
648 ForegroundControl = 37;\r
649 break;\r
650\r
651 }\r
652 //\r
653 // bit4 of the Attribute indicates bright control\r
654 // of terminal emulator.\r
655 //\r
656 BrightControl = (UINT8) ((Attribute >> 3) & 1);\r
657\r
658 //\r
659 // convert Attribute value to terminal emulator\r
660 // understandable background color.\r
661 //\r
662 switch ((Attribute >> 4) & 0x07) {\r
663\r
664 case EFI_BLACK:\r
665 BackgroundControl = 40;\r
666 break;\r
667\r
668 case EFI_BLUE:\r
669 BackgroundControl = 44;\r
670 break;\r
671\r
672 case EFI_GREEN:\r
673 BackgroundControl = 42;\r
674 break;\r
675\r
676 case EFI_CYAN:\r
677 BackgroundControl = 46;\r
678 break;\r
679\r
680 case EFI_RED:\r
681 BackgroundControl = 41;\r
682 break;\r
683\r
684 case EFI_MAGENTA:\r
685 BackgroundControl = 45;\r
686 break;\r
687\r
688 case EFI_BROWN:\r
689 BackgroundControl = 43;\r
690 break;\r
691\r
692 default:\r
693\r
694 case EFI_LIGHTGRAY:\r
695 BackgroundControl = 47;\r
696 break;\r
697 }\r
698 //\r
699 // terminal emulator's control sequence to set attributes\r
700 //\r
701 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);\r
702 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));\r
703 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));\r
704 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));\r
705 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));\r
706\r
707 //\r
708 // save current column and row\r
709 // for future scrolling back use.\r
710 //\r
711 SavedColumn = This->Mode->CursorColumn;\r
712 SavedRow = This->Mode->CursorRow;\r
713\r
714 TerminalDevice->OutputEscChar = TRUE;\r
715 Status = This->OutputString (This, mSetAttributeString);\r
716 TerminalDevice->OutputEscChar = FALSE;\r
717\r
718 if (EFI_ERROR (Status)) {\r
719 return EFI_DEVICE_ERROR;\r
720 }\r
721 //\r
722 // scroll back to saved cursor position.\r
723 //\r
724 This->Mode->CursorColumn = SavedColumn;\r
725 This->Mode->CursorRow = SavedRow;\r
726\r
727 This->Mode->Attribute = (INT32) Attribute;\r
728\r
729 return EFI_SUCCESS;\r
730\r
731}\r
732\r
733EFI_STATUS\r
734EFIAPI\r
735TerminalConOutClearScreen (\r
736 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
737 )\r
738/*++\r
739 Routine Description:\r
740 \r
741 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().\r
742 It clears the ANSI terminal's display to the \r
743 currently selected background color.\r
744 \r
745 \r
746 Arguments:\r
747 \r
748 This\r
749 Indicates the calling context.\r
750\r
751 Returns:\r
752 \r
753 EFI_SUCCESS\r
754 The operation completed successfully.\r
755 \r
756 EFI_DEVICE_ERROR\r
757 The terminal screen cannot be cleared due to serial port error. \r
758 \r
759 EFI_UNSUPPORTED\r
760 The terminal is not in a valid display mode. \r
761 \r
762--*/\r
763{\r
764 EFI_STATUS Status;\r
765 TERMINAL_DEV *TerminalDevice;\r
766\r
767 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
768\r
769 //\r
770 // control sequence for clear screen request\r
771 //\r
772 TerminalDevice->OutputEscChar = TRUE;\r
773 Status = This->OutputString (This, mClearScreenString);\r
774 TerminalDevice->OutputEscChar = FALSE;\r
775\r
776 if (EFI_ERROR (Status)) {\r
777 return EFI_DEVICE_ERROR;\r
778 }\r
779\r
780 Status = This->SetCursorPosition (This, 0, 0);\r
781\r
782 return Status;\r
783}\r
784\r
785EFI_STATUS\r
786EFIAPI\r
787TerminalConOutSetCursorPosition (\r
788 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
789 IN UINTN Column,\r
790 IN UINTN Row\r
791 )\r
792/*++\r
793 Routine Description:\r
794 \r
795 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition(). \r
796 \r
797 Arguments:\r
798 \r
799 This\r
800 Indicates the calling context.\r
801 \r
802 Column\r
803 The row to set cursor to.\r
804 \r
805 Row\r
806 The column to set cursor to. \r
807\r
808 Returns:\r
809 \r
810 EFI_SUCCESS\r
811 The operation completed successfully.\r
812 \r
813 EFI_DEVICE_ERROR\r
814 The request fails due to serial port error. \r
815 \r
816 EFI_UNSUPPORTED\r
817 The terminal is not in a valid text mode, or the cursor position\r
818 is invalid for current mode. \r
819 \r
820--*/\r
821{\r
822 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
823 UINTN MaxColumn;\r
824 UINTN MaxRow;\r
825 EFI_STATUS Status;\r
826 TERMINAL_DEV *TerminalDevice;\r
827\r
828 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
829\r
830 //\r
831 // get current mode\r
832 //\r
833 Mode = This->Mode;\r
834\r
835 //\r
836 // get geometry of current mode\r
837 //\r
838 Status = This->QueryMode (\r
839 This,\r
840 Mode->Mode,\r
841 &MaxColumn,\r
842 &MaxRow\r
843 );\r
844 if (EFI_ERROR (Status)) {\r
845 return EFI_UNSUPPORTED;\r
846 }\r
847\r
848 if (Column >= MaxColumn || Row >= MaxRow) {\r
849 return EFI_UNSUPPORTED;\r
850 }\r
851 //\r
852 // control sequence to move the cursor\r
853 //\r
854 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));\r
855 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));\r
856 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));\r
857 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));\r
858\r
859 TerminalDevice->OutputEscChar = TRUE;\r
860 Status = This->OutputString (This, mSetCursorPositionString);\r
861 TerminalDevice->OutputEscChar = FALSE;\r
862\r
863 if (EFI_ERROR (Status)) {\r
864 return EFI_DEVICE_ERROR;\r
865 }\r
866 //\r
867 // update current cursor position\r
868 // in the Mode data structure.\r
869 //\r
870 Mode->CursorColumn = (INT32) Column;\r
871 Mode->CursorRow = (INT32) Row;\r
872\r
873 return EFI_SUCCESS;\r
874}\r
875\r
876EFI_STATUS\r
877EFIAPI\r
878TerminalConOutEnableCursor (\r
879 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
880 IN BOOLEAN Visible\r
881 )\r
882/*++\r
883 Routine Description:\r
884 \r
885 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
886 In this driver, the cursor cannot be hidden. \r
887 \r
888 Arguments:\r
889 \r
890 This\r
891 Indicates the calling context.\r
892 \r
893 Visible\r
894 If TRUE, the cursor is set to be visible,\r
895 If FALSE, the cursor is set to be invisible. \r
896\r
897 Returns:\r
898 \r
899 EFI_SUCCESS\r
900 The request is valid.\r
901 \r
902 EFI_UNSUPPORTED\r
903 The terminal does not support cursor hidden. \r
904 \r
905--*/\r
906{\r
907 if (!Visible) {\r
908 return EFI_UNSUPPORTED;\r
909 }\r
910\r
911 return EFI_SUCCESS;\r
912}\r
913\r
914BOOLEAN\r
915TerminalIsValidTextGraphics (\r
916 IN CHAR16 Graphic,\r
917 OUT CHAR8 *PcAnsi, OPTIONAL\r
918 OUT CHAR8 *Ascii OPTIONAL\r
919 )\r
920/*++\r
921\r
922Routine Description:\r
923\r
924 Detects if a Unicode char is for Box Drawing text graphics.\r
925\r
926Arguments:\r
927\r
928 Graphic - Unicode char to test.\r
929\r
930 PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.\r
931\r
932 Ascii - Optional pointer to return ASCII equivalent of Graphic.\r
933\r
934Returns:\r
935\r
936 TRUE if Graphic is a supported Unicode Box Drawing character.\r
937\r
938--*/\r
939{\r
940 UNICODE_TO_CHAR *Table;\r
941\r
942 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {\r
943 //\r
944 // Unicode drawing code charts are all in the 0x25xx range,\r
945 // arrows are 0x21xx\r
946 //\r
947 return FALSE;\r
948 }\r
949\r
950 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {\r
951 if (Graphic == Table->Unicode) {\r
952 if (PcAnsi != NULL) {\r
953 *PcAnsi = Table->PcAnsi;\r
954 }\r
955\r
956 if (Ascii != NULL) {\r
957 *Ascii = Table->Ascii;\r
958 }\r
959\r
960 return TRUE;\r
961 }\r
962 }\r
963\r
964 return FALSE;\r
965}\r
966\r
967BOOLEAN\r
968TerminalIsValidAscii (\r
969 IN CHAR16 Ascii\r
970 )\r
971{\r
972 //\r
973 // valid ascii code lies in the extent of 0x20 ~ 0x7f\r
974 //\r
975 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {\r
976 return TRUE;\r
977 }\r
978\r
979 return FALSE;\r
980}\r
981\r
982BOOLEAN\r
983TerminalIsValidEfiCntlChar (\r
984 IN CHAR16 CharC\r
985 )\r
986{\r
987 //\r
988 // only support four control characters.\r
989 //\r
990 if (CharC == CHAR_NULL ||\r
991 CharC == CHAR_BACKSPACE ||\r
992 CharC == CHAR_LINEFEED ||\r
993 CharC == CHAR_CARRIAGE_RETURN ||\r
994 CharC == CHAR_TAB\r
995 ) {\r
996 return TRUE;\r
997 }\r
998\r
999 return FALSE;\r
1000}\r