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