changeset 49:8887bff45dee tn5250

start tn5250 integration
author Carl Byington <carl@five-ten-sg.com>
date Wed, 11 Jun 2014 11:28:31 -0700
parents 1e931ef5f776
children 2cd3d8091e37
files src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java src/com/five_ten_sg/connectbot/transport/TN5250.java
diffstat 2 files changed, 478 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java	Wed Jun 11 10:11:29 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java	Wed Jun 11 11:28:31 2014 -0700
@@ -45,7 +45,6 @@
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 import de.mud.terminal.VDUBuffer;
 import de.mud.terminal.vt320;
 
@@ -91,20 +90,14 @@
     private String customKeyboard = null;
 
     private int metaState = 0;
-
     private int mDeadKey = 0;
 
     // TODO add support for the new API.
     private ClipboardManager clipboard = null;
-
     private boolean selectingForCopy = false;
     private final SelectionArea selectionArea;
-
-
     private final SharedPreferences prefs;
 
-    private Toast debugToast = null;
-    private Toast metakeyToast = null;
 
     public TerminalKeyListener(TerminalManager manager,
                                TerminalBridge bridge,
@@ -149,13 +142,7 @@
                 if (prefs.getBoolean(PreferenceConstants.DEBUG_KEYCODES, false)) {
                     String keyCodeString = String.format(": %d", keyCode);
                     String toastText = v.getContext().getString(R.string.keycode_pressed) + keyCodeString;
-
-                    if (debugToast == null)
-                        debugToast = Toast.makeText(v.getContext(), toastText, Toast.LENGTH_LONG);
-                    else
-                        debugToast.setText(toastText);
-
-                    debugToast.show();
+                    Log.d(TAG, toastText);
                 }
 
                 if (fullKeyboard()) {
@@ -653,13 +640,7 @@
     }
 
     private void showMetakeyToast(View v, String keyname) {
-        if (metakeyToast == null)
-            metakeyToast = Toast.makeText(v.getContext(), keyname, Toast.LENGTH_LONG);
-        else
-            metakeyToast.setText(keyname);
-
-        metakeyToast.setGravity(Gravity.TOP | Gravity.RIGHT, 0, 0);
-        metakeyToast.show();
+        Log.d(TAG, keyname);
     }
 
     public int keyAsControl(int key) {
--- a/src/com/five_ten_sg/connectbot/transport/TN5250.java	Wed Jun 11 10:11:29 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/transport/TN5250.java	Wed Jun 11 11:28:31 2014 -0700
@@ -71,9 +71,11 @@
         }
         @Override
         public void write(byte[] b) {
+            screen52.sendKeys(new String(b));
         }
         @Override
         public void write(int b) {
+            screen52.sendKeys(new String(new byte[] {b}));
         }
         // bridge.monitor placement of new characters
         @Override
@@ -96,8 +98,482 @@
                                        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() || bridge.transport == null)
+                    return false;
+
+                final boolean hardKeyboardHidden = manager.hardKeyboardHidden;
+
+                // 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 || (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);
+                            buffer.write("[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);
+                            buffer.write("[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 || (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
+                        buffer.write(new String(Character.toChars(uchar)).getBytes(encoding));
+
+                    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:
+                        buffer.write("[tab]");
+                        return true;
+
+                    case KEYCODE_PAGE_DOWN:
+                        buffer.write("[pgdown]");
+                        metaState &= ~META_TRANSIENT;
+                        bridge.tryKeyVibrate();
+                        return true;
+
+                    case KEYCODE_PAGE_UP:
+                        buffer.write("[pgup]");
+                        metaState &= ~META_TRANSIENT;
+                        bridge.tryKeyVibrate();
+                        return true;
+
+                    case KeyEvent.KEYCODE_MOVE_HOME:
+                        buffer.write("[home]");
+                        metaState &= ~META_TRANSIENT;
+                        bridge.tryKeyVibrate();
+                        return true;
+
+                    case KeyEvent.KEYCODE_MOVE_END:
+                        buffer.write("[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) {
+                            buffer.write("[insert]");
+                        }
+                        else {
+                            buffer.write("[backspace]");
+                        }
+
+                        metaState &= ~META_TRANSIENT;
+                        return true;
+
+                    case KeyEvent.KEYCODE_ENTER:
+                        buffer.write("[enter]");
+                        metaState &= ~META_TRANSIENT;
+                        return true;
+
+                    case KeyEvent.KEYCODE_DPAD_LEFT:
+                        if (selectingForCopy) {
+                            selectionArea.decrementColumn();
+                            bridge.redraw();
+                        }
+                        else {
+                            if ((metaState & META_ALT_MASK) != 0) {
+                                buffer.write("[home]");
+                            }
+                            else {
+                                buffer.write("[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) {
+                                buffer.write("[pgup]");
+                            }
+                            else {
+                                buffer.write("[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) {
+                                buffer.write("[pgdown]");
+                            }
+                            else {
+                                buffer.write("[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) {
+                                buffer.write("[end]");
+                            }
+                            else {
+                                buffer.write("[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 {
+                    bridge.transport.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();
    }