REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2186

Extend the support types of terminal console driver. New added types
are Linux, XtermR6, VT400 and SCO.

Refer to
https://www.ssh.com/ssh/putty/putty-manuals/0.68/Chapter4.html#config-funkeys

Add the missing VT100+ function keys map.

Add F1-F12 function keys map for Linux, XtermR6, VT400 and SCO.

Cc: Jian J Wang <jian.j.w...@intel.com>
Cc: Hao A Wu <hao.a...@intel.com>
Cc: Ray Ni <ray...@intel.com>
Cc: Liming Gao <liming....@intel.com>
Signed-off-by: Zhichao Gao <zhichao....@intel.com>
---
 .../Universal/Console/TerminalDxe/Terminal.c  |  17 +-
 .../Universal/Console/TerminalDxe/Terminal.h  |  37 ++-
 .../Console/TerminalDxe/TerminalConIn.c       | 281 ++++++++++++++++--
 .../Console/TerminalDxe/TerminalConOut.c      |   4 +
 .../Console/TerminalDxe/TerminalDxe.inf       |   6 +-
 5 files changed, 319 insertions(+), 26 deletions(-)

diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c 
b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
index c76b2c5100..526067d023 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
@@ -2,7 +2,7 @@
   Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
   Simple Text Output Protocol upon Serial IO Protocol.
 
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -28,7 +28,11 @@ EFI_GUID  *mTerminalType[] = {
   &gEfiVT100Guid,
   &gEfiVT100PlusGuid,
   &gEfiVTUTF8Guid,
-  &gEfiTtyTermGuid
+  &gEfiTtyTermGuid,
+  &gEdkiiLinuxModeGuid,
+  &gEdkiiXtermR6Guid,
+  &gEdkiiVT400Guid,
+  &gEdkiiSCOGuid
 };
 
 
@@ -37,7 +41,11 @@ CHAR16 *mSerialConsoleNames[] = {
   L"VT-100 Serial Console",
   L"VT-100+ Serial Console",
   L"VT-UTF8 Serial Console",
-  L"Tty Terminal Serial Console"
+  L"Tty Terminal Serial Console",
+  L"Linux Mode Terminal Serial Console",
+  L"Xterm R6 Terminal Serial Console",
+  L"VT400 Terminal Serial Console",
+  L"SCO Terminal Serial Console"
 };
 
 TERMINAL_DEV  mTerminalDevTemplate = {
@@ -187,7 +195,8 @@ TerminalDriverBindingSupported (
 
       }
       //
-      // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal 
types
+      // only supports PC ANSI, VT100, VT100+, VT-UTF8, TtyTerm
+      // Linux, XtermR6, VT400 and SCO terminal types
       //
       if (TerminalTypeFromGuid (&Node->Guid) == ARRAY_SIZE (mTerminalType)) {
         return EFI_UNSUPPORTED;
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h 
b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
index b2f0901fc1..d683aa792f 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for Terminal driver.
 
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -81,7 +81,11 @@ typedef enum {
   TerminalTypeVt100,
   TerminalTypeVt100Plus,
   TerminalTypeVtUtf8,
-  TerminalTypeTtyTerm
+  TerminalTypeTtyTerm,
+  TerminalTypeLinux,
+  TerminalTypeXtermR6,
+  TerminalTypeVt400,
+  TerminalTypeSCO
 } TERMINAL_TYPE;
 
 typedef struct {
@@ -126,7 +130,9 @@ typedef struct {
 #define INPUT_STATE_LEFTOPENBRACKET       0x04
 #define INPUT_STATE_O                     0x08
 #define INPUT_STATE_2                     0x10
-#define INPUT_STATE_LEFTOPENBRACKET_2     0x20
+#define INPUT_STATE_LEFTOPENBRACKET_TTY   0x20
+#define INPUT_STATE_1                     0x40
+#define INPUT_STATE_LEFTOPENBRACKET_2ND   0x80
 
 #define RESET_STATE_DEFAULT               0x00
 #define RESET_STATE_ESC_R                 0x01
@@ -848,7 +854,8 @@ TerminalRemoveConsoleDevVariable (
 /**
   Build termial device path according to terminal type.
 
-  @param  TerminalType           The terminal type is PC ANSI, VT100, VT100+ 
or VT-UTF8.
+  @param  TerminalType           The terminal type is PC ANSI, VT100, VT100+, 
VT-UTF8, TTY-Term,
+                                 Linux, XtermR6 or VT400.
   @param  ParentDevicePath       Parent device path.
   @param  TerminalDevicePath     Returned terminal device path, if building 
successfully.
 
@@ -1209,6 +1216,28 @@ AnsiRawDataToUnicode (
   | F12     | 0x16 |           | ESC @    |          |
   +=========+======+===========+==========+==========+
 
+Putty function key map:
+  
+=========+======+===========+=============+=============+=============+=========+
+  |         | EFI  |           |             |             |             |     
    |
+  |         | Scan |           |             |  Normal     |             |     
    |
+  |   KEY   | Code |  VT100+   | Xterm R6    |  VT400      | Linux       | SCO 
    |
+  
+=========+======+===========+=============+=============+=============+=========+
+  | F1      | 0x0B | ESC O P   | ESC O P     | ESC [ 1 1 ~ | ESC [ [ A   | ESC 
[ M |
+  | F2      | 0x0C | ESC O Q   | ESC O Q     | ESC [ 1 2 ~ | ESC [ [ B   | ESC 
[ N |
+  | F3      | 0x0D | ESC O R   | ESC O R     | ESC [ 1 3 ~ | ESC [ [ C   | ESC 
[ O |
+  | F4      | 0x0E | ESC O S   | ESC O S     | ESC [ 1 4 ~ | ESC [ [ D   | ESC 
[ P |
+  | F5      | 0x0F | ESC O T   | ESC [ 1 5 ~ | ESC [ 1 5 ~ | ESC [ [ E   | ESC 
[ Q |
+  | F6      | 0x10 | ESC O U   | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC 
[ R |
+  | F7      | 0x11 | ESC O V   | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC 
[ S |
+  | F8      | 0x12 | ESC O W   | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC 
[ T |
+  | F9      | 0x13 | ESC O X   | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC 
[ U |
+  | F10     | 0x14 | ESC O Y   | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC 
[ V |
+  | Escape  | 0x17 | ESC       | ESC         | ESC         | ESC         | ESC 
    |
+  | F11     | 0x15 | ESC O Z   | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC 
[ W |
+  | F12     | 0x16 | ESC O [   | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC 
[ X |
+  
+=========+======+===========+=============+=============+=============+=========+
+
+
   Special Mappings
   ================
   ESC R ESC r ESC R = Reset System
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c 
b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
index 4ede416774..fb2eda01e7 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
@@ -2,7 +2,7 @@
   Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
 
 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -453,6 +453,10 @@ TranslateRawDataToEfiKey (
   case TerminalTypeVt100:
   case TerminalTypeVt100Plus:
   case TerminalTypeTtyTerm:
+  case TerminalTypeLinux:
+  case TerminalTypeXtermR6:
+  case TerminalTypeVt400:
+  case TerminalTypeSCO:
     AnsiRawDataToUnicode (TerminalDevice);
     UnicodeToEfiKey (TerminalDevice);
     break;
@@ -1319,6 +1323,27 @@ UnicodeToEfiKeyFlushState (
   | F12     | 0x16 |           | ESC @    |          |
   +=========+======+===========+==========+==========+
 
+Putty function key map:
+  
+=========+======+===========+=============+=============+=============+=========+
+  |         | EFI  |           |             |             |             |     
    |
+  |         | Scan |           |             |  Normal     |             |     
    |
+  |   KEY   | Code |  VT100+   | Xterm R6    |  VT400      | Linux       | SCO 
    |
+  
+=========+======+===========+=============+=============+=============+=========+
+  | F1      | 0x0B | ESC O P   | ESC O P     | ESC [ 1 1 ~ | ESC [ [ A   | ESC 
[ M |
+  | F2      | 0x0C | ESC O Q   | ESC O Q     | ESC [ 1 2 ~ | ESC [ [ B   | ESC 
[ N |
+  | F3      | 0x0D | ESC O R   | ESC O R     | ESC [ 1 3 ~ | ESC [ [ C   | ESC 
[ O |
+  | F4      | 0x0E | ESC O S   | ESC O S     | ESC [ 1 4 ~ | ESC [ [ D   | ESC 
[ P |
+  | F5      | 0x0F | ESC O T   | ESC [ 1 5 ~ | ESC [ 1 5 ~ | ESC [ [ E   | ESC 
[ Q |
+  | F6      | 0x10 | ESC O U   | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC 
[ R |
+  | F7      | 0x11 | ESC O V   | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC 
[ S |
+  | F8      | 0x12 | ESC O W   | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC 
[ T |
+  | F9      | 0x13 | ESC O X   | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC 
[ U |
+  | F10     | 0x14 | ESC O Y   | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC 
[ V |
+  | Escape  | 0x17 | ESC       | ESC         | ESC         | ESC         | ESC 
    |
+  | F11     | 0x15 | ESC O Z   | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC 
[ W |
+  | F12     | 0x16 | ESC O [   | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC 
[ X |
+  
+=========+======+===========+=============+=============+=============+=========+
+
   Special Mappings
   ================
   ESC R ESC r ESC R = Reset System
@@ -1378,7 +1403,9 @@ UnicodeToEfiKey (
       }
 
       if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == 
TerminalTypeVt100 ||
-                                 TerminalDevice->TerminalType == 
TerminalTypeTtyTerm)) {
+                                 TerminalDevice->TerminalType == 
TerminalTypeTtyTerm ||
+                                 TerminalDevice->TerminalType == 
TerminalTypeXtermR6 ||
+                                 TerminalDevice->TerminalType == 
TerminalTypeVt100Plus)) {
         TerminalDevice->InputState |= INPUT_STATE_O;
         TerminalDevice->ResetState = RESET_STATE_DEFAULT;
         continue;
@@ -1548,6 +1575,60 @@ UnicodeToEfiKey (
           Key.ScanCode = SCAN_END;
           break;
         }
+      } else if (TerminalDevice->TerminalType == TerminalTypeVt100Plus) {
+        switch (UnicodeChar) {
+        case 'P':
+          Key.ScanCode = SCAN_F1;
+          break;
+        case 'Q':
+          Key.ScanCode = SCAN_F2;
+          break;
+        case 'R':
+          Key.ScanCode = SCAN_F3;
+          break;
+        case 'S':
+          Key.ScanCode = SCAN_F4;
+          break;
+        case 'T':
+          Key.ScanCode = SCAN_F5;
+          break;
+        case 'U':
+          Key.ScanCode = SCAN_F6;
+          break;
+        case 'V':
+          Key.ScanCode = SCAN_F7;
+          break;
+        case 'W':
+          Key.ScanCode = SCAN_F8;
+          break;
+        case 'X':
+          Key.ScanCode = SCAN_F9;
+          break;
+        case 'Y':
+          Key.ScanCode = SCAN_F10;
+          break;
+        case 'Z':
+          Key.ScanCode = SCAN_F11;
+          break;
+        case '[':
+          Key.ScanCode = SCAN_F12;
+          break;
+        }
+      } else if (TerminalDevice->TerminalType == TerminalTypeXtermR6) {
+        switch (UnicodeChar) {
+        case 'P':
+          Key.ScanCode = SCAN_F1;
+          break;
+        case 'Q':
+          Key.ScanCode = SCAN_F2;
+          break;
+        case 'R':
+          Key.ScanCode = SCAN_F3;
+          break;
+        case 'S':
+          Key.ScanCode = SCAN_F4;
+          break;
+        }
       }
 
       if (Key.ScanCode != SCAN_NULL) {
@@ -1564,15 +1645,33 @@ UnicodeToEfiKey (
 
     case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:
 
+      if (UnicodeChar == '1' && (TerminalDevice->TerminalType == 
TerminalTypeXtermR6 ||
+                                  TerminalDevice->TerminalType == 
TerminalTypeVt400 ||
+                                  TerminalDevice->TerminalType == 
TerminalTypeLinux)) {
+        TerminalDevice->InputState |= INPUT_STATE_1;
+        continue;
+      }
+
+      if (UnicodeChar == '2' && (TerminalDevice->TerminalType == 
TerminalTypeXtermR6 ||
+                                  TerminalDevice->TerminalType == 
TerminalTypeVt400 ||
+                                  TerminalDevice->TerminalType == 
TerminalTypeLinux)) {
+        TerminalDevice->InputState |= INPUT_STATE_2;
+        continue;
+      }
+
+      if (UnicodeChar == LEFTOPENBRACKET && TerminalDevice->TerminalType == 
TerminalTypeLinux) {
+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2ND;
+        continue;
+      }
+
       TerminalDevice->ResetState = RESET_STATE_DEFAULT;
 
       Key.ScanCode = SCAN_NULL;
 
       if (TerminalDevice->TerminalType == TerminalTypePcAnsi    ||
           TerminalDevice->TerminalType == TerminalTypeVt100     ||
-          TerminalDevice->TerminalType == TerminalTypeVt100Plus ||
-          TerminalDevice->TerminalType == TerminalTypeVtUtf8    ||
-          TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
+          TerminalDevice->TerminalType == TerminalTypeVtUtf8 ||
+          TerminalDevice->TerminalType == TerminalTypeSCO) {
         switch (UnicodeChar) {
         case 'A':
           Key.ScanCode = SCAN_UP;
@@ -1614,12 +1713,15 @@ UnicodeToEfiKey (
         case 'X':
           if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
             Key.ScanCode = SCAN_DELETE;
+          } else if (TerminalDevice->TerminalType == TerminalTypeSCO) {
+            Key.ScanCode = SCAN_F12;
           }
           break;
         case 'P':
           if (TerminalDevice->TerminalType == TerminalTypeVt100) {
             Key.ScanCode = SCAN_DELETE;
-          } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+                      TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F4;
           }
           break;
@@ -1629,7 +1731,8 @@ UnicodeToEfiKey (
           }
           break;
         case 'V':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F10;
           }
           break;
@@ -1644,7 +1747,8 @@ UnicodeToEfiKey (
           }
           break;
         case 'U':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F9;
           }
           break;
@@ -1654,40 +1758,52 @@ UnicodeToEfiKey (
           }
           break;
         case 'M':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F1;
           }
           break;
         case 'N':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F2;
           }
           break;
         case 'O':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F3;
           }
           break;
         case 'Q':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F5;
           }
           break;
         case 'R':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F6;
           }
           break;
         case 'S':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F7;
           }
           break;
         case 'T':
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+              TerminalDevice->TerminalType == TerminalTypeSCO) {
             Key.ScanCode = SCAN_F8;
           }
           break;
+        case 'W':
+          if (TerminalDevice->TerminalType == TerminalTypeSCO) {
+            Key.ScanCode = SCAN_F11;
+          }
+          break;
         default :
           break;
         }
@@ -1704,10 +1820,105 @@ UnicodeToEfiKey (
           UnicodeChar <= '9') {
         TerminalDevice->TtyEscapeStr[0] = UnicodeChar;
         TerminalDevice->TtyEscapeIndex = 1;
-        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2;
+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_TTY;
+        continue;
+      }
+
+      if (Key.ScanCode != SCAN_NULL) {
+        Key.UnicodeChar = 0;
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+        UnicodeToEfiKeyFlushState (TerminalDevice);
+        continue;
+      }
+
+      UnicodeToEfiKeyFlushState (TerminalDevice);
+
+      break;
+
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_1:
+
+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+
+      Key.ScanCode = SCAN_NULL;
+
+      if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||
+          TerminalDevice->TerminalType == TerminalTypeVt400 ||
+          TerminalDevice->TerminalType == TerminalTypeLinux) {
+        switch (UnicodeChar) {
+        case '1':
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {
+            Key.ScanCode = SCAN_F1;
+          }
+          break;
+        case '2':
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {
+            Key.ScanCode = SCAN_F2;
+          }
+          break;
+        case '3':
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {
+            Key.ScanCode = SCAN_F3;
+          }
+          break;
+        case '4':
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {
+            Key.ScanCode = SCAN_F4;
+          }
+          break;
+        case '5':
+          if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||
+              TerminalDevice->TerminalType == TerminalTypeVt400) {
+            Key.ScanCode = SCAN_F5;
+          }
+          break;
+        case '7':
+          Key.ScanCode = SCAN_F6;
+          break;
+        case '8':
+          Key.ScanCode = SCAN_F7;
+          break;
+        case '9':
+          Key.ScanCode = SCAN_F8;
+          break;
+        }
+      }
+
+      if (Key.ScanCode != SCAN_NULL) {
+        Key.UnicodeChar = 0;
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+        UnicodeToEfiKeyFlushState (TerminalDevice);
         continue;
       }
 
+      UnicodeToEfiKeyFlushState (TerminalDevice);
+
+      break;
+
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_2:
+
+      TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+      Key.ScanCode = SCAN_NULL;
+      if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||
+          TerminalDevice->TerminalType == TerminalTypeVt400 ||
+          TerminalDevice->TerminalType == TerminalTypeLinux) {
+        switch (UnicodeChar) {
+        case '0':
+          Key.ScanCode = SCAN_F9;
+          break;
+        case '1':
+          Key.ScanCode = SCAN_F10;
+          break;
+        case '3':
+          Key.ScanCode = SCAN_F11;
+          break;
+        case '4':
+          Key.ScanCode = SCAN_F12;
+          break;
+        }
+      }
+
       if (Key.ScanCode != SCAN_NULL) {
         Key.UnicodeChar = 0;
         EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
@@ -1720,8 +1931,44 @@ UnicodeToEfiKey (
 
       break;
 
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | 
INPUT_STATE_LEFTOPENBRACKET_2ND:
+
+      TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+      Key.ScanCode = SCAN_NULL;
+
+      if (TerminalDevice->TerminalType == TerminalTypeLinux) {
+        switch (UnicodeChar) {
+        case 'A':
+          Key.ScanCode = SCAN_F1;
+          break;
+        case 'B':
+          Key.ScanCode = SCAN_F2;
+          break;
+        case 'C':
+          Key.ScanCode = SCAN_F3;
+          break;
+        case 'D':
+          Key.ScanCode = SCAN_F4;
+          break;
+        case 'E':
+          Key.ScanCode = SCAN_F5;
+          break;
+        }
+      }
+
+      if (Key.ScanCode != SCAN_NULL) {
+        Key.UnicodeChar = 0;
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+        UnicodeToEfiKeyFlushState (TerminalDevice);
+        continue;
+      }
+
+      UnicodeToEfiKeyFlushState (TerminalDevice);
+
+      break;
 
-    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | 
INPUT_STATE_LEFTOPENBRACKET_2:
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | 
INPUT_STATE_LEFTOPENBRACKET_TTY:
       /*
        * Here we handle the VT220 escape codes that we accept.  This
        * state is only used by the TTY terminal type.
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c 
b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
index 7ef655cca5..aae470e956 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c
@@ -222,6 +222,10 @@ TerminalConOutOutputString (
     case TerminalTypeVt100:
     case TerminalTypeVt100Plus:
     case TerminalTypeTtyTerm:
+    case TerminalTypeLinux:
+    case TerminalTypeXtermR6:
+    case TerminalTypeVt400:
+    case TerminalTypeSCO:
 
       if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
         //
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf 
b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
index 24e164ef4d..e3785c3436 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
@@ -5,7 +5,7 @@
 #  protocols based on Serial I/O protocol for serial devices including hotplug 
serial
 #  devices.
 #
-#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 #
@@ -69,6 +69,10 @@
   gEfiVT100PlusGuid                             ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
   gEfiPcAnsiGuid                                ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
   gEfiTtyTermGuid                               ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
+  gEdkiiLinuxModeGuid                           ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
+  gEdkiiXtermR6Guid                             ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
+  gEdkiiVT400Guid                               ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
+  gEdkiiSCOGuid                                 ## SOMETIMES_CONSUMES ## GUID 
# used with a Vendor-Defined Messaging Device Path
   gEdkiiStatusCodeDataTypeVariableGuid          ## SOMETIMES_CONSUMES ## GUID
 
 [Protocols]
-- 
2.21.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#47342): https://edk2.groups.io/g/devel/message/47342
Mute This Topic: https://groups.io/mt/34173531/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to