diff src/com/five_ten_sg/connectbot/service/TerminalBridge.java @ 79:01d939969b10

merge tn5250 branch into default
author Carl Byington <carl@five-ten-sg.com>
date Mon, 16 Jun 2014 08:24:00 -0700
parents 1588e359a972 99d5b02ad90c
children 33eb63352be5
line wrap: on
line diff
--- a/src/com/five_ten_sg/connectbot/service/TerminalBridge.java	Tue Jun 03 08:48:14 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/service/TerminalBridge.java	Mon Jun 16 08:24:00 2014 -0700
@@ -95,13 +95,12 @@
 
     private Relay relay;
 
-    private final String emulation;
-    private final int scrollback;
+    private String emulation;   // aka answerback string, aka terminal type
 
     public Bitmap bitmap = null;
     public vt320  buffer = null;
 
-    private TerminalView parent = null;
+    public  TerminalView parent = null;
     private final Canvas canvas = new Canvas();
 
     private boolean disconnected = false;
@@ -120,11 +119,10 @@
     // TODO add support for the new clipboard API
     private ClipboardManager clipboard;
 
-    public int charWidth = -1;
-    public int charHeight = -1;
-    private int charTop = -1;
-
-    private float fontSize = -1;
+    public  int   charWidth  = -1;
+    public  int   charHeight = -1;
+    private int   charTop    = -1;
+    private float fontSize   = -1;
 
     private final List<FontSizeChangedListener> fontSizeChangedListeners;
 
@@ -160,7 +158,6 @@
         manager = null;
         defaultPaint = new Paint();
         selectionArea = new SelectionArea();
-        scrollback = 1;
         localOutput = new LinkedList<String>();
         fontSizeChangedListeners = new LinkedList<FontSizeChangedListener>();
         transport   = null;
@@ -169,16 +166,14 @@
     }
 
     /**
-     * Create new terminal bridge with following parameters. We will immediately
-     * launch thread to start SSH connection and handle any hostkey verification
-     * and password authentication.
+     * Create new terminal bridge with following parameters.
      */
     public TerminalBridge(final TerminalManager manager, final HostBean host) throws IOException {
         float hostFontSize;
         this.manager = manager;
         this.host = host;
-        emulation = manager.getEmulation();
-        scrollback = manager.getScrollback();
+        emulation = host.getHostEmulation();
+        if ((emulation == null) || (emulation.length() == 0)) emulation = manager.getEmulation();
         // create prompt helper to relay password and hostkey requests up to gui
         promptHelper = new PromptHelper(this);
         // create our default paint
@@ -191,128 +186,20 @@
         Integer defaultFontSize = Integer.parseInt(manager.prefs.getString(PreferenceConstants.DEFAULT_FONT_SIZE, "-1"));
         Log.i(TAG, "fontSize: " + this.fontSize + ", defaultFontSize: " + defaultFontSize);
 
-        if (this.fontSize == -1) {
+        if (fontSize == -1) {
             if (defaultFontSize > 0 && host.getFontSize() == -1)
                 hostFontSize = defaultFontSize;
             else
                 hostFontSize = host.getFontSize();
         }
         else
-            hostFontSize = this.fontSize;
+            hostFontSize = fontSize;
 
-        if (hostFontSize <= 0)
-            hostFontSize = DEFAULT_FONT_SIZE;
+        if (hostFontSize <= 0) hostFontSize = DEFAULT_FONT_SIZE;
 
         setFontSize(hostFontSize);
-        // create terminal buffer and handle outgoing data
-        // this is probably status reply information
-        buffer = new vt320() {
-            @Override
-            public void debug(String s) {
-                Log.d(TAG, s);
-            }
-            @Override
-            public void write(byte[] b) {
-                try {
-                    if (b != null && transport != null) {
-                        if (monitor != null) monitor.hostData(b);
-                        transport.write(b);
-                    }    
-                }
-                catch (IOException e) {
-                    Log.e(TAG, "Problem writing outgoing data in vt320() thread", e);
-                }
-            }
-            @Override
-            public void write(int b) {
-                try {
-                    if (transport != null) {
-                        if (monitor != null) monitor.hostData(b);
-                        transport.write(b);
-                    }    
-                }
-                catch (IOException e) {
-                    Log.e(TAG, "Problem writing outgoing data in vt320() thread", e);
-                }
-            }
-            // We don't use telnet sequences.
-            @Override
-            public void sendTelnetCommand(byte cmd) {
-            }
-            // We don't want remote to resize our window.
-            @Override
-            public void setWindowSize(int c, int r) {
-            }
-            // test for changed screen contents
-            @Override
-            public void testChanged() {
-                if (monitor != null) monitor.testChanged();
-            }
-            // play beep noise
-            @Override
-            public void beep() {
-                if (parent.isShown())
-                    manager.playBeep();
-                else
-                    manager.sendActivityNotification(host);
-            }
-            // monitor placement of new characters
-            @Override
-            public void putChar(int c, int l, char ch, int attributes) {
-                if (monitor != null) monitor.screenChanged(l, c);
-
-                super.putChar(c, l, ch, attributes);
-            }
-            @Override
-            public void insertChar(int c, int l, char ch, int attributes) {
-                if (monitor != null) monitor.screenChanged(l, l, c, width - 1);
-
-                super.insertChar(c, l, ch, attributes);
-            }
-            @Override
-            public void insertLine(int l, int n, boolean scrollDown) {
-                if (monitor != null) {
-                    if (scrollDown) monitor.screenChanged(l, height - 1, 0, width - 1);
-                    else            monitor.screenChanged(0, l, 0, width - 1);
-                }
-
-                super.insertLine(l, n, scrollDown);
-            }
-            @Override
-            public void deleteLine(int l) {
-                if (monitor != null) monitor.screenChanged(l, height - 1, 0, width - 1);
-
-                super.deleteLine(l);
-            }
-            @Override
-            public void deleteChar(int c, int l) {
-                if (monitor != null) monitor.screenChanged(l, l, c, width - 1);
-
-                super.deleteChar(c, l);
-            }
-            @Override
-            public void setCursorPosition(int c, int l) {
-                if (monitor != null) monitor.cursorMove(l, c);
-
-                super.setCursorPosition(c, l);
-            }
-        };
-
-        // Don't keep any scrollback if a session is not being opened.
-        if (host.getWantSession())
-            buffer.setBufferSize(scrollback);
-        else
-            buffer.setBufferSize(0);
-
         resetColors();
-        buffer.setDisplay(this);
         selectionArea = new SelectionArea();
-        keyListener   = new TerminalKeyListener(manager, this, buffer, host.getEncoding());
-
-        String monitor_init = host.getMonitor();
-        if ((monitor_init != null) && (monitor_init.length() > 0)) {
-            monitor = new TerminalMonitor(manager, buffer, keyListener, parent, monitor_init);
-        }
     }
 
     public PromptHelper getPromptHelper() {
@@ -323,15 +210,19 @@
      * Spawn thread to open connection and start login process.
      */
     protected void startConnection() {
-        transport = TransportFactory.getTransport(host.getProtocol());
-        transport.setBridge(this);
-        transport.setManager(manager);
-        transport.setHost(host);
-        // TODO make this more abstract so we don't litter on AbsTransport
+        transport   = TransportFactory.getTransport(host.getProtocol());
+        transport.setLinks(manager, this, host, emulation);
+        buffer      = transport.getTransportBuffer();
+        keyListener = transport.getTerminalKeyListener();
+
+        String monitor_init = host.getMonitor();
+        if ((monitor_init != null) && (monitor_init.length() > 0)) {
+            monitor = new TerminalMonitor(manager, buffer, keyListener, parent, monitor_init);
+        }
+
         transport.setCompression(host.getCompression());
         transport.setHttpproxy(host.getHttpproxy());
         transport.setUseAuthAgent(host.getUseAuthAgent());
-        transport.setEmulation(emulation);
 
         if (transport.canForwardPorts()) {
             for (PortForwardBean portForward : manager.hostdb.getPortForwardsForHost(host))
@@ -367,7 +258,8 @@
      * @return charset in use by bridge
      */
     public Charset getCharset() {
-        return relay.getCharset();
+        if (relay != null) return relay.getCharset();
+        return keyListener.getCharset();
     }
 
     /**
@@ -376,9 +268,7 @@
      * @param encoding the canonical name of the character encoding
      */
     public void setCharset(String encoding) {
-        if (relay != null)
-            relay.setCharset(encoding);
-
+        if (relay != null) relay.setCharset(encoding);
         keyListener.setCharset(encoding);
     }
 
@@ -429,11 +319,8 @@
     public void onConnected() {
         disconnected = false;
         buffer.reset();
-        // We no longer need our local output.
-        localOutput.clear();
-        // previously tried vt100 and xterm for emulation modes
-        // "screen" works the best for color and escape codes
         buffer.setAnswerBack(emulation);
+        localOutput.clear();    // We no longer need our local output.
 
         if (HostDatabase.DELKEY_BACKSPACE.equals(host.getDelKey()))
             buffer.setBackspace(vt320.DELETE_IS_BACKSPACE);
@@ -441,11 +328,15 @@
             buffer.setBackspace(vt320.DELETE_IS_DEL);
 
         // create thread to relay incoming connection data to buffer
-        relay = new Relay(this, transport, buffer, host.getEncoding());
-        Thread relayThread = new Thread(relay);
-        relayThread.setDaemon(true);
-        relayThread.setName("Relay");
-        relayThread.start();
+        // only if needed by the transport
+        if (transport.needsRelay()) {
+            relay = new Relay(this, transport, buffer, host.getEncoding());
+            Thread relayThread = new Thread(relay);
+            relayThread.setDaemon(true);
+            relayThread.setName("Relay");
+            relayThread.start();
+        }
+
         // force font-size to make sure we resizePTY as needed
         setFontSize(fontSize);
         // finally send any post-login string, if requested
@@ -563,8 +454,7 @@
         charHeight = (int)FloatMath.ceil(fm.descent - fm.top);
 
         // refresh any bitmap with new font size
-        if (parent != null)
-            parentChanged(parent);
+        if (parent != null) parentChanged(parent);
 
         for (FontSizeChangedListener ofscl : fontSizeChangedListeners)
             ofscl.onFontSizeChanged(size);
@@ -664,8 +554,10 @@
 
         try {
             // request a terminal pty resize
-            synchronized (buffer) {
-                buffer.setScreenSize(columns, rows, true);
+            if (buffer != null) {
+                synchronized (buffer) {
+                    buffer.setScreenSize(columns, rows, true);
+                }
             }
 
             if (transport != null)
@@ -675,7 +567,7 @@
             Log.e(TAG, "Problem while trying to resize screen or PTY", e);
         }
 
-        // redraw local output if we don't have a sesson to receive our resize request
+        // redraw local output if we don't have a session to receive our resize request
         if (transport == null) {
             synchronized (localOutput) {
                 buffer.reset();
@@ -1246,20 +1138,14 @@
                     buffer.keyPressed(vt320.KEY_UP, ' ', 0);
                 else if (result.equals("↓"))
                     buffer.keyPressed(vt320.KEY_DOWN, ' ', 0);
+                else if (result.equals("T"))
+                    buffer.keyPressed(vt320.KEY_TAB, ' ', 0);
                 else if (result.equals("I"))
                     buffer.keyPressed(vt320.KEY_INSERT, ' ', 0);
                 else if (result.equals("D"))
                     buffer.keyPressed(vt320.KEY_DELETE, ' ', 0);
                 else if (result.equals("E"))
-                    buffer.keyTyped(vt320.KEY_ENTER, ' ', 0);
-                else if (result.equals("T")) {
-                    try {
-                        transport.write(0x09);
-                    }
-                    catch (IOException e) {
-                        Log.e(TAG, "Problem with the arrowsDialog", e);
-                    }
-                }
+                    buffer.keyPressed(vt320.KEY_ENTER, ' ', 0);
             }
             @Override
             public void onItemClick(AdapterView p, View v, int pos, long id) {
@@ -1400,8 +1286,7 @@
                 else if (result.equals("0"))
                     key = vt320.KEY_F10;
 
-                if (key != 0)
-                    buffer.keyPressed(key, ' ', 0);
+                if (key != 0) buffer.keyPressed(key, ' ', 0);
 
                 dismiss();
             }
@@ -1496,10 +1381,7 @@
                         dismiss();
                         return true;
                     }
-
-//                  return keyListener.onKey(parent, event.getKeyCode(), event);
                 }
-
                 return super.dispatchKeyEvent(event);
             }
         };