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