changeset 53:e872762ec105 tn5250

start tn5250 integration
author Carl Byington <carl@five-ten-sg.com>
date Wed, 11 Jun 2014 13:37:02 -0700
parents 0e3fc85d0586
children a7e660661e08
files src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java src/com/five_ten_sg/connectbot/transport/TN5250.java src/de/mud/terminal/vt320.java
diffstat 3 files changed, 117 insertions(+), 524 deletions(-) [+]
line wrap: on
line diff
--- a/src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java	Wed Jun 11 12:18:18 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java	Wed Jun 11 13:37:02 2014 -0700
@@ -91,7 +91,7 @@
     protected String  customKeyboard = null;
 
     protected int metaState = 0;
-    private   int mDeadKey  = 0;
+    protected int mDeadKey  = 0;
 
     // TODO add support for the new API.
     private ClipboardManager clipboard = null;
@@ -118,11 +118,17 @@
     }
 
     public void sendEscape() {
-        buffer.write(0x1b);
+        buffer.keyPressed(vt320.KEY_ESCAPE, ' ',  getStateForBuffer());
     }
 
     protected void sendEncoded(String s) {
-        buffer.write(s.getBytes(encoding));
+        byte [] b = null;
+        try {
+            b = s.getBytes(encoding);
+        }
+        catch (UnsupportedEncodingException e){
+        }
+        if (b != null) buffer.write(b);
     }
 
     /**
@@ -176,7 +182,7 @@
                     else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
                              && (metaState & META_TAB) != 0) {
                         metaState &= ~(META_TAB | META_TRANSIENT);
-                        buffer.write(0x09);
+                        buffer.keyPressed(vt320.KEY_TAB, ' ',  getStateForBuffer());
                         return true;
                     }
                 }
@@ -190,7 +196,7 @@
                     else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
                              && (metaState & META_TAB) != 0) {
                         metaState &= ~(META_TAB | META_TRANSIENT);
-                        buffer.write(0x09);
+                        buffer.keyPressed(vt320.KEY_TAB, ' ',  getStateForBuffer());
                         return true;
                     }
                 }
@@ -317,7 +323,7 @@
                     }
                     else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) {
                         sendMeta = true;
-                        buffer.write(0x1b);
+                        sendEscape();
                     }
 
                     if (sendMeta || sendCtrl) {
@@ -342,7 +348,7 @@
                         return true;
                     }
                     else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) {
-                        buffer.write(0x1b);
+                        sendEscape();
                         buffer.write(k);
                         return true;
                     }
@@ -418,11 +424,11 @@
             // look for special chars
             switch (keyCode) {
                 case KEYCODE_ESCAPE:
-                    buffer.write(0x1b);
+                    sendEscape();
                     return true;
 
                 case KeyEvent.KEYCODE_TAB:
-                    buffer.write(0x09);
+                    buffer.keyPressed(vt320.KEY_TAB, ' ',  getStateForBuffer());
                     return true;
 
                 case KEYCODE_PAGE_DOWN:
@@ -479,12 +485,10 @@
 
                 case KeyEvent.KEYCODE_DEL:
                     if ((metaState & META_ALT_MASK) != 0) {
-                        buffer.keyPressed(vt320.KEY_INSERT, ' ',
-                                          getStateForBuffer());
+                        buffer.keyPressed(vt320.KEY_INSERT, ' ', getStateForBuffer());
                     }
                     else {
-                        buffer.keyPressed(vt320.KEY_BACK_SPACE, ' ',
-                                          getStateForBuffer());
+                        buffer.keyPressed(vt320.KEY_BACK_SPACE, ' ', getStateForBuffer());
                     }
 
                     metaState &= ~META_TRANSIENT;
@@ -502,12 +506,10 @@
                     }
                     else {
                         if ((metaState & META_ALT_MASK) != 0) {
-                            buffer.keyPressed(vt320.KEY_HOME, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_HOME, ' ', getStateForBuffer());
                         }
                         else {
-                            buffer.keyPressed(vt320.KEY_LEFT, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_LEFT, ' ', getStateForBuffer());
                         }
 
                         metaState &= ~META_TRANSIENT;
@@ -523,12 +525,10 @@
                     }
                     else {
                         if ((metaState & META_ALT_MASK) != 0) {
-                            buffer.keyPressed(vt320.KEY_PAGE_UP, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_PAGE_UP, ' ', getStateForBuffer());
                         }
                         else {
-                            buffer.keyPressed(vt320.KEY_UP, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_UP, ' ', getStateForBuffer());
                         }
 
                         metaState &= ~META_TRANSIENT;
@@ -544,12 +544,10 @@
                     }
                     else {
                         if ((metaState & META_ALT_MASK) != 0) {
-                            buffer.keyPressed(vt320.KEY_PAGE_DOWN, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_PAGE_DOWN, ' ', getStateForBuffer());
                         }
                         else {
-                            buffer.keyPressed(vt320.KEY_DOWN, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_DOWN, ' ', getStateForBuffer());
                         }
 
                         metaState &= ~META_TRANSIENT;
@@ -565,12 +563,10 @@
                     }
                     else {
                         if ((metaState & META_ALT_MASK) != 0) {
-                            buffer.keyPressed(vt320.KEY_END, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_END, ' ', getStateForBuffer());
                         }
                         else {
-                            buffer.keyPressed(vt320.KEY_RIGHT, ' ',
-                                              getStateForBuffer());
+                            buffer.keyPressed(vt320.KEY_RIGHT, ' ', getStateForBuffer());
                         }
 
                         metaState &= ~META_TRANSIENT;
@@ -612,7 +608,7 @@
             metaPress(META_CTRL_ON);
         }
         else if (PreferenceConstants.HWBUTTON_TAB.equals(shortcut)) {
-            buffer.write(0x09);
+            buffer.keyPressed(vt320.KEY_TAB, ' ',  getStateForBuffer());
         }
         else if (PreferenceConstants.HWBUTTON_CTRLA_SPACE.equals(shortcut)) {
             buffer.write(0x01);
@@ -623,10 +619,10 @@
         }
         else if (PreferenceConstants.HWBUTTON_ESC.equals(shortcut)) {
             showMetakeyToast(v, PreferenceConstants.HWBUTTON_ESC);
-            buffer.write(0x1b);
+            sendEscape();
         }
         else if (PreferenceConstants.HWBUTTON_ESC_A.equals(shortcut)) {
-            buffer.write(0x1b);
+            sendEscape();
             buffer.write('a');
         }
         else {
@@ -901,7 +897,7 @@
         }
         else {
             if ((metaState & META_CTRL_ON) != 0) {
-                buffer.write(0x1b);
+                sendEscape();
                 metaState &= ~META_CTRL_ON;
             }
             else
@@ -911,7 +907,7 @@
         bridge.redraw();
     }
 
-    private boolean customKeymapAction(View v, int keyCode, KeyEvent event) {
+    protected boolean customKeymapAction(View v, int keyCode, KeyEvent event) {
         if (bridge == null || customKeyboard.equals(PreferenceConstants.CUSTOM_KEYMAP_DISABLED))
             return false;
 
@@ -941,7 +937,7 @@
                         // screen (-1) or the Asus Transformer Keyboard Dock.
                         // Treat the HW button as ESC.
                         if (event.getDeviceId() > 0) {
-                            buffer.write(0x1b);
+                            sendEscape();
                             return true;
                         }
                     }
@@ -1035,12 +1031,14 @@
             // Samsung Captivate Glide (SGH-i927)
             if (keyCode == 115) {
                 // .com key = ESC
-                c = 0x1b;
+                c = 0x00;
+                termKey = vt320.KEY_ESCAPE;
                 return true;
             }
             else if (keyCode == 116) {
                 // Microphone key = TAB
-                c = 0x09;
+                c = 0x00;
+                termKey = vt320.KEY_TAB;
             }
             else if ((metaState & META_ALT_MASK) != 0 && (metaState & META_SHIFT_MASK) != 0) {
                 switch (keyCode) {
@@ -1066,11 +1064,13 @@
             // Samsung Captivate Glide (SGH-i927) Ice Cream Sandwich (4.0.x)
             if (keyCode == 226) {
                 // .com key = ESC
-                c = 0x1b;
+                c = 0x00;
+                termKey = vt320.KEY_ESCAPE;
             }
             else if (keyCode == 220) {
                 // Microphone key = TAB
-                c = 0x09;
+                c = 0x00;
+                termKey = vt320.KEY_TAB;
             }
             else if ((metaState & META_ALT_MASK) != 0 && (metaState & META_SHIFT_MASK) != 0) {
                 switch (keyCode) {
--- a/src/com/five_ten_sg/connectbot/transport/TN5250.java	Wed Jun 11 12:18:18 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/transport/TN5250.java	Wed Jun 11 13:37:02 2014 -0700
@@ -42,6 +42,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.util.Log;
+import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
 import de.mud.terminal.vt320;
@@ -68,10 +69,63 @@
 
 
     class vt320x5250 extends vt320 {
+        private HashMap<Integer, String> mnemonics;
+
+        public vt320x5250(int width, int height) {
+            super(width, height);
+            mnemonics = new HashMap<Integer, String>();
+            mnemonics.put(KEY_PAUSE       , "[attn]");
+            mnemonics.put(KEY_F1          , "[pf1]");
+            mnemonics.put(KEY_F2          , "[pf2]");
+            mnemonics.put(KEY_F3          , "[pf3]");
+            mnemonics.put(KEY_F4          , "[pf4]");
+            mnemonics.put(KEY_F5          , "[pf5]");
+            mnemonics.put(KEY_F6          , "[pf6]");
+            mnemonics.put(KEY_F7          , "[pf7]");
+            mnemonics.put(KEY_F8          , "[pf8]");
+            mnemonics.put(KEY_F9          , "[pf9]");
+            mnemonics.put(KEY_F10         , "[pf10]");
+            mnemonics.put(KEY_F11         , "[pf11]");
+            mnemonics.put(KEY_F12         , "[pf12]");
+            mnemonics.put(KEY_UP          , "[up]");
+            mnemonics.put(KEY_DOWN        , "[down]");
+            mnemonics.put(KEY_LEFT        , "[left]");
+            mnemonics.put(KEY_RIGHT       , "[right]");
+            mnemonics.put(KEY_PAGE_DOWN   , "[pgdown]");
+            mnemonics.put(KEY_PAGE_UP     , "[pgup]");
+            mnemonics.put(KEY_INSERT      , "[insert]");
+            mnemonics.put(KEY_DELETE      , "[delete]");
+            mnemonics.put(KEY_BACK_SPACE  , "[backspace]");
+            mnemonics.put(KEY_HOME        , "[home]");
+            mnemonics.put(KEY_END         , "[end]");
+            mnemonics.put(KEY_NUM_LOCK    , "");
+            mnemonics.put(KEY_CAPS_LOCK   , "");
+            mnemonics.put(KEY_SHIFT       , "");
+            mnemonics.put(KEY_CONTROL     , "");
+            mnemonics.put(KEY_ALT         , "");
+            mnemonics.put(KEY_ENTER       , "");
+            mnemonics.put(KEY_NUMPAD0     , "0");
+            mnemonics.put(KEY_NUMPAD1     , "1");
+            mnemonics.put(KEY_NUMPAD2     , "2");
+            mnemonics.put(KEY_NUMPAD3     , "3");
+            mnemonics.put(KEY_NUMPAD4     , "4");
+            mnemonics.put(KEY_NUMPAD5     , "5");
+            mnemonics.put(KEY_NUMPAD6     , "6");
+            mnemonics.put(KEY_NUMPAD7     , "7");
+            mnemonics.put(KEY_NUMPAD8     , "8");
+            mnemonics.put(KEY_NUMPAD9     , "9");
+            mnemonics.put(KEY_DECIMAL     , ".");
+            mnemonics.put(KEY_ADD         , "+");
+            mnemonics.put(KEY_ESCAPE      , "");
+            mnemonics.put(KEY_TAB         , "[tab]");
+        }
+
         @Override
         public void debug(String s) {
             Log.d(TAG, s);
         }
+
+        // terminal key listener sending to the host
         @Override
         public void write(byte[] b) {
             screen52.sendKeys(new String(b));
@@ -80,7 +134,15 @@
         public void write(int b) {
             screen52.sendKeys(new String(new byte[] {(byte)b}));
         }
-        // bridge.monitor placement of new characters
+        @Override
+        public void keyPressed(int keyCode, char keyChar, int modifiers) {
+            String s;
+            if (mnemonics.containsKey(keyCode)) {
+                s = mnemonics.get(keyCode);
+                if (s != "") screen52.sendKeys(s);
+            }
+        }
+        // 5250 writing to the screen
         @Override
         public void putChar(int c, int l, char ch, int attributes) {
             if (bridge.monitor != null) bridge.monitor.screenChanged(l, c);
@@ -94,487 +156,9 @@
     };
 
 
-    class Terminal5250KeyListener extends TerminalKeyListener {
-        public Terminal5250KeyListener(TerminalManager manager,
-                                       TerminalBridge bridge,
-                                       vt320 buffer,
-                                       String encoding) {
-            super(manager, bridge, buffer, encoding);
-        }
-
-        /**
-         * Handle onKey() events coming down from a {@link com.five_ten_sg.connectbot.TerminalView} above us.
-         * Modify the keys to make more sense to a host then pass it to the 5250.
-         */
-        public boolean onKey(View v, int keyCode, KeyEvent event) {
-            try {
-                // skip keys if we aren't connected yet or have been disconnected
-                if (bridge.isDisconnected()) return false;
-
-                // Ignore all key-up events except for the special keys
-                if (event.getAction() == KeyEvent.ACTION_UP) {
-                    // There's nothing here for virtual keyboard users.
-                    if (!hardKeyboard || hardKeyboardHidden) return false;
-
-                    // if keycode debugging enabled, log and print the pressed key
-                    if (prefs.getBoolean(PreferenceConstants.DEBUG_KEYCODES, false)) {
-                        String keyCodeString = String.format(": %d", keyCode);
-                        String toastText = v.getContext().getString(R.string.keycode_pressed) + keyCodeString;
-                        Log.d(TAG, toastText);
-                    }
-
-                    if (fullKeyboard()) {
-                        switch (keyCode) {
-                            case KeyEvent.KEYCODE_CTRL_LEFT:
-                            case KeyEvent.KEYCODE_CTRL_RIGHT:
-                                metaKeyUp(META_CTRL_ON);
-                                return true;
-
-                            case KeyEvent.KEYCODE_ALT_LEFT:
-                            case KeyEvent.KEYCODE_ALT_RIGHT:
-                                metaKeyUp(META_ALT_ON);
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_LEFT:
-                            case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                                metaKeyUp(META_SHIFT_ON);
-                                return true;
-
-                            default:
-                        }
-                    }
-                    else if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
-                        if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT
-                                && (metaState & META_SLASH) != 0) {
-                            metaState &= ~(META_SLASH | META_TRANSIENT);
-                            buffer.write('/');
-                            return true;
-                        }
-                        else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
-                                 && (metaState & META_TAB) != 0) {
-                            metaState &= ~(META_TAB | META_TRANSIENT);
-                            sendEncoded("[tab]");
-                            return true;
-                        }
-                    }
-                    else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
-                        if (keyCode == KeyEvent.KEYCODE_ALT_LEFT
-                                && (metaState & META_SLASH) != 0) {
-                            metaState &= ~(META_SLASH | META_TRANSIENT);
-                            buffer.write('/');
-                            return true;
-                        }
-                        else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
-                                 && (metaState & META_TAB) != 0) {
-                            metaState &= ~(META_TAB | META_TRANSIENT);
-                            sendEncoded("[tab]");
-                            return true;
-                        }
-                    }
-
-                    return false;
-                }
-
-                bridge.resetScrollPosition();
-
-                if (keyCode == KeyEvent.KEYCODE_UNKNOWN &&
-                        event.getAction() == KeyEvent.ACTION_MULTIPLE) {
-                    byte[] input = event.getCharacters().getBytes(encoding);
-                    buffer.write(input);
-                    return true;
-                }
-
-                int curMetaState = event.getMetaState();
-                final int orgMetaState = curMetaState;
-
-                if ((metaState & META_SHIFT_MASK) != 0) {
-                    curMetaState |= KeyEvent.META_SHIFT_ON;
-                }
-
-                if ((metaState & META_ALT_MASK) != 0) {
-                    curMetaState |= KeyEvent.META_ALT_ON;
-                }
-
-                int uchar = event.getUnicodeChar(curMetaState);
-
-                // no hard keyboard?  ALT-k should pass through to below
-                if ((orgMetaState & KeyEvent.META_ALT_ON) != 0 &&
-                        (!hardKeyboard || hardKeyboardHidden)) {
-                    uchar = 0;
-                }
-
-                if ((uchar & KeyCharacterMap.COMBINING_ACCENT) != 0) {
-                    mDeadKey = uchar & KeyCharacterMap.COMBINING_ACCENT_MASK;
-                    return true;
-                }
-
-                if (mDeadKey != 0 && uchar != 0) {
-                    uchar = KeyCharacterMap.getDeadChar(mDeadKey, uchar);
-                    mDeadKey = 0;
-                }
-
-                // handle customized keymaps
-                if (customKeymapAction(v, keyCode, event))
-                    return true;
-
-                if (v != null) {
-                    //Show up the CharacterPickerDialog when the SYM key is pressed
-                    if ((isSymKey(keyCode) || uchar == KeyCharacterMap.PICKER_DIALOG_INPUT)) {
-                        bridge.showCharPickerDialog();
-
-                        if (metaState == 4) { // reset fn-key state
-                            metaState = 0;
-                            bridge.redraw();
-                        }
-
-                        return true;
-                    }
-                    else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
-                        //Show up the URL scan dialog when the search key is pressed
-                        urlScan(v);
-                        return true;
-                    }
-                }
-
-                // otherwise pass through to existing session
-                // print normal keys
-                if (uchar > 0x00 && keyCode != KeyEvent.KEYCODE_ENTER) {
-                    metaState &= ~(META_SLASH | META_TAB);
-                    // Remove shift and alt modifiers
-                    final int lastMetaState = metaState;
-                    metaState &= ~(META_SHIFT_ON | META_ALT_ON);
-
-                    if (metaState != lastMetaState) {
-                        bridge.redraw();
-                    }
-
-                    if ((metaState & META_CTRL_MASK) != 0) {
-                        metaState &= ~META_CTRL_ON;
-                        bridge.redraw();
-
-                        // If there is no hard keyboard or there is a hard keyboard currently hidden,
-                        // CTRL-1 through CTRL-9 will send F1 through F9
-                        if ((!hardKeyboard || hardKeyboardHidden) && sendFunctionKey(keyCode))
-                            return true;
-
-                        uchar = keyAsControl(uchar);
-                    }
-
-                    // handle pressing f-keys
-                    if ((hardKeyboard && !hardKeyboardHidden)
-                            && (curMetaState & KeyEvent.META_ALT_ON) != 0
-                            && (curMetaState & KeyEvent.META_SHIFT_ON) != 0
-                            && sendFunctionKey(keyCode))
-                        return true;
-
-                    if (uchar < 0x80)
-                        buffer.write(uchar);
-                    else
-                        sendEncoded(new String(Character.toChars(uchar)));
-
-                    return true;
-                }
-
-                // send ctrl and meta-keys as appropriate
-                if (!hardKeyboard || hardKeyboardHidden) {
-                    int k = event.getUnicodeChar(0);
-                    int k0 = k;
-                    boolean sendCtrl = false;
-                    boolean sendMeta = false;
-
-                    if (k != 0) {
-                        if ((orgMetaState & HC_META_CTRL_ON) != 0) {
-                            k = keyAsControl(k);
-
-                            if (k != k0)
-                                sendCtrl = true;
-
-                            // send F1-F10 via CTRL-1 through CTRL-0
-                            if (!sendCtrl && sendFunctionKey(keyCode))
-                                return true;
-                        }
-                        else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) {
-                            sendMeta = true;
-                            buffer.write(0x1b);
-                        }
-
-                        if (sendMeta || sendCtrl) {
-                            buffer.write(k);
-                            return true;
-                        }
-                    }
-                }
-
-                // handle meta and f-keys for full hardware keyboard
-                if (hardKeyboard && !hardKeyboardHidden && fullKeyboard()) {
-                    int k = event.getUnicodeChar(orgMetaState & KeyEvent.META_SHIFT_ON);
-                    int k0 = k;
-
-                    if (k != 0) {
-                        if ((orgMetaState & HC_META_CTRL_ON) != 0) {
-                            k = keyAsControl(k);
-
-                            if (k != k0)
-                                buffer.write(k);
-
-                            return true;
-                        }
-                        else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) {
-                            buffer.write(0x1b);
-                            buffer.write(k);
-                            return true;
-                        }
-                    }
-
-                    if (sendFullSpecialKey(keyCode))
-                        return true;
-                }
-
-                // try handling keymode shortcuts
-                if (hardKeyboard && !hardKeyboardHidden &&
-                        event.getRepeatCount() == 0) {
-                    if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
-                        switch (keyCode) {
-                            case KeyEvent.KEYCODE_ALT_RIGHT:
-                                metaState |= META_SLASH;
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                                metaState |= META_TAB;
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_LEFT:
-                                metaPress(META_SHIFT_ON);
-                                return true;
-
-                            case KeyEvent.KEYCODE_ALT_LEFT:
-                                metaPress(META_ALT_ON);
-                                return true;
-                        }
-                    }
-                    else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
-                        switch (keyCode) {
-                            case KeyEvent.KEYCODE_ALT_LEFT:
-                                metaState |= META_SLASH;
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_LEFT:
-                                metaState |= META_TAB;
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                                metaPress(META_SHIFT_ON);
-                                return true;
-
-                            case KeyEvent.KEYCODE_ALT_RIGHT:
-                                metaPress(META_ALT_ON);
-                                return true;
-                        }
-                    }
-                    else {
-                        switch (keyCode) {
-                            case KeyEvent.KEYCODE_ALT_RIGHT:
-                            case KeyEvent.KEYCODE_ALT_LEFT:
-                                metaPress(META_ALT_ON);
-                                return true;
-
-                            case KeyEvent.KEYCODE_SHIFT_LEFT:
-                            case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                                metaPress(META_SHIFT_ON);
-                                return true;
-                        }
-                    }
-
-                    // Handle hardware CTRL keys
-                    if (keyCode == KeyEvent.KEYCODE_CTRL_LEFT ||
-                            keyCode == KeyEvent.KEYCODE_CTRL_RIGHT) {
-                        ctrlKeySpecial();
-                        return true;
-                    }
-                }
-
-                // look for special chars
-                switch (keyCode) {
-                    case KEYCODE_ESCAPE:
-                        buffer.write(0x1b);
-                        return true;
-
-                    case KeyEvent.KEYCODE_TAB:
-                        sendEncoded("[tab]");
-                        return true;
-
-                    case KEYCODE_PAGE_DOWN:
-                        sendEncoded("[pgdown]");
-                        metaState &= ~META_TRANSIENT;
-                        bridge.tryKeyVibrate();
-                        return true;
-
-                    case KEYCODE_PAGE_UP:
-                        sendEncoded("[pgup]");
-                        metaState &= ~META_TRANSIENT;
-                        bridge.tryKeyVibrate();
-                        return true;
-
-                    case KeyEvent.KEYCODE_MOVE_HOME:
-                        sendEncoded("[home]");
-                        metaState &= ~META_TRANSIENT;
-                        bridge.tryKeyVibrate();
-                        return true;
-
-                    case KeyEvent.KEYCODE_MOVE_END:
-                        sendEncoded("[end]");  // does not exist!!
-                        metaState &= ~META_TRANSIENT;
-                        bridge.tryKeyVibrate();
-                        return true;
-
-                    case KeyEvent.KEYCODE_CAMERA:
-                        // check to see which shortcut the camera button triggers
-                        String hwbuttonShortcut = manager.prefs.getString(
-                                                      PreferenceConstants.CAMERA,
-                                                      PreferenceConstants.HWBUTTON_SCREEN_CAPTURE);
-                        return (handleShortcut(v, hwbuttonShortcut));
-
-                    case KeyEvent.KEYCODE_VOLUME_UP:
-                        // check to see which shortcut the volume button triggers
-                        hwbuttonShortcut = manager.prefs.getString(
-                                               PreferenceConstants.VOLUP,
-                                               PreferenceConstants.HWBUTTON_CTRL);
-                        return (handleShortcut(v, hwbuttonShortcut));
-
-                    case KeyEvent.KEYCODE_VOLUME_DOWN:
-                        // check to see which shortcut the camera button triggers
-                        hwbuttonShortcut = manager.prefs.getString(
-                                               PreferenceConstants.VOLDN,
-                                               PreferenceConstants.HWBUTTON_TAB);
-                        return (handleShortcut(v, hwbuttonShortcut));
-
-                    case KeyEvent.KEYCODE_SEARCH:
-                        // check to see which shortcut the search button triggers
-                        hwbuttonShortcut = manager.prefs.getString(
-                                               PreferenceConstants.SEARCH,
-                                               PreferenceConstants.HWBUTTON_ESC);
-                        return (handleShortcut(v, hwbuttonShortcut));
-
-                    case KeyEvent.KEYCODE_DEL:
-                        if ((metaState & META_ALT_MASK) != 0) {
-                            sendEncoded("[insert]");
-                        }
-                        else {
-                            sendEncoded("[backspace]");
-                        }
-
-                        metaState &= ~META_TRANSIENT;
-                        return true;
-
-                    case KeyEvent.KEYCODE_ENTER:
-                        sendEncoded("[enter]");
-                        metaState &= ~META_TRANSIENT;
-                        return true;
-
-                    case KeyEvent.KEYCODE_DPAD_LEFT:
-                        if (selectingForCopy) {
-                            selectionArea.decrementColumn();
-                            bridge.redraw();
-                        }
-                        else {
-                            if ((metaState & META_ALT_MASK) != 0) {
-                                sendEncoded("[home]");
-                            }
-                            else {
-                                sendEncoded("[left]");
-                            }
-
-                            metaState &= ~META_TRANSIENT;
-                            bridge.tryKeyVibrate();
-                        }
-
-                        return true;
-
-                    case KeyEvent.KEYCODE_DPAD_UP:
-                        if (selectingForCopy) {
-                            selectionArea.decrementRow();
-                            bridge.redraw();
-                        }
-                        else {
-                            if ((metaState & META_ALT_MASK) != 0) {
-                                sendEncoded("[pgup]");
-                            }
-                            else {
-                                sendEncoded("[up]");
-                            }
-
-                            metaState &= ~META_TRANSIENT;
-                            bridge.tryKeyVibrate();
-                        }
-
-                        return true;
-
-                    case KeyEvent.KEYCODE_DPAD_DOWN:
-                        if (selectingForCopy) {
-                            selectionArea.incrementRow();
-                            bridge.redraw();
-                        }
-                        else {
-                            if ((metaState & META_ALT_MASK) != 0) {
-                                sendEncoded("[pgdown]");
-                            }
-                            else {
-                                sendEncoded("[down]");
-                            }
-
-                            metaState &= ~META_TRANSIENT;
-                            bridge.tryKeyVibrate();
-                        }
-
-                        return true;
-
-                    case KeyEvent.KEYCODE_DPAD_RIGHT:
-                        if (selectingForCopy) {
-                            selectionArea.incrementColumn();
-                            bridge.redraw();
-                        }
-                        else {
-                            if ((metaState & META_ALT_MASK) != 0) {
-                                sendEncoded("[end]");   // does not exist!!
-                            }
-                            else {
-                                sendEncoded("[right]");
-                            }
-
-                            metaState &= ~META_TRANSIENT;
-                            bridge.tryKeyVibrate();
-                        }
-
-                        return true;
-
-                    case KeyEvent.KEYCODE_DPAD_CENTER:
-                        ctrlKeySpecial();
-                        return true;
-                }
-            }
-            catch (IOException e) {
-                Log.e(TAG, "Problem while trying to handle an onKey() event", e);
-
-                try {
-                    flush();
-                }
-                catch (IOException ioe) {
-                    Log.d(TAG, "Our transport was closed, dispatching disconnect event");
-                    bridge.dispatchDisconnect(false);
-                }
-            }
-            catch (NullPointerException npe) {
-                Log.d(TAG, "Input before connection established ignored.");
-                return true;
-            }
-        }
-
-    };
-
-
     public TN5250() {
        super();
-   }
+    }
 
 
     /**
@@ -824,7 +408,7 @@
     }
 
     public TerminalKeyListener getTerminalKeyListener() {
-        return new Terminal5250KeyListener(manager, bridge, buffer, host.getEncoding());
+        return new TerminalKeyListener(manager, bridge, buffer, host.getEncoding());
     }
 
 }
--- a/src/de/mud/terminal/vt320.java	Wed Jun 11 12:18:18 2014 -0700
+++ b/src/de/mud/terminal/vt320.java	Wed Jun 11 13:37:02 2014 -0700
@@ -739,8 +739,9 @@
     public final static int KEY_NUMPAD8 = 39;
     public final static int KEY_NUMPAD9 = 40;
     public final static int KEY_DECIMAL = 41;
-    public final static int KEY_ADD = 42;
-    public final static int KEY_ESCAPE = 43;
+    public final static int KEY_ADD     = 42;
+    public final static int KEY_ESCAPE  = 43;
+    public final static int KEY_TAB     = 44;
 
     public final static int DELETE_IS_DEL = 0;
     public final static int DELETE_IS_BACKSPACE = 1;
@@ -1092,12 +1093,20 @@
 
             case KEY_CAPS_LOCK:
                 capslock = !capslock;
-                return;
+                break;
 
             case KEY_SHIFT:
             case KEY_CONTROL:
             case KEY_ALT:
-                return;
+                break;
+
+            case KEY_ESCAPE:
+                write(0x1b);
+                break;
+
+            case KEY_TAB:
+                write(0x09);
+                break;
 
             default:
                 break;