]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Accept VT220 DEL and function keys for TTY terminal type
authorRoy Franz <roy.franz@linaro.org>
Thu, 9 Jul 2015 06:24:20 +0000 (06:24 +0000)
committerlersek <lersek@Edk2>
Thu, 9 Jul 2015 06:24:20 +0000 (06:24 +0000)
Accept the VT220 escape code [3~ as backspace for TtyTerm terminals.  This is
sent by many Linux terminals by default.  Also accept VT220 function keys
F1-F12, and VT100 F1-F4 keys as these are commonly sent by Linux terminals.
The VT220 escape codes are longer, and variable length so a new state is added
to the state machine along with a variable to construct the multibyte escape
sequence.
There are currently no ambiguous escape sequence prefixes accepted, so the TTY
terminal accepts escape sequences for a variety of terminals.  The goal is to
'just work' with as many terminals as possible, rather than properly emulating
any specific terminal.  Backspace, Del, and F10 have been tested on xterm,
rxvt, tmux, and screen.
Note: The existing vt100 function key handling does not match the vt100
documentation that I found, so I added the TTY terminal handling
of VT100 F1-F4 (really PF1-PF4 on vt100) separately.  The vt100
has no F5-F10 keys, so I don't know what the current vt100 code
is based on.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Roy Franz <roy.franz@linaro.org>
Reviewed-by: Feng Tian <feng.tian@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17897 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c

index babb097e57895428e7dada89a275c1f2ca56d43f..597b15d09c085b35a75ca35da31171cb0a8fc926 100644 (file)
@@ -81,6 +81,12 @@ TERMINAL_DEV  mTerminalDevTemplate = {
   NULL, // TwoSecondTimeOut\r
   INPUT_STATE_DEFAULT,\r
   RESET_STATE_DEFAULT,\r
   NULL, // TwoSecondTimeOut\r
   INPUT_STATE_DEFAULT,\r
   RESET_STATE_DEFAULT,\r
+  {\r
+      0,\r
+      0,\r
+      0\r
+  },\r
+  0,\r
   FALSE,\r
   {   // SimpleTextInputEx\r
     TerminalConInResetEx,\r
   FALSE,\r
   {   // SimpleTextInputEx\r
     TerminalConInResetEx,\r
index 03542a40dc0777b3e439edcaff6137a6854bf81c..269d2aeb5a08311b7c5a037ba31a39474a7113d8 100644 (file)
@@ -99,6 +99,8 @@ typedef struct {
   EFI_EVENT                           TwoSecondTimeOut;\r
   UINT32                              InputState;\r
   UINT32                              ResetState;\r
   EFI_EVENT                           TwoSecondTimeOut;\r
   UINT32                              InputState;\r
   UINT32                              ResetState;\r
+  UINT16                              TtyEscapeStr[3];\r
+  INTN                                TtyEscapeIndex;\r
 \r
   //\r
   // Esc could not be output to the screen by user,\r
 \r
   //\r
   // Esc could not be output to the screen by user,\r
@@ -118,6 +120,7 @@ typedef struct {
 #define INPUT_STATE_LEFTOPENBRACKET       0x04\r
 #define INPUT_STATE_O                     0x08\r
 #define INPUT_STATE_2                     0x10\r
 #define INPUT_STATE_LEFTOPENBRACKET       0x04\r
 #define INPUT_STATE_O                     0x08\r
 #define INPUT_STATE_2                     0x10\r
+#define INPUT_STATE_LEFTOPENBRACKET_2     0x20\r
 \r
 #define RESET_STATE_DEFAULT               0x00\r
 #define RESET_STATE_ESC_R                 0x01\r
 \r
 #define RESET_STATE_DEFAULT               0x00\r
 #define RESET_STATE_ESC_R                 0x01\r
index 227df85f69086f1ad19d4e559168163e54f0dcc2..fbaf33ba45f9763af55a2f4116e8d57446a781a8 100644 (file)
@@ -1223,7 +1223,8 @@ UnicodeToEfiKey (
         continue;\r
       }\r
 \r
         continue;\r
       }\r
 \r
-      if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100TYPE) {\r
+      if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == VT100TYPE ||\r
+                                 TerminalDevice->TerminalType == TTYTERMTYPE)) {\r
         TerminalDevice->InputState |= INPUT_STATE_O;\r
         TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
         continue;\r
         TerminalDevice->InputState |= INPUT_STATE_O;\r
         TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
         continue;\r
@@ -1371,6 +1372,22 @@ UnicodeToEfiKey (
         default :\r
           break;\r
         }\r
         default :\r
           break;\r
         }\r
+      } else if (TerminalDevice->TerminalType == TTYTERMTYPE) {\r
+        /* Also accept VT100 escape codes for F1-F4 for TTY term */\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
       }\r
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
@@ -1514,6 +1531,21 @@ UnicodeToEfiKey (
         }\r
       }\r
 \r
         }\r
       }\r
 \r
+      /*\r
+       * The VT220 escape codes that the TTY terminal accepts all have\r
+       * numeric codes, and there are no ambiguous prefixes shared with\r
+       * other terminal types.\r
+       */\r
+      if (TerminalDevice->TerminalType == TTYTERMTYPE &&\r
+          Key.ScanCode == SCAN_NULL &&\r
+          UnicodeChar >= '0' &&\r
+          UnicodeChar <= '9') {\r
+        TerminalDevice->TtyEscapeStr[0] = UnicodeChar;\r
+        TerminalDevice->TtyEscapeIndex = 1;\r
+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2;\r
+        continue;\r
+      }\r
+\r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
         EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
         EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
@@ -1527,6 +1559,65 @@ UnicodeToEfiKey (
       break;\r
 \r
 \r
       break;\r
 \r
 \r
+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_2:\r
+      /*\r
+       * Here we handle the VT220 escape codes that we accept.  This\r
+       * state is only used by the TTY terminal type.\r
+       */\r
+      Key.ScanCode = SCAN_NULL;\r
+      if (TerminalDevice->TerminalType == TTYTERMTYPE) {\r
+\r
+        if (UnicodeChar == '~' && TerminalDevice->TtyEscapeIndex <= 2) {\r
+          UINTN EscCode;\r
+          TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex] = 0; /* Terminate string */\r
+          EscCode = StrDecimalToUintn(TerminalDevice->TtyEscapeStr);\r
+          switch (EscCode) {\r
+          case 3:\r
+              Key.ScanCode = SCAN_DELETE;\r
+              break;\r
+          case 11:\r
+          case 12:\r
+          case 13:\r
+          case 14:\r
+          case 15:\r
+            Key.ScanCode = SCAN_F1 + EscCode - 11;\r
+            break;\r
+          case 17:\r
+          case 18:\r
+          case 19:\r
+          case 20:\r
+          case 21:\r
+            Key.ScanCode = SCAN_F6 + EscCode - 17;\r
+            break;\r
+          case 23:\r
+          case 24:\r
+            Key.ScanCode = SCAN_F11 + EscCode - 23;\r
+            break;\r
+          default:\r
+            break;\r
+          }\r
+        } else if (TerminalDevice->TtyEscapeIndex == 1){\r
+          /* 2 character escape code   */\r
+          TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex++] = UnicodeChar;\r
+          continue;\r
+        }\r
+        else {\r
+          DEBUG ((EFI_D_ERROR, "Unexpected state in escape2\n"));\r
+        }\r
+      }\r
+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;\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
+      break;\r
+\r
     default:\r
       //\r
       // Invalid state. This should never happen.\r
     default:\r
       //\r
       // Invalid state. This should never happen.\r