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