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