]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
MdeModulePkg/TerminalDxe: Extend the terminal console support types
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConIn.c
index 4ede41677493da9c72af5a37ac8cb175cb3b4567..ac31f27984a086c13820b208dff29fd98d912394 100644 (file)
@@ -2,7 +2,7 @@
   Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
 \r
 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
@@ -453,6 +453,10 @@ TranslateRawDataToEfiKey (
   case TerminalTypeVt100:\r
   case TerminalTypeVt100Plus:\r
   case TerminalTypeTtyTerm:\r
+  case TerminalTypeLinux:\r
+  case TerminalTypeXtermR6:\r
+  case TerminalTypeVt400:\r
+  case TerminalTypeSCO:\r
     AnsiRawDataToUnicode (TerminalDevice);\r
     UnicodeToEfiKey (TerminalDevice);\r
     break;\r
@@ -1319,6 +1323,27 @@ UnicodeToEfiKeyFlushState (
   | F12     | 0x16 |           | ESC @    |          |\r
   +=========+======+===========+==========+==========+\r
 \r
+Putty function key map:\r
+  +=========+======+===========+=============+=============+=============+=========+\r
+  |         | EFI  |           |             |             |             |         |\r
+  |         | Scan |           |             |  Normal     |             |         |\r
+  |   KEY   | Code |  VT100+   | Xterm R6    |  VT400      | Linux       | SCO     |\r
+  +=========+======+===========+=============+=============+=============+=========+\r
+  | F1      | 0x0B | ESC O P   | ESC O P     | ESC [ 1 1 ~ | ESC [ [ A   | ESC [ M |\r
+  | F2      | 0x0C | ESC O Q   | ESC O Q     | ESC [ 1 2 ~ | ESC [ [ B   | ESC [ N |\r
+  | F3      | 0x0D | ESC O R   | ESC O R     | ESC [ 1 3 ~ | ESC [ [ C   | ESC [ O |\r
+  | F4      | 0x0E | ESC O S   | ESC O S     | ESC [ 1 4 ~ | ESC [ [ D   | ESC [ P |\r
+  | F5      | 0x0F | ESC O T   | ESC [ 1 5 ~ | ESC [ 1 5 ~ | ESC [ [ E   | ESC [ Q |\r
+  | F6      | 0x10 | ESC O U   | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC [ 1 7 ~ | ESC [ R |\r
+  | F7      | 0x11 | ESC O V   | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC [ 1 8 ~ | ESC [ S |\r
+  | F8      | 0x12 | ESC O W   | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC [ 1 9 ~ | ESC [ T |\r
+  | F9      | 0x13 | ESC O X   | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC [ 2 0 ~ | ESC [ U |\r
+  | F10     | 0x14 | ESC O Y   | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC [ 2 1 ~ | ESC [ V |\r
+  | Escape  | 0x17 | ESC       | ESC         | ESC         | ESC         | ESC     |\r
+  | F11     | 0x15 | ESC O Z   | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC [ 2 3 ~ | ESC [ W |\r
+  | F12     | 0x16 | ESC O [   | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC [ 2 4 ~ | ESC [ X |\r
+  +=========+======+===========+=============+=============+=============+=========+\r
+\r
   Special Mappings\r
   ================\r
   ESC R ESC r ESC R = Reset System\r
@@ -1378,7 +1403,9 @@ UnicodeToEfiKey (
       }\r
 \r
       if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == TerminalTypeVt100 ||\r
-                                 TerminalDevice->TerminalType == TerminalTypeTtyTerm)) {\r
+                                 TerminalDevice->TerminalType == TerminalTypeTtyTerm ||\r
+                                 TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+                                 TerminalDevice->TerminalType == TerminalTypeVt100Plus)) {\r
         TerminalDevice->InputState |= INPUT_STATE_O;\r
         TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
         continue;\r
@@ -1548,6 +1575,60 @@ UnicodeToEfiKey (
           Key.ScanCode = SCAN_END;\r
           break;\r
         }\r
+      } else if (TerminalDevice->TerminalType == TerminalTypeVt100Plus) {\r
+        switch (UnicodeChar) {\r
+        case 'P':\r
+          Key.ScanCode = SCAN_F1;\r
+          break;\r
+        case 'Q':\r
+          Key.ScanCode = SCAN_F2;\r
+          break;\r
+        case 'R':\r
+          Key.ScanCode = SCAN_F3;\r
+          break;\r
+        case 'S':\r
+          Key.ScanCode = SCAN_F4;\r
+          break;\r
+        case 'T':\r
+          Key.ScanCode = SCAN_F5;\r
+          break;\r
+        case 'U':\r
+          Key.ScanCode = SCAN_F6;\r
+          break;\r
+        case 'V':\r
+          Key.ScanCode = SCAN_F7;\r
+          break;\r
+        case 'W':\r
+          Key.ScanCode = SCAN_F8;\r
+          break;\r
+        case 'X':\r
+          Key.ScanCode = SCAN_F9;\r
+          break;\r
+        case 'Y':\r
+          Key.ScanCode = SCAN_F10;\r
+          break;\r
+        case 'Z':\r
+          Key.ScanCode = SCAN_F11;\r
+          break;\r
+        case '[':\r
+          Key.ScanCode = SCAN_F12;\r
+          break;\r
+        }\r
+      } else if (TerminalDevice->TerminalType == TerminalTypeXtermR6) {\r
+        switch (UnicodeChar) {\r
+        case 'P':\r
+          Key.ScanCode = SCAN_F1;\r
+          break;\r
+        case 'Q':\r
+          Key.ScanCode = SCAN_F2;\r
+          break;\r
+        case 'R':\r
+          Key.ScanCode = SCAN_F3;\r
+          break;\r
+        case 'S':\r
+          Key.ScanCode = SCAN_F4;\r
+          break;\r
+        }\r
       }\r
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
@@ -1564,15 +1645,34 @@ UnicodeToEfiKey (
 \r
     case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:\r
 \r
+      if (UnicodeChar == '1' && (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+                                  TerminalDevice->TerminalType == TerminalTypeVt400 ||\r
+                                  TerminalDevice->TerminalType == TerminalTypeLinux)) {\r
+        TerminalDevice->InputState |= INPUT_STATE_1;\r
+        continue;\r
+      }\r
+\r
+      if (UnicodeChar == '2' && (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+                                  TerminalDevice->TerminalType == TerminalTypeVt400 ||\r
+                                  TerminalDevice->TerminalType == TerminalTypeLinux)) {\r
+        TerminalDevice->InputState |= INPUT_STATE_2;\r
+        continue;\r
+      }\r
+\r
+      if (UnicodeChar == LEFTOPENBRACKET && TerminalDevice->TerminalType == TerminalTypeLinux) {\r
+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2ND;\r
+        continue;\r
+      }\r
+\r
       TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
 \r
       Key.ScanCode = SCAN_NULL;\r
 \r
       if (TerminalDevice->TerminalType == TerminalTypePcAnsi    ||\r
           TerminalDevice->TerminalType == TerminalTypeVt100     ||\r
-          TerminalDevice->TerminalType == TerminalTypeVt100Plus ||\r
-          TerminalDevice->TerminalType == TerminalTypeVtUtf8    ||\r
-          TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\r
+          TerminalDevice->TerminalType == TerminalTypeVtUtf8 ||\r
+          TerminalDevice->TerminalType == TerminalTypeTtyTerm ||\r
+          TerminalDevice->TerminalType == TerminalTypeSCO) {\r
         switch (UnicodeChar) {\r
         case 'A':\r
           Key.ScanCode = SCAN_UP;\r
@@ -1614,12 +1714,15 @@ UnicodeToEfiKey (
         case 'X':\r
           if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
             Key.ScanCode = SCAN_DELETE;\r
+          } else if (TerminalDevice->TerminalType == TerminalTypeSCO) {\r
+            Key.ScanCode = SCAN_F12;\r
           }\r
           break;\r
         case 'P':\r
           if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
             Key.ScanCode = SCAN_DELETE;\r
-          } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+                      TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F4;\r
           }\r
           break;\r
@@ -1629,7 +1732,8 @@ UnicodeToEfiKey (
           }\r
           break;\r
         case 'V':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F10;\r
           }\r
           break;\r
@@ -1644,7 +1748,8 @@ UnicodeToEfiKey (
           }\r
           break;\r
         case 'U':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F9;\r
           }\r
           break;\r
@@ -1654,40 +1759,52 @@ UnicodeToEfiKey (
           }\r
           break;\r
         case 'M':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F1;\r
           }\r
           break;\r
         case 'N':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F2;\r
           }\r
           break;\r
         case 'O':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F3;\r
           }\r
           break;\r
         case 'Q':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F5;\r
           }\r
           break;\r
         case 'R':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F6;\r
           }\r
           break;\r
         case 'S':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F7;\r
           }\r
           break;\r
         case 'T':\r
-          if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
+          if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+              TerminalDevice->TerminalType == TerminalTypeSCO) {\r
             Key.ScanCode = SCAN_F8;\r
           }\r
           break;\r
+        case 'W':\r
+          if (TerminalDevice->TerminalType == TerminalTypeSCO) {\r
+            Key.ScanCode = SCAN_F11;\r
+          }\r
+          break;\r
         default :\r
           break;\r
         }\r
@@ -1704,10 +1821,105 @@ UnicodeToEfiKey (
           UnicodeChar <= '9') {\r
         TerminalDevice->TtyEscapeStr[0] = UnicodeChar;\r
         TerminalDevice->TtyEscapeIndex = 1;\r
-        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2;\r
+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_TTY;\r
+        continue;\r
+      }\r
+\r
+      if (Key.ScanCode != SCAN_NULL) {\r
+        Key.UnicodeChar = 0;\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+        UnicodeToEfiKeyFlushState (TerminalDevice);\r
+        continue;\r
+      }\r
+\r
+      UnicodeToEfiKeyFlushState (TerminalDevice);\r
+\r
+      break;\r
+\r
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_1:\r
+\r
+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
+\r
+      Key.ScanCode = SCAN_NULL;\r
+\r
+      if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+          TerminalDevice->TerminalType == TerminalTypeVt400 ||\r
+          TerminalDevice->TerminalType == TerminalTypeLinux) {\r
+        switch (UnicodeChar) {\r
+        case '1':\r
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {\r
+            Key.ScanCode = SCAN_F1;\r
+          }\r
+          break;\r
+        case '2':\r
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {\r
+            Key.ScanCode = SCAN_F2;\r
+          }\r
+          break;\r
+        case '3':\r
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {\r
+            Key.ScanCode = SCAN_F3;\r
+          }\r
+          break;\r
+        case '4':\r
+          if (TerminalDevice->TerminalType == TerminalTypeVt400) {\r
+            Key.ScanCode = SCAN_F4;\r
+          }\r
+          break;\r
+        case '5':\r
+          if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+              TerminalDevice->TerminalType == TerminalTypeVt400) {\r
+            Key.ScanCode = SCAN_F5;\r
+          }\r
+          break;\r
+        case '7':\r
+          Key.ScanCode = SCAN_F6;\r
+          break;\r
+        case '8':\r
+          Key.ScanCode = SCAN_F7;\r
+          break;\r
+        case '9':\r
+          Key.ScanCode = SCAN_F8;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (Key.ScanCode != SCAN_NULL) {\r
+        Key.UnicodeChar = 0;\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+        UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
       }\r
 \r
+      UnicodeToEfiKeyFlushState (TerminalDevice);\r
+\r
+      break;\r
+\r
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_2:\r
+\r
+      TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+      Key.ScanCode = SCAN_NULL;\r
+      if (TerminalDevice->TerminalType == TerminalTypeXtermR6 ||\r
+          TerminalDevice->TerminalType == TerminalTypeVt400 ||\r
+          TerminalDevice->TerminalType == TerminalTypeLinux) {\r
+        switch (UnicodeChar) {\r
+        case '0':\r
+          Key.ScanCode = SCAN_F9;\r
+          break;\r
+        case '1':\r
+          Key.ScanCode = SCAN_F10;\r
+          break;\r
+        case '3':\r
+          Key.ScanCode = SCAN_F11;\r
+          break;\r
+        case '4':\r
+          Key.ScanCode = SCAN_F12;\r
+          break;\r
+        }\r
+      }\r
+\r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
         EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
@@ -1720,8 +1932,44 @@ UnicodeToEfiKey (
 \r
       break;\r
 \r
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_2ND:\r
+\r
+      TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+      Key.ScanCode = SCAN_NULL;\r
+\r
+      if (TerminalDevice->TerminalType == TerminalTypeLinux) {\r
+        switch (UnicodeChar) {\r
+        case 'A':\r
+          Key.ScanCode = SCAN_F1;\r
+          break;\r
+        case 'B':\r
+          Key.ScanCode = SCAN_F2;\r
+          break;\r
+        case 'C':\r
+          Key.ScanCode = SCAN_F3;\r
+          break;\r
+        case 'D':\r
+          Key.ScanCode = SCAN_F4;\r
+          break;\r
+        case 'E':\r
+          Key.ScanCode = SCAN_F5;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (Key.ScanCode != SCAN_NULL) {\r
+        Key.UnicodeChar = 0;\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+        UnicodeToEfiKeyFlushState (TerminalDevice);\r
+        continue;\r
+      }\r
+\r
+      UnicodeToEfiKeyFlushState (TerminalDevice);\r
+\r
+      break;\r
 \r
-    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_2:\r
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_TTY:\r
       /*\r
        * Here we handle the VT220 escape codes that we accept.  This\r
        * state is only used by the TTY terminal type.\r