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