]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
Refine the validation for the input attribute before return.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConOut.c
CommitLineData
fb0b259e 1/** @file\r
2 Implementation for EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL protocol.\r
95276127 3\r
e5eed7d3
HT
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
fb0b259e 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
95276127 9\r
fb0b259e 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
95276127 12\r
fb0b259e 13**/\r
95276127 14\r
95276127 15#include "Terminal.h"\r
16\r
95276127 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
fe1e36e5 23UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {\r
fb0b259e 24 { BOXDRAW_HORIZONTAL, 0xc4, L'-' },\r
95276127 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
ab76200c 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
95276127 77\r
78 { 0x0000, 0x00, L'\0' }\r
79};\r
80\r
fe1e36e5 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
95276127 85\r
86//\r
87// Body of the ConOut functions\r
88//\r
e49ef433 89\r
90/**\r
91 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().\r
ab76200c 92\r
e49ef433 93 If ExtendeVerification is TRUE, then perform dependent serial device reset,\r
94 and set display mode to mode 0.\r
95 If ExtendedVerification is FALSE, only set display mode to mode 0.\r
96\r
97 @param This Indicates the calling context.\r
98 @param ExtendedVerification Indicates that the driver may perform a more\r
99 exhaustive verification operation of the device\r
100 during reset.\r
101\r
00bfdbe1 102 @retval EFI_SUCCESS The reset operation succeeds.\r
103 @retval EFI_DEVICE_ERROR The terminal is not functioning correctly or the serial port reset fails.\r
e49ef433 104\r
105**/\r
95276127 106EFI_STATUS\r
107EFIAPI\r
108TerminalConOutReset (\r
109 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
110 IN BOOLEAN ExtendedVerification\r
111 )\r
95276127 112{\r
113 EFI_STATUS Status;\r
114 TERMINAL_DEV *TerminalDevice;\r
115\r
116 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
117\r
118 //\r
119 // Perform a more exhaustive reset by resetting the serial port.\r
120 //\r
121 if (ExtendedVerification) {\r
122 //\r
123 // Report progress code here\r
124 //\r
125 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
126 EFI_PROGRESS_CODE,\r
f9876ecf 127 (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),\r
95276127 128 TerminalDevice->DevicePath\r
129 );\r
130\r
131 Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);\r
132 if (EFI_ERROR (Status)) {\r
133 //\r
134 // Report error code here\r
135 //\r
136 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
137 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
f9876ecf 138 (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),\r
95276127 139 TerminalDevice->DevicePath\r
140 );\r
141\r
142 return Status;\r
143 }\r
144 }\r
145\r
0ce1dd70 146 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));\r
95276127 147\r
148 Status = This->SetMode (This, 0);\r
149\r
150 return Status;\r
151}\r
152\r
e49ef433 153\r
154/**\r
155 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().\r
ab76200c 156\r
e49ef433 157 The Unicode string will be converted to terminal expressible data stream\r
158 and send to terminal via serial port.\r
159\r
160 @param This Indicates the calling context.\r
161 @param WString The Null-terminated Unicode string to be displayed\r
162 on the terminal screen.\r
163\r
8fd98315 164 @retval EFI_SUCCESS The string is output successfully.\r
165 @retval EFI_DEVICE_ERROR The serial port fails to send the string out.\r
166 @retval EFI_WARN_UNKNOWN_GLYPH Indicates that some of the characters in the Unicode string could not\r
e49ef433 167 be rendered and are skipped.\r
8fd98315 168 @retval EFI_UNSUPPORTED If current display mode is out of range.\r
e49ef433 169\r
170**/\r
95276127 171EFI_STATUS\r
172EFIAPI\r
173TerminalConOutOutputString (\r
174 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
175 IN CHAR16 *WString\r
176 )\r
95276127 177{\r
178 TERMINAL_DEV *TerminalDevice;\r
179 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
180 UINTN MaxColumn;\r
181 UINTN MaxRow;\r
182 UINTN Length;\r
183 UTF8_CHAR Utf8Char;\r
184 CHAR8 GraphicChar;\r
c97b5672 185 CHAR8 AsciiChar;\r
95276127 186 EFI_STATUS Status;\r
187 UINT8 ValidBytes;\r
188 //\r
189 // flag used to indicate whether condition happens which will cause\r
190 // return EFI_WARN_UNKNOWN_GLYPH\r
191 //\r
192 BOOLEAN Warning;\r
193\r
194 ValidBytes = 0;\r
195 Warning = FALSE;\r
c97b5672 196 AsciiChar = 0;\r
95276127 197\r
198 //\r
199 // get Terminal device data structure pointer.\r
200 //\r
201 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
202\r
203 //\r
3012ce5c 204 // Get current display mode\r
95276127 205 //\r
206 Mode = This->Mode;\r
fb0b259e 207\r
79d07c66 208 if (Mode->Mode >= Mode->MaxMode) {\r
95276127 209 return EFI_UNSUPPORTED;\r
210 }\r
211\r
212 This->QueryMode (\r
213 This,\r
214 Mode->Mode,\r
215 &MaxColumn,\r
216 &MaxRow\r
217 );\r
218\r
219 for (; *WString != CHAR_NULL; WString++) {\r
220\r
221 switch (TerminalDevice->TerminalType) {\r
222\r
e49ef433 223 case PCANSITYPE:\r
224 case VT100TYPE:\r
225 case VT100PLUSTYPE:\r
95276127 226\r
227 if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {\r
228 //\r
229 // If it's not a graphic character convert Unicode to ASCII.\r
230 //\r
231 GraphicChar = (CHAR8) *WString;\r
232\r
233 if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {\r
234 //\r
235 // when this driver use the OutputString to output control string,\r
236 // TerminalDevice->OutputEscChar is set to let the Esc char\r
237 // to be output to the terminal emulation software.\r
238 //\r
239 if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {\r
240 GraphicChar = 27;\r
241 } else {\r
242 GraphicChar = '?';\r
243 Warning = TRUE;\r
244 }\r
245 }\r
246\r
247 AsciiChar = GraphicChar;\r
248\r
249 }\r
250\r
e49ef433 251 if (TerminalDevice->TerminalType != PCANSITYPE) {\r
95276127 252 GraphicChar = AsciiChar;\r
253 }\r
254\r
255 Length = 1;\r
256\r
257 Status = TerminalDevice->SerialIo->Write (\r
258 TerminalDevice->SerialIo,\r
259 &Length,\r
260 &GraphicChar\r
261 );\r
262\r
263 if (EFI_ERROR (Status)) {\r
264 goto OutputError;\r
265 }\r
266\r
267 break;\r
268\r
e49ef433 269 case VTUTF8TYPE:\r
95276127 270 UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);\r
271 Length = ValidBytes;\r
272 Status = TerminalDevice->SerialIo->Write (\r
273 TerminalDevice->SerialIo,\r
274 &Length,\r
275 (UINT8 *) &Utf8Char\r
276 );\r
277 if (EFI_ERROR (Status)) {\r
278 goto OutputError;\r
279 }\r
280 break;\r
281 }\r
282 //\r
283 // Update cursor position.\r
284 //\r
285 switch (*WString) {\r
286\r
287 case CHAR_BACKSPACE:\r
288 if (Mode->CursorColumn > 0) {\r
289 Mode->CursorColumn--;\r
290 }\r
291 break;\r
292\r
293 case CHAR_LINEFEED:\r
294 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
295 Mode->CursorRow++;\r
296 }\r
297 break;\r
298\r
299 case CHAR_CARRIAGE_RETURN:\r
300 Mode->CursorColumn = 0;\r
301 break;\r
302\r
303 default:\r
304 if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {\r
305\r
306 Mode->CursorColumn++;\r
307\r
308 } else {\r
309\r
310 Mode->CursorColumn = 0;\r
311 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
312 Mode->CursorRow++;\r
313 }\r
314\r
315 }\r
316 break;\r
317\r
318 };\r
319\r
320 }\r
321\r
322 if (Warning) {\r
323 return EFI_WARN_UNKNOWN_GLYPH;\r
324 }\r
325\r
326 return EFI_SUCCESS;\r
327\r
328OutputError:\r
329 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
330 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
f9876ecf 331 (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR),\r
95276127 332 TerminalDevice->DevicePath\r
333 );\r
334\r
335 return EFI_DEVICE_ERROR;\r
336}\r
337\r
e49ef433 338\r
339/**\r
340 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().\r
ab76200c 341\r
e49ef433 342 If one of the characters in the *Wstring is\r
343 neither valid Unicode drawing characters,\r
344 not ASCII code, then this function will return\r
345 EFI_UNSUPPORTED.\r
346\r
347 @param This Indicates the calling context.\r
348 @param WString The Null-terminated Unicode string to be tested.\r
349\r
00bfdbe1 350 @retval EFI_SUCCESS The terminal is capable of rendering the output string.\r
351 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be rendered.\r
e49ef433 352\r
353**/\r
95276127 354EFI_STATUS\r
355EFIAPI\r
356TerminalConOutTestString (\r
357 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
358 IN CHAR16 *WString\r
359 )\r
95276127 360{\r
361 TERMINAL_DEV *TerminalDevice;\r
362 EFI_STATUS Status;\r
363\r
364 //\r
365 // get Terminal device data structure pointer.\r
366 //\r
367 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
368\r
369 switch (TerminalDevice->TerminalType) {\r
370\r
e49ef433 371 case PCANSITYPE:\r
372 case VT100TYPE:\r
373 case VT100PLUSTYPE:\r
95276127 374 Status = AnsiTestString (TerminalDevice, WString);\r
375 break;\r
376\r
e49ef433 377 case VTUTF8TYPE:\r
95276127 378 Status = VTUTF8TestString (TerminalDevice, WString);\r
379 break;\r
380\r
381 default:\r
382 Status = EFI_UNSUPPORTED;\r
383 break;\r
384 }\r
385\r
386 return Status;\r
387}\r
388\r
e49ef433 389\r
390/**\r
391 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().\r
ab76200c 392\r
e49ef433 393 It returns information for an available text mode\r
394 that the terminal supports.\r
e49ef433 395\r
396 @param This Indicates the calling context.\r
397 @param ModeNumber The mode number to return information on.\r
398 @param Columns The returned columns of the requested mode.\r
399 @param Rows The returned rows of the requested mode.\r
400\r
00bfdbe1 401 @retval EFI_SUCCESS The requested mode information is returned.\r
402 @retval EFI_UNSUPPORTED The mode number is not valid.\r
e49ef433 403\r
404**/\r
95276127 405EFI_STATUS\r
406EFIAPI\r
407TerminalConOutQueryMode (\r
408 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
409 IN UINTN ModeNumber,\r
410 OUT UINTN *Columns,\r
411 OUT UINTN *Rows\r
412 )\r
95276127 413{\r
79d07c66 414 TERMINAL_DEV *TerminalDevice;\r
95276127 415\r
79d07c66 416 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
417 return EFI_UNSUPPORTED;\r
95276127 418 }\r
419\r
79d07c66 420 //\r
421 // Get Terminal device data structure pointer.\r
422 //\r
423 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This); \r
424 *Columns = TerminalDevice->TerminalConsoleModeData[ModeNumber].Columns;\r
425 *Rows = TerminalDevice->TerminalConsoleModeData[ModeNumber].Rows;\r
426\r
427 return EFI_SUCCESS;\r
95276127 428}\r
429\r
e49ef433 430\r
431/**\r
432 Implements EFI_SIMPLE_TEXT_OUT.SetMode().\r
ab76200c 433\r
e49ef433 434 Set the terminal to a specified display mode.\r
435 In this driver, we only support mode 0.\r
436\r
437 @param This Indicates the calling context.\r
438 @param ModeNumber The text mode to set.\r
439\r
00bfdbe1 440 @retval EFI_SUCCESS The requested text mode is set.\r
441 @retval EFI_DEVICE_ERROR The requested text mode cannot be set \r
e49ef433 442 because of serial device error.\r
00bfdbe1 443 @retval EFI_UNSUPPORTED The text mode number is not valid.\r
e49ef433 444\r
445**/\r
95276127 446EFI_STATUS\r
447EFIAPI\r
448TerminalConOutSetMode (\r
449 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
450 IN UINTN ModeNumber\r
451 )\r
95276127 452{\r
453 EFI_STATUS Status;\r
454 TERMINAL_DEV *TerminalDevice;\r
455\r
456 //\r
457 // get Terminal device data structure pointer.\r
458 //\r
459 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
460\r
79d07c66 461 if (ModeNumber >= (UINTN) This->Mode->MaxMode) {\r
95276127 462 return EFI_UNSUPPORTED;\r
463 }\r
fb0b259e 464\r
3012ce5c 465 //\r
466 // Set the current mode\r
467 //\r
468 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 469\r
470 This->ClearScreen (This);\r
471\r
472 TerminalDevice->OutputEscChar = TRUE;\r
473 Status = This->OutputString (This, mSetModeString);\r
474 TerminalDevice->OutputEscChar = FALSE;\r
475\r
476 if (EFI_ERROR (Status)) {\r
477 return EFI_DEVICE_ERROR;\r
478 }\r
479\r
3012ce5c 480 This->Mode->Mode = (INT32) ModeNumber;\r
95276127 481\r
482 Status = This->ClearScreen (This);\r
483 if (EFI_ERROR (Status)) {\r
484 return EFI_DEVICE_ERROR;\r
485 }\r
486\r
487 return EFI_SUCCESS;\r
488\r
489}\r
490\r
e49ef433 491\r
492/**\r
493 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().\r
494\r
495 @param This Indicates the calling context.\r
496 @param Attribute The attribute to set. Only bit0..6 are valid, all other bits\r
497 are undefined and must be zero.\r
498\r
00bfdbe1 499 @retval EFI_SUCCESS The requested attribute is set.\r
500 @retval EFI_DEVICE_ERROR The requested attribute cannot be set due to serial port error.\r
501 @retval EFI_UNSUPPORTED The attribute requested is not defined by EFI spec.\r
e49ef433 502\r
503**/\r
95276127 504EFI_STATUS\r
505EFIAPI\r
506TerminalConOutSetAttribute (\r
507 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
508 IN UINTN Attribute\r
509 )\r
95276127 510{\r
511 UINT8 ForegroundControl;\r
512 UINT8 BackgroundControl;\r
513 UINT8 BrightControl;\r
514 INT32 SavedColumn;\r
515 INT32 SavedRow;\r
516 EFI_STATUS Status;\r
517 TERMINAL_DEV *TerminalDevice;\r
518\r
519 SavedColumn = 0;\r
520 SavedRow = 0;\r
521\r
522 //\r
523 // get Terminal device data structure pointer.\r
524 //\r
525 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
526\r
527 //\r
528 // only the bit0..6 of the Attribute is valid\r
529 //\r
530 if ((Attribute | 0x7f) != 0x7f) {\r
531 return EFI_UNSUPPORTED;\r
532 }\r
0ce1dd70 533\r
534 //\r
535 // Skip outputting the command string for the same attribute\r
11baadb6 536 // It improves the terminal performance significantly\r
0ce1dd70 537 //\r
538 if (This->Mode->Attribute == (INT32) Attribute) {\r
539 return EFI_SUCCESS;\r
540 }\r
541\r
95276127 542 //\r
543 // convert Attribute value to terminal emulator\r
544 // understandable foreground color\r
545 //\r
546 switch (Attribute & 0x07) {\r
547\r
548 case EFI_BLACK:\r
549 ForegroundControl = 30;\r
550 break;\r
551\r
552 case EFI_BLUE:\r
553 ForegroundControl = 34;\r
554 break;\r
555\r
556 case EFI_GREEN:\r
557 ForegroundControl = 32;\r
558 break;\r
559\r
560 case EFI_CYAN:\r
561 ForegroundControl = 36;\r
562 break;\r
563\r
564 case EFI_RED:\r
565 ForegroundControl = 31;\r
566 break;\r
567\r
568 case EFI_MAGENTA:\r
569 ForegroundControl = 35;\r
570 break;\r
571\r
572 case EFI_BROWN:\r
573 ForegroundControl = 33;\r
574 break;\r
575\r
576 default:\r
577\r
578 case EFI_LIGHTGRAY:\r
579 ForegroundControl = 37;\r
580 break;\r
581\r
582 }\r
583 //\r
584 // bit4 of the Attribute indicates bright control\r
585 // of terminal emulator.\r
586 //\r
587 BrightControl = (UINT8) ((Attribute >> 3) & 1);\r
588\r
589 //\r
590 // convert Attribute value to terminal emulator\r
591 // understandable background color.\r
592 //\r
593 switch ((Attribute >> 4) & 0x07) {\r
594\r
595 case EFI_BLACK:\r
596 BackgroundControl = 40;\r
597 break;\r
598\r
599 case EFI_BLUE:\r
600 BackgroundControl = 44;\r
601 break;\r
602\r
603 case EFI_GREEN:\r
604 BackgroundControl = 42;\r
605 break;\r
606\r
607 case EFI_CYAN:\r
608 BackgroundControl = 46;\r
609 break;\r
610\r
611 case EFI_RED:\r
612 BackgroundControl = 41;\r
613 break;\r
614\r
615 case EFI_MAGENTA:\r
616 BackgroundControl = 45;\r
617 break;\r
618\r
619 case EFI_BROWN:\r
620 BackgroundControl = 43;\r
621 break;\r
622\r
623 default:\r
624\r
625 case EFI_LIGHTGRAY:\r
626 BackgroundControl = 47;\r
627 break;\r
628 }\r
629 //\r
630 // terminal emulator's control sequence to set attributes\r
631 //\r
632 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);\r
633 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));\r
634 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));\r
635 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));\r
636 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));\r
637\r
638 //\r
639 // save current column and row\r
640 // for future scrolling back use.\r
641 //\r
642 SavedColumn = This->Mode->CursorColumn;\r
643 SavedRow = This->Mode->CursorRow;\r
644\r
645 TerminalDevice->OutputEscChar = TRUE;\r
646 Status = This->OutputString (This, mSetAttributeString);\r
647 TerminalDevice->OutputEscChar = FALSE;\r
648\r
649 if (EFI_ERROR (Status)) {\r
650 return EFI_DEVICE_ERROR;\r
651 }\r
652 //\r
653 // scroll back to saved cursor position.\r
654 //\r
655 This->Mode->CursorColumn = SavedColumn;\r
656 This->Mode->CursorRow = SavedRow;\r
657\r
658 This->Mode->Attribute = (INT32) Attribute;\r
659\r
660 return EFI_SUCCESS;\r
661\r
662}\r
663\r
e49ef433 664\r
665/**\r
666 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().\r
667 It clears the ANSI terminal's display to the\r
668 currently selected background color.\r
669\r
670 @param This Indicates the calling context.\r
671\r
00bfdbe1 672 @retval EFI_SUCCESS The operation completed successfully.\r
673 @retval EFI_DEVICE_ERROR The terminal screen cannot be cleared due to serial port error.\r
674 @retval EFI_UNSUPPORTED The terminal is not in a valid display mode.\r
e49ef433 675\r
676**/\r
95276127 677EFI_STATUS\r
678EFIAPI\r
679TerminalConOutClearScreen (\r
680 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
681 )\r
95276127 682{\r
683 EFI_STATUS Status;\r
684 TERMINAL_DEV *TerminalDevice;\r
685\r
686 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
687\r
688 //\r
689 // control sequence for clear screen request\r
690 //\r
691 TerminalDevice->OutputEscChar = TRUE;\r
692 Status = This->OutputString (This, mClearScreenString);\r
693 TerminalDevice->OutputEscChar = FALSE;\r
694\r
695 if (EFI_ERROR (Status)) {\r
696 return EFI_DEVICE_ERROR;\r
697 }\r
698\r
699 Status = This->SetCursorPosition (This, 0, 0);\r
700\r
701 return Status;\r
702}\r
703\r
e49ef433 704\r
705/**\r
706 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().\r
707\r
708 @param This Indicates the calling context.\r
709 @param Column The row to set cursor to.\r
710 @param Row The column to set cursor to.\r
711\r
00bfdbe1 712 @retval EFI_SUCCESS The operation completed successfully.\r
713 @retval EFI_DEVICE_ERROR The request fails due to serial port error.\r
714 @retval EFI_UNSUPPORTED The terminal is not in a valid text mode, or the cursor position\r
e49ef433 715 is invalid for current mode.\r
716\r
717**/\r
95276127 718EFI_STATUS\r
719EFIAPI\r
720TerminalConOutSetCursorPosition (\r
721 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
722 IN UINTN Column,\r
723 IN UINTN Row\r
724 )\r
95276127 725{\r
726 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
727 UINTN MaxColumn;\r
728 UINTN MaxRow;\r
729 EFI_STATUS Status;\r
730 TERMINAL_DEV *TerminalDevice;\r
731\r
732 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
733\r
734 //\r
735 // get current mode\r
736 //\r
737 Mode = This->Mode;\r
738\r
739 //\r
740 // get geometry of current mode\r
741 //\r
742 Status = This->QueryMode (\r
743 This,\r
744 Mode->Mode,\r
745 &MaxColumn,\r
746 &MaxRow\r
747 );\r
748 if (EFI_ERROR (Status)) {\r
749 return EFI_UNSUPPORTED;\r
750 }\r
751\r
752 if (Column >= MaxColumn || Row >= MaxRow) {\r
753 return EFI_UNSUPPORTED;\r
754 }\r
755 //\r
756 // control sequence to move the cursor\r
757 //\r
758 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));\r
759 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));\r
760 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));\r
761 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));\r
762\r
763 TerminalDevice->OutputEscChar = TRUE;\r
764 Status = This->OutputString (This, mSetCursorPositionString);\r
765 TerminalDevice->OutputEscChar = FALSE;\r
766\r
767 if (EFI_ERROR (Status)) {\r
768 return EFI_DEVICE_ERROR;\r
769 }\r
770 //\r
771 // update current cursor position\r
772 // in the Mode data structure.\r
773 //\r
774 Mode->CursorColumn = (INT32) Column;\r
775 Mode->CursorRow = (INT32) Row;\r
776\r
777 return EFI_SUCCESS;\r
778}\r
779\r
e49ef433 780\r
781/**\r
782 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
ab76200c 783\r
e49ef433 784 In this driver, the cursor cannot be hidden.\r
785\r
786 @param This Indicates the calling context.\r
787 @param Visible If TRUE, the cursor is set to be visible,\r
788 If FALSE, the cursor is set to be invisible.\r
789\r
00bfdbe1 790 @retval EFI_SUCCESS The request is valid.\r
791 @retval EFI_UNSUPPORTED The terminal does not support cursor hidden.\r
e49ef433 792\r
793**/\r
95276127 794EFI_STATUS\r
795EFIAPI\r
796TerminalConOutEnableCursor (\r
797 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
798 IN BOOLEAN Visible\r
799 )\r
95276127 800{\r
801 if (!Visible) {\r
802 return EFI_UNSUPPORTED;\r
803 }\r
804\r
805 return EFI_SUCCESS;\r
806}\r
807\r
e49ef433 808\r
809/**\r
810 Detects if a Unicode char is for Box Drawing text graphics.\r
811\r
812 @param Graphic Unicode char to test.\r
813 @param PcAnsi Optional pointer to return PCANSI equivalent of\r
814 Graphic.\r
815 @param Ascii Optional pointer to return ASCII equivalent of\r
816 Graphic.\r
817\r
00bfdbe1 818 @retval TRUE If Graphic is a supported Unicode Box Drawing character.\r
e49ef433 819\r
820**/\r
95276127 821BOOLEAN\r
822TerminalIsValidTextGraphics (\r
823 IN CHAR16 Graphic,\r
824 OUT CHAR8 *PcAnsi, OPTIONAL\r
825 OUT CHAR8 *Ascii OPTIONAL\r
826 )\r
95276127 827{\r
828 UNICODE_TO_CHAR *Table;\r
829\r
830 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {\r
831 //\r
832 // Unicode drawing code charts are all in the 0x25xx range,\r
833 // arrows are 0x21xx\r
834 //\r
835 return FALSE;\r
836 }\r
837\r
838 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {\r
839 if (Graphic == Table->Unicode) {\r
840 if (PcAnsi != NULL) {\r
841 *PcAnsi = Table->PcAnsi;\r
842 }\r
843\r
844 if (Ascii != NULL) {\r
845 *Ascii = Table->Ascii;\r
846 }\r
847\r
848 return TRUE;\r
849 }\r
850 }\r
851\r
852 return FALSE;\r
853}\r
854\r
8fd98315 855/**\r
856 Detects if a valid ASCII char.\r
857\r
858 @param Ascii An ASCII character.\r
859 \r
860 @retval TRUE If it is a valid ASCII character.\r
861 @retval FALSE If it is not a valid ASCII character.\r
862\r
863**/\r
95276127 864BOOLEAN\r
865TerminalIsValidAscii (\r
866 IN CHAR16 Ascii\r
867 )\r
868{\r
869 //\r
870 // valid ascii code lies in the extent of 0x20 ~ 0x7f\r
871 //\r
872 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {\r
873 return TRUE;\r
874 }\r
875\r
876 return FALSE;\r
877}\r
878\r
8fd98315 879/**\r
880 Detects if a valid EFI control character.\r
881\r
882 @param CharC An input EFI Control character.\r
883 \r
884 @retval TRUE If it is a valid EFI control character.\r
885 @retval FALSE If it is not a valid EFI control character.\r
886\r
887**/\r
95276127 888BOOLEAN\r
889TerminalIsValidEfiCntlChar (\r
890 IN CHAR16 CharC\r
891 )\r
892{\r
893 //\r
894 // only support four control characters.\r
895 //\r
896 if (CharC == CHAR_NULL ||\r
897 CharC == CHAR_BACKSPACE ||\r
898 CharC == CHAR_LINEFEED ||\r
899 CharC == CHAR_CARRIAGE_RETURN ||\r
900 CharC == CHAR_TAB\r
901 ) {\r
902 return TRUE;\r
903 }\r
904\r
905 return FALSE;\r
906}\r