]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
provide a temporary method to generate SecMain executable file.
[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
0ce1dd70 153 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));\r
95276127 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
0ce1dd70 608\r
609 //\r
610 // Skip outputting the command string for the same attribute\r
611 // It improves the terminal performance siginificantly\r
612 //\r
613 if (This->Mode->Attribute == (INT32) Attribute) {\r
614 return EFI_SUCCESS;\r
615 }\r
616\r
95276127 617 //\r
618 // convert Attribute value to terminal emulator\r
619 // understandable foreground color\r
620 //\r
621 switch (Attribute & 0x07) {\r
622\r
623 case EFI_BLACK:\r
624 ForegroundControl = 30;\r
625 break;\r
626\r
627 case EFI_BLUE:\r
628 ForegroundControl = 34;\r
629 break;\r
630\r
631 case EFI_GREEN:\r
632 ForegroundControl = 32;\r
633 break;\r
634\r
635 case EFI_CYAN:\r
636 ForegroundControl = 36;\r
637 break;\r
638\r
639 case EFI_RED:\r
640 ForegroundControl = 31;\r
641 break;\r
642\r
643 case EFI_MAGENTA:\r
644 ForegroundControl = 35;\r
645 break;\r
646\r
647 case EFI_BROWN:\r
648 ForegroundControl = 33;\r
649 break;\r
650\r
651 default:\r
652\r
653 case EFI_LIGHTGRAY:\r
654 ForegroundControl = 37;\r
655 break;\r
656\r
657 }\r
658 //\r
659 // bit4 of the Attribute indicates bright control\r
660 // of terminal emulator.\r
661 //\r
662 BrightControl = (UINT8) ((Attribute >> 3) & 1);\r
663\r
664 //\r
665 // convert Attribute value to terminal emulator\r
666 // understandable background color.\r
667 //\r
668 switch ((Attribute >> 4) & 0x07) {\r
669\r
670 case EFI_BLACK:\r
671 BackgroundControl = 40;\r
672 break;\r
673\r
674 case EFI_BLUE:\r
675 BackgroundControl = 44;\r
676 break;\r
677\r
678 case EFI_GREEN:\r
679 BackgroundControl = 42;\r
680 break;\r
681\r
682 case EFI_CYAN:\r
683 BackgroundControl = 46;\r
684 break;\r
685\r
686 case EFI_RED:\r
687 BackgroundControl = 41;\r
688 break;\r
689\r
690 case EFI_MAGENTA:\r
691 BackgroundControl = 45;\r
692 break;\r
693\r
694 case EFI_BROWN:\r
695 BackgroundControl = 43;\r
696 break;\r
697\r
698 default:\r
699\r
700 case EFI_LIGHTGRAY:\r
701 BackgroundControl = 47;\r
702 break;\r
703 }\r
704 //\r
705 // terminal emulator's control sequence to set attributes\r
706 //\r
707 mSetAttributeString[BRIGHT_CONTROL_OFFSET] = (CHAR16) ('0' + BrightControl);\r
708 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (ForegroundControl / 10));\r
709 mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (ForegroundControl % 10));\r
710 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16) ('0' + (BackgroundControl / 10));\r
711 mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16) ('0' + (BackgroundControl % 10));\r
712\r
713 //\r
714 // save current column and row\r
715 // for future scrolling back use.\r
716 //\r
717 SavedColumn = This->Mode->CursorColumn;\r
718 SavedRow = This->Mode->CursorRow;\r
719\r
720 TerminalDevice->OutputEscChar = TRUE;\r
721 Status = This->OutputString (This, mSetAttributeString);\r
722 TerminalDevice->OutputEscChar = FALSE;\r
723\r
724 if (EFI_ERROR (Status)) {\r
725 return EFI_DEVICE_ERROR;\r
726 }\r
727 //\r
728 // scroll back to saved cursor position.\r
729 //\r
730 This->Mode->CursorColumn = SavedColumn;\r
731 This->Mode->CursorRow = SavedRow;\r
732\r
733 This->Mode->Attribute = (INT32) Attribute;\r
734\r
735 return EFI_SUCCESS;\r
736\r
737}\r
738\r
739EFI_STATUS\r
740EFIAPI\r
741TerminalConOutClearScreen (\r
742 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
743 )\r
744/*++\r
745 Routine Description:\r
fb0b259e 746\r
95276127 747 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().\r
fb0b259e 748 It clears the ANSI terminal's display to the\r
95276127 749 currently selected background color.\r
fb0b259e 750\r
751\r
95276127 752 Arguments:\r
fb0b259e 753\r
95276127 754 This\r
755 Indicates the calling context.\r
756\r
757 Returns:\r
fb0b259e 758\r
95276127 759 EFI_SUCCESS\r
760 The operation completed successfully.\r
fb0b259e 761\r
95276127 762 EFI_DEVICE_ERROR\r
fb0b259e 763 The terminal screen cannot be cleared due to serial port error.\r
764\r
95276127 765 EFI_UNSUPPORTED\r
fb0b259e 766 The terminal is not in a valid display mode.\r
767\r
95276127 768--*/\r
769{\r
770 EFI_STATUS Status;\r
771 TERMINAL_DEV *TerminalDevice;\r
772\r
773 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
774\r
775 //\r
776 // control sequence for clear screen request\r
777 //\r
778 TerminalDevice->OutputEscChar = TRUE;\r
779 Status = This->OutputString (This, mClearScreenString);\r
780 TerminalDevice->OutputEscChar = FALSE;\r
781\r
782 if (EFI_ERROR (Status)) {\r
783 return EFI_DEVICE_ERROR;\r
784 }\r
785\r
786 Status = This->SetCursorPosition (This, 0, 0);\r
787\r
788 return Status;\r
789}\r
790\r
791EFI_STATUS\r
792EFIAPI\r
793TerminalConOutSetCursorPosition (\r
794 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
795 IN UINTN Column,\r
796 IN UINTN Row\r
797 )\r
798/*++\r
799 Routine Description:\r
fb0b259e 800\r
801 Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().\r
802\r
95276127 803 Arguments:\r
fb0b259e 804\r
95276127 805 This\r
806 Indicates the calling context.\r
fb0b259e 807\r
95276127 808 Column\r
809 The row to set cursor to.\r
fb0b259e 810\r
95276127 811 Row\r
fb0b259e 812 The column to set cursor to.\r
95276127 813\r
814 Returns:\r
fb0b259e 815\r
95276127 816 EFI_SUCCESS\r
817 The operation completed successfully.\r
fb0b259e 818\r
95276127 819 EFI_DEVICE_ERROR\r
fb0b259e 820 The request fails due to serial port error.\r
821\r
95276127 822 EFI_UNSUPPORTED\r
823 The terminal is not in a valid text mode, or the cursor position\r
fb0b259e 824 is invalid for current mode.\r
825\r
95276127 826--*/\r
827{\r
828 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
829 UINTN MaxColumn;\r
830 UINTN MaxRow;\r
831 EFI_STATUS Status;\r
832 TERMINAL_DEV *TerminalDevice;\r
833\r
834 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);\r
835\r
836 //\r
837 // get current mode\r
838 //\r
839 Mode = This->Mode;\r
840\r
841 //\r
842 // get geometry of current mode\r
843 //\r
844 Status = This->QueryMode (\r
845 This,\r
846 Mode->Mode,\r
847 &MaxColumn,\r
848 &MaxRow\r
849 );\r
850 if (EFI_ERROR (Status)) {\r
851 return EFI_UNSUPPORTED;\r
852 }\r
853\r
854 if (Column >= MaxColumn || Row >= MaxRow) {\r
855 return EFI_UNSUPPORTED;\r
856 }\r
857 //\r
858 // control sequence to move the cursor\r
859 //\r
860 mSetCursorPositionString[ROW_OFFSET + 0] = (CHAR16) ('0' + ((Row + 1) / 10));\r
861 mSetCursorPositionString[ROW_OFFSET + 1] = (CHAR16) ('0' + ((Row + 1) % 10));\r
862 mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));\r
863 mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));\r
864\r
865 TerminalDevice->OutputEscChar = TRUE;\r
866 Status = This->OutputString (This, mSetCursorPositionString);\r
867 TerminalDevice->OutputEscChar = FALSE;\r
868\r
869 if (EFI_ERROR (Status)) {\r
870 return EFI_DEVICE_ERROR;\r
871 }\r
872 //\r
873 // update current cursor position\r
874 // in the Mode data structure.\r
875 //\r
876 Mode->CursorColumn = (INT32) Column;\r
877 Mode->CursorRow = (INT32) Row;\r
878\r
879 return EFI_SUCCESS;\r
880}\r
881\r
882EFI_STATUS\r
883EFIAPI\r
884TerminalConOutEnableCursor (\r
885 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
886 IN BOOLEAN Visible\r
887 )\r
888/*++\r
889 Routine Description:\r
fb0b259e 890\r
95276127 891 Implements SIMPLE_TEXT_OUTPUT.EnableCursor().\r
fb0b259e 892 In this driver, the cursor cannot be hidden.\r
893\r
95276127 894 Arguments:\r
fb0b259e 895\r
95276127 896 This\r
897 Indicates the calling context.\r
fb0b259e 898\r
95276127 899 Visible\r
900 If TRUE, the cursor is set to be visible,\r
fb0b259e 901 If FALSE, the cursor is set to be invisible.\r
95276127 902\r
903 Returns:\r
fb0b259e 904\r
95276127 905 EFI_SUCCESS\r
906 The request is valid.\r
fb0b259e 907\r
95276127 908 EFI_UNSUPPORTED\r
fb0b259e 909 The terminal does not support cursor hidden.\r
910\r
95276127 911--*/\r
912{\r
913 if (!Visible) {\r
914 return EFI_UNSUPPORTED;\r
915 }\r
916\r
917 return EFI_SUCCESS;\r
918}\r
919\r
920BOOLEAN\r
921TerminalIsValidTextGraphics (\r
922 IN CHAR16 Graphic,\r
923 OUT CHAR8 *PcAnsi, OPTIONAL\r
924 OUT CHAR8 *Ascii OPTIONAL\r
925 )\r
926/*++\r
927\r
928Routine Description:\r
929\r
930 Detects if a Unicode char is for Box Drawing text graphics.\r
931\r
932Arguments:\r
933\r
934 Graphic - Unicode char to test.\r
935\r
936 PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.\r
937\r
938 Ascii - Optional pointer to return ASCII equivalent of Graphic.\r
939\r
940Returns:\r
941\r
942 TRUE if Graphic is a supported Unicode Box Drawing character.\r
943\r
944--*/\r
945{\r
946 UNICODE_TO_CHAR *Table;\r
947\r
948 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {\r
949 //\r
950 // Unicode drawing code charts are all in the 0x25xx range,\r
951 // arrows are 0x21xx\r
952 //\r
953 return FALSE;\r
954 }\r
955\r
956 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {\r
957 if (Graphic == Table->Unicode) {\r
958 if (PcAnsi != NULL) {\r
959 *PcAnsi = Table->PcAnsi;\r
960 }\r
961\r
962 if (Ascii != NULL) {\r
963 *Ascii = Table->Ascii;\r
964 }\r
965\r
966 return TRUE;\r
967 }\r
968 }\r
969\r
970 return FALSE;\r
971}\r
972\r
973BOOLEAN\r
974TerminalIsValidAscii (\r
975 IN CHAR16 Ascii\r
976 )\r
977{\r
978 //\r
979 // valid ascii code lies in the extent of 0x20 ~ 0x7f\r
980 //\r
981 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {\r
982 return TRUE;\r
983 }\r
984\r
985 return FALSE;\r
986}\r
987\r
988BOOLEAN\r
989TerminalIsValidEfiCntlChar (\r
990 IN CHAR16 CharC\r
991 )\r
992{\r
993 //\r
994 // only support four control characters.\r
995 //\r
996 if (CharC == CHAR_NULL ||\r
997 CharC == CHAR_BACKSPACE ||\r
998 CharC == CHAR_LINEFEED ||\r
999 CharC == CHAR_CARRIAGE_RETURN ||\r
1000 CharC == CHAR_TAB\r
1001 ) {\r
1002 return TRUE;\r
1003 }\r
1004\r
1005 return FALSE;\r
1006}\r