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