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