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