]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
apply for doxgen format.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConOut.c
... / ...
CommitLineData
1/** @file\r
2 Implementation for EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL protocol.\r
3\r
4Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Terminal.h"\r
16\r
17//\r
18// This list is used to define the valid extend chars.\r
19// It also provides a mapping from Unicode to PCANSI or\r
20// ASCII. The ASCII mapping we just made up.\r
21//\r
22//\r
23STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {\r
24 { BOXDRAW_HORIZONTAL, 0xc4, L'-' },\r
25 { BOXDRAW_VERTICAL, 0xb3, L'|' },\r
26 { BOXDRAW_DOWN_RIGHT, 0xda, L'/' },\r
27 { BOXDRAW_DOWN_LEFT, 0xbf, L'\\' },\r
28 { BOXDRAW_UP_RIGHT, 0xc0, L'\\' },\r
29 { BOXDRAW_UP_LEFT, 0xd9, L'/' },\r
30 { BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|' },\r
31 { BOXDRAW_VERTICAL_LEFT, 0xb4, L'|' },\r
32 { BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+' },\r
33 { BOXDRAW_UP_HORIZONTAL, 0xc1, L'+' },\r
34 { BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+' },\r
35 { BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-' },\r
36 { BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|' },\r
37 { BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/' },\r
38 { BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/' },\r
39 { BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/' },\r
40 { BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\' },\r
41 { BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\' },\r
42 { BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\' },\r
43 { BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\' },\r
44 { BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\' },\r
45 { BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\' },\r
46 { BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/' },\r
47 { BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/' },\r
48 { BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/' },\r
49 { BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|' },\r
50 { BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|' },\r
51 { BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|' },\r
52 { BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|' },\r
53 { BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|' },\r
54 { BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|' },\r
55 { BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+' },\r
56 { BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+' },\r
57 { BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+' },\r
58 { BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+' },\r
59 { BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+' },\r
60 { BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+' },\r
61 { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' },\r
62 { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' },\r
63 { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' },\r
64\r
65 { BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*' },\r
66 { BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+' },\r
67\r
68 { GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, L'^' },\r
69 { GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, L'>' },\r
70 { GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, L'v' },\r
71 { GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, L'<' },\r
72\r
73 { ARROW_LEFT, 0x3c, L'<' },\r
74 { ARROW_UP, 0x18, L'^' },\r
75 { ARROW_RIGHT, 0x3e, L'>' },\r
76 { ARROW_DOWN, 0x19, L'v' },\r
77\r
78 { 0x0000, 0x00, L'\0' }\r
79};\r
80\r
81CHAR16 mSetModeString[] = { ESC, '[', '=', '3', 'h', 0 };\r
82CHAR16 mSetAttributeString[] = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };\r
83CHAR16 mClearScreenString[] = { ESC, '[', '2', 'J', 0 };\r
84CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 };\r
85\r
86//\r
87// Body of the ConOut functions\r
88//\r
89EFI_STATUS\r
90EFIAPI\r
91TerminalConOutReset (\r
92 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
93 IN BOOLEAN ExtendedVerification\r
94 )\r
95/*++\r
96 Routine Description:\r
97\r
98 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().\r
99 If ExtendeVerification is TRUE, then perform dependent serial device reset,\r
100 and set display mode to mode 0.\r
101 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
102\r
103 Arguments:\r
104\r
105 This - Indicates the calling context.\r
106\r
107 ExtendedVerification - Indicates that the driver may perform a more exhaustive\r
108 verification operation of the device during reset.\r
109\r
110 Returns:\r
111\r
112 EFI_SUCCESS\r
113 The reset operation succeeds.\r
114\r
115 EFI_DEVICE_ERROR\r
116 The terminal is not functioning correctly or the serial port reset fails.\r
117\r
118--*/\r
119{\r
120 EFI_STATUS Status;\r
121 TERMINAL_DEV *TerminalDevice;\r
122\r
123 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
124\r
125 //\r
126 // Perform a more exhaustive reset by resetting the serial port.\r
127 //\r
128 if (ExtendedVerification) {\r
129 //\r
130 // Report progress code here\r
131 //\r
132 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
133 EFI_PROGRESS_CODE,\r
134 PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),\r
135 TerminalDevice->DevicePath\r
136 );\r
137\r
138 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);\r
139 if (EFI_ERROR (Status)) {\r
140 //\r
141 // Report error code here\r
142 //\r
143 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
144 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
145 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
146 TerminalDevice->DevicePath\r
147 );\r
148\r
149 return Status;\r
150 }\r
151 }\r
152\r
153 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
154\r
155 Status = This->SetMode (This, 0);\r
156\r
157 return Status;\r
158}\r
159\r
160EFI_STATUS\r
161EFIAPI\r
162TerminalConOutOutputString (\r
163 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
164 IN CHAR16 *WString\r
165 )\r
166/*++\r
167 Routine Description:\r
168\r
169 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().\r
170 The Unicode string will be converted to terminal expressible data stream\r
171 and send to terminal via serial port.\r
172\r
173\r
174 Arguments:\r
175\r
176 This - Indicates the calling context.\r
177\r
178 WString - The Null-terminated Unicode string to be displayed on\r
179 the terminal screen.\r
180\r
181 Returns:\r
182\r
183 EFI_SUCCESS\r
184 The string is output successfully.\r
185\r
186 EFI_DEVICE_ERROR\r
187 The serial port fails to send the string out.\r
188\r
189 EFI_WARN_UNKNOWN_GLYPH\r
190 Indicates that some of the characters in the Unicode string could not\r
191 be rendered and are skipped.\r
192\r
193 EFI_UNSUPPORTED\r
194\r
195--*/\r
196{\r
197 TERMINAL_DEV *TerminalDevice;\r
198 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
199 UINTN MaxColumn;\r
200 UINTN MaxRow;\r
201 UINTN Length;\r
202 UTF8_CHAR Utf8Char;\r
203 CHAR8 GraphicChar;\r
204 CHAR8 AsciiChar;\r
205 EFI_STATUS Status;\r
206 UINT8 ValidBytes;\r
207 //\r
208 // flag used to indicate whether condition happens which will cause\r
209 // return EFI_WARN_UNKNOWN_GLYPH\r
210 //\r
211 BOOLEAN Warning;\r
212\r
213 ValidBytes = 0;\r
214 Warning = FALSE;\r
215\r
216 //\r
217 // get Terminal device data structure pointer.\r
218 //\r
219 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
220\r
221 //\r
222 // Get current display mode\r
223 //\r
224 Mode = This->Mode;\r
225\r
226 if (Mode->Mode > 2) {\r
227 return EFI_UNSUPPORTED;\r
228 }\r
229\r
230 This->QueryMode (\r
231 This,\r
232 Mode->Mode,\r
233 &MaxColumn,\r
234 &MaxRow\r
235 );\r
236\r
237 for (; *WString != CHAR_NULL; WString++) {\r
238\r
239 switch (TerminalDevice->TerminalType) {\r
240\r
241 case PcAnsiType:\r
242 case VT100Type:\r
243 case VT100PlusType:\r
244\r
245 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {\r
246 //\r
247 // If it's not a graphic character convert Unicode to ASCII.\r
248 //\r
249 GraphicChar = (CHAR8) *WString;\r
250\r
251 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {\r
252 //\r
253 // when this driver use the OutputString to output control string,\r
254 // TerminalDevice->OutputEscChar is set to let the Esc char\r
255 // to be output to the terminal emulation software.\r
256 //\r
257 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {\r
258 GraphicChar = 27;\r
259 } else {\r
260 GraphicChar = '?';\r
261 Warning = TRUE;\r
262 }\r
263 }\r
264\r
265 AsciiChar = GraphicChar;\r
266\r
267 }\r
268\r
269 if (TerminalDevice->TerminalType != PcAnsiType) {\r
270 GraphicChar = AsciiChar;\r
271 }\r
272\r
273 Length = 1;\r
274\r
275 Status = TerminalDevice->SerialIo->Write (\r
276 TerminalDevice->SerialIo,\r
277 &Length,\r
278 &GraphicChar\r
279 );\r
280\r
281 if (EFI_ERROR (Status)) {\r
282 goto OutputError;\r
283 }\r
284\r
285 break;\r
286\r
287 case VTUTF8Type:\r
288 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);\r
289 Length = ValidBytes;\r
290 Status = TerminalDevice->SerialIo->Write (\r
291 TerminalDevice->SerialIo,\r
292 &Length,\r
293 (UINT8 *) &Utf8Char\r
294 );\r
295 if (EFI_ERROR (Status)) {\r
296 goto OutputError;\r
297 }\r
298 break;\r
299 }\r
300 //\r
301 // Update cursor position.\r
302 //\r
303 switch (*WString) {\r
304\r
305 case CHAR_BACKSPACE:\r
306 if (Mode->CursorColumn > 0) {\r
307 Mode->CursorColumn--;\r
308 }\r
309 break;\r
310\r
311 case CHAR_LINEFEED:\r
312 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
313 Mode->CursorRow++;\r
314 }\r
315 break;\r
316\r
317 case CHAR_CARRIAGE_RETURN:\r
318 Mode->CursorColumn = 0;\r
319 break;\r
320\r
321 default:\r
322 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {\r
323\r
324 Mode->CursorColumn++;\r
325\r
326 } else {\r
327\r
328 Mode->CursorColumn = 0;\r
329 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
330 Mode->CursorRow++;\r
331 }\r
332\r
333 }\r
334 break;\r
335\r
336 };\r
337\r
338 }\r
339\r
340 if (Warning) {\r
341 return EFI_WARN_UNKNOWN_GLYPH;\r
342 }\r
343\r
344 return EFI_SUCCESS;\r
345\r
346OutputError:\r
347 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
348 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
349 PcdGet32 (PcdStatusCodeValueRemoteConsoleOutputError),\r
350 TerminalDevice->DevicePath\r
351 );\r
352\r
353 return EFI_DEVICE_ERROR;\r
354}\r
355\r
356EFI_STATUS\r
357EFIAPI\r
358TerminalConOutTestString (\r
359 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
360 IN CHAR16 *WString\r
361 )\r
362/*++\r
363 Routine Description:\r
364\r
365 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().\r
366 If one of the characters in the *Wstring is\r
367 neither valid Unicode drawing characters,\r
368 not ASCII code, then this function will return\r
369 EFI_UNSUPPORTED.\r
370\r
371\r
372 Arguments:\r
373\r
374 This - Indicates the calling context.\r
375\r
376 WString - The Null-terminated Unicode string to be tested.\r
377\r
378 Returns:\r
379\r
380 EFI_SUCCESS\r
381 The terminal is capable of rendering the output string.\r
382\r
383 EFI_UNSUPPORTED\r
384 Some of the characters in the Unicode string cannot be rendered.\r
385\r
386--*/\r
387{\r
388 TERMINAL_DEV *TerminalDevice;\r
389 EFI_STATUS Status;\r
390\r
391 //\r
392 // get Terminal device data structure pointer.\r
393 //\r
394 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
395\r
396 switch (TerminalDevice->TerminalType) {\r
397\r
398 case PcAnsiType:\r
399 case VT100Type:\r
400 case VT100PlusType:\r
401 Status = AnsiTestString (TerminalDevice, WString);\r
402 break;\r
403\r
404 case VTUTF8Type:\r
405 Status = VTUTF8TestString (TerminalDevice, WString);\r
406 break;\r
407\r
408 default:\r
409 Status = EFI_UNSUPPORTED;\r
410 break;\r
411 }\r
412\r
413 return Status;\r
414}\r
415\r
416EFI_STATUS\r
417EFIAPI\r
418TerminalConOutQueryMode (\r
419 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
420 IN UINTN ModeNumber,\r
421 OUT UINTN *Columns,\r
422 OUT UINTN *Rows\r
423 )\r
424/*++\r
425 Routine Description:\r
426\r
427 Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.QueryMode().\r
428 It returns information for an available text mode\r
429 that the terminal supports.\r
430 In this driver, we support text mode 80x25 (mode 0),\r
431 80x50 (mode 1), 100x31 (mode 2).\r
432\r
433\r
434 Arguments:\r
435\r
436 *This\r
437 Indicates the calling context.\r
438\r
439 ModeNumber\r
440 The mode number to return information on.\r
441\r
442 Columns\r
443 The returned columns of the requested mode.\r
444\r
445 Rows\r
446 The returned rows of the requested mode.\r
447\r
448 Returns:\r
449\r
450 EFI_SUCCESS\r
451 The requested mode information is returned.\r
452\r
453 EFI_UNSUPPORTED\r
454 The mode number is not valid.\r
455\r
456 EFI_DEVICE_ERROR\r
457\r
458--*/\r
459{\r
460 if (This->Mode->MaxMode > 3) {\r
461 return EFI_DEVICE_ERROR;\r
462 }\r
463\r
464 if (ModeNumber == 0) {\r
465 *Columns = MODE0_COLUMN_COUNT;\r
466 *Rows = MODE0_ROW_COUNT;\r
467 return EFI_SUCCESS;\r
468 } else if (ModeNumber == 1) {\r
469 *Columns = MODE1_COLUMN_COUNT;\r
470 *Rows = MODE1_ROW_COUNT;\r
471 return EFI_SUCCESS;\r
472 } else if (ModeNumber == 2) {\r
473 *Columns = MODE2_COLUMN_COUNT;\r
474 *Rows = MODE2_ROW_COUNT;\r
475 return EFI_SUCCESS;\r
476 }\r
477\r
478 return EFI_UNSUPPORTED;\r
479}\r
480\r
481EFI_STATUS\r
482EFIAPI\r
483TerminalConOutSetMode (\r
484 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
485 IN UINTN ModeNumber\r
486 )\r
487/*++\r
488 Routine Description:\r
489\r
490 Implements EFI_SIMPLE_TEXT_OUT.SetMode().\r
491 Set the terminal to a specified display mode.\r
492 In this driver, we only support mode 0.\r
493\r
494 Arguments:\r
495\r
496 This\r
497 Indicates the calling context.\r
498\r
499 ModeNumber\r
500 The text mode to set.\r
501\r
502 Returns:\r
503\r
504 EFI_SUCCESS\r
505 The requested text mode is set.\r
506\r
507 EFI_DEVICE_ERROR\r
508 The requested text mode cannot be set because of serial device error.\r
509\r
510 EFI_UNSUPPORTED\r
511 The text mode number is not valid.\r
512\r
513--*/\r
514{\r
515 EFI_STATUS Status;\r
516 TERMINAL_DEV *TerminalDevice;\r
517\r
518 //\r
519 // get Terminal device data structure pointer.\r
520 //\r
521 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
522\r
523 if (ModeNumber > 2) {\r
524 return EFI_UNSUPPORTED;\r
525 }\r
526\r
527 //\r
528 // Set the current mode\r
529 //\r
530 This->Mode->Mode = (INT32) ModeNumber;\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 = (INT32) ModeNumber;\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_OUTPUT_PROTOCOL *This,\r
557 IN UINTN Attribute\r
558 )\r
559/*++\r
560 Routine Description:\r
561\r
562 Implements EFI_SIMPLE_TEXT_OUTPUT_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_OUTPUT_PROTOCOL *This\r
734 )\r
735/*++\r
736 Routine Description:\r
737\r
738 Implements EFI_SIMPLE_TEXT_OUTPUT_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_OUTPUT_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_OUTPUT_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_OUTPUT_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