diff options
| -rw-r--r-- | src/com/trilead/ssh2/channel/ChannelOutputStream.java | 9 | ||||
| -rw-r--r-- | src/de/mud/terminal/VDUBuffer.java | 51 | ||||
| -rw-r--r-- | src/de/mud/terminal/vt320.java | 34 | ||||
| -rw-r--r-- | src/org/connectbot/service/TerminalBridge.java | 58 | 
4 files changed, 94 insertions, 58 deletions
| diff --git a/src/com/trilead/ssh2/channel/ChannelOutputStream.java b/src/com/trilead/ssh2/channel/ChannelOutputStream.java index 3fd7214..30e8fd8 100644 --- a/src/com/trilead/ssh2/channel/ChannelOutputStream.java +++ b/src/com/trilead/ssh2/channel/ChannelOutputStream.java @@ -13,20 +13,21 @@ public final class ChannelOutputStream extends OutputStream  {
  	Channel c;
 +	private byte[] writeBuffer;
 +
  	boolean isClosed = false;
  	ChannelOutputStream(Channel c)
  	{
  		this.c = c;
 +		writeBuffer = new byte[1];
  	}
  	public void write(int b) throws IOException
  	{	
 -		byte[] buff = new byte[1];
 -		
 -		buff[0] = (byte) b;
 +		writeBuffer[0] = (byte) b;
 -		write(buff, 0, 1);
 +		write(writeBuffer, 0, 1);
  	}
  	public void close() throws IOException
 diff --git a/src/de/mud/terminal/VDUBuffer.java b/src/de/mud/terminal/VDUBuffer.java index 269f57e..e8f6617 100644 --- a/src/de/mud/terminal/VDUBuffer.java +++ b/src/de/mud/terminal/VDUBuffer.java @@ -32,7 +32,7 @@ import java.util.Arrays;   * all methods to manipulate the buffer that stores characters and their   * attributes as well as the regions displayed.   * - * @author Matthias L. Jugel, Marcus Mei�ner + * @author Matthias L. Jugel, Marcus Meißner   * @version $Id: VDUBuffer.java 503 2005-10-24 07:34:13Z marcus $   */  public class VDUBuffer { @@ -344,8 +344,8 @@ public class VDUBuffer {        if (n > (bottom - top)) n = (bottom - top);        int size = bottom - l - (n - 1);        if(size < 0) size = 0; -      cbuf = new char[size][width]; -      abuf = new int[size][width]; +      cbuf = new char[size][]; +      abuf = new int[size][];        System.arraycopy(charArray, oldBase + l, cbuf, 0, bottom - l - (n - 1));        System.arraycopy(charAttributes, oldBase + l, @@ -373,8 +373,8 @@ public class VDUBuffer {              bufSize += n;            } -          cbuf = new char[bufSize][width]; -          abuf = new int[bufSize][width]; +          cbuf = new char[bufSize][]; +          abuf = new int[bufSize][];          } else {            offset = n;            cbuf = charArray; @@ -482,15 +482,23 @@ public class VDUBuffer {      int bottom = (l > bottomMargin ? height - 1:              (l < topMargin?topMargin:bottomMargin + 1));      int numRows = bottom - l - 1; + +    char[] discardedChars = charArray[screenBase + l]; +    int[] discardedAttributes = charAttributes[screenBase + l]; +      if (numRows > 0) {  	    System.arraycopy(charArray, screenBase + l + 1,  	                     charArray, screenBase + l, numRows);  	    System.arraycopy(charAttributes, screenBase + l + 1,  	                     charAttributes, screenBase + l, numRows);      } -    charArray[screenBase + bottom - 1] = new char[width]; -    Arrays.fill(charArray[screenBase + bottom - 1], ' '); -    charAttributes[screenBase + bottom - 1] = new int[width]; + +    int newBottomRow = screenBase + bottom - 1; +    charArray[newBottomRow] = discardedChars; +    charAttributes[newBottomRow] = discardedAttributes; +    Arrays.fill(charArray[newBottomRow], ' '); +    Arrays.fill(charAttributes[newBottomRow], 0); +      markLine(l, bottom - l);    } @@ -510,15 +518,12 @@ public class VDUBuffer {      c = checkBounds(c, 0, width - 1);      l = checkBounds(l, 0, height - 1); -    char cbuf[] = new char[w]; -    int abuf[] = new int[w]; - -    Arrays.fill(cbuf, ' '); -     -    for (int i = 0; i < w; i++) abuf[i] = curAttr; +    int endColumn = c + w; +    int targetRow = screenBase + l;      for (int i = 0; i < h && l + i < height; i++) { -      System.arraycopy(cbuf, 0, charArray[screenBase + l + i], c, w); -      System.arraycopy(abuf, 0, charAttributes[screenBase + l + i], c, w); +      Arrays.fill(charAttributes[targetRow], c, endColumn, curAttr); +      Arrays.fill(charArray[targetRow], c, endColumn, ' '); +      targetRow++;      }      markLine(l, h);    } @@ -535,19 +540,7 @@ public class VDUBuffer {     * @see #redraw     */    public void deleteArea(int c, int l, int w, int h) { -    c = checkBounds(c, 0, width - 1); -    l = checkBounds(l, 0, height - 1); - -    char cbuf[] = new char[w]; -    int abuf[] = new int[w]; - -    Arrays.fill(cbuf, ' '); -     -    for (int i = 0; i < h && l + i < height; i++) { -      System.arraycopy(cbuf, 0, charArray[screenBase + l + i], c, w); -      System.arraycopy(abuf, 0, charAttributes[screenBase + l + i], c, w); -    } -    markLine(l, h); +    deleteArea(c, l, w, h, 0);    }    /** diff --git a/src/de/mud/terminal/vt320.java b/src/de/mud/terminal/vt320.java index dd43528..0e92523 100644 --- a/src/de/mud/terminal/vt320.java +++ b/src/de/mud/terminal/vt320.java @@ -56,6 +56,13 @@ public abstract class vt320 extends VDUBuffer implements VDUInput {    public abstract void write(byte[] b);    /** +   * Write an answer back to the remote host. This is needed to be able to +   * send terminal answers requests like status and type information. +   * @param b the array of bytes to be sent +   */ +  public abstract void write(int b); + +  /**     * Play the beep sound ...     */    public void beep() { /* do nothing by default */ @@ -511,6 +518,23 @@ public void setScreenSize(int c, int r, boolean broadcast) {      return true;    } +  private boolean write(int s, boolean doecho) { +    if (debug > 2) { +      debugStr.append("write(|") +        .append(s) +        .append("|,") +        .append(doecho); +      debug(debugStr.toString()); +      debugStr.setLength(0); +    } + +    write(s); + +    if (doecho) +      putChar((char)s, false); +    return true; +  } +    private boolean write(String s) {      return write(s, localecho);    } @@ -958,20 +982,20 @@ public void setScreenSize(int c, int r, boolean broadcast) {        return;      }      if (alt) { -      write("" + ((char) (keyChar | 0x80))); +      write(((char) (keyChar | 0x80)));        return;      }      if (((keyCode == KEY_ENTER) || (keyChar == 10))              && !control) { -      write("\r", false); +      write('\r');        if (localecho) putString("\r\n"); // bad hack        return;      }      if ((keyCode == 10) && !control) {        debug("Sending \\r"); -      write("\r", false); +      write('\r');        return;      } @@ -981,7 +1005,7 @@ public void setScreenSize(int c, int r, boolean broadcast) {      // if(((!vms && keyChar == '2') || keyChar == '@' || keyChar == ' ')      //    && control)      if (((!vms && keyChar == '2') || keyChar == ' ') && control) -      write("" + (char) 0); +      write(0);      if (vms) {        if (keyChar == 127 && !control) { @@ -1117,7 +1141,7 @@ public void setScreenSize(int c, int r, boolean broadcast) {        }      if (!((keyChar == 8) || (keyChar == 127) || (keyChar == '\r') || (keyChar == '\n'))) { -      write("" + keyChar); +      write(keyChar);        return;      }    } diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index 3e89316..3cf0109 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -203,9 +203,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  		final String encoding = host.getEncoding();  		public void run() { -			final byte[] b = new byte[BUFFER_SIZE]; -			final byte[] tmpBuff = new byte[BUFFER_SIZE]; -  			final Charset charset = Charset.forName(encoding);  			/* Set up character set decoder to report any byte sequences @@ -223,9 +220,13 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  			replacer.onUnmappableCharacter(CodingErrorAction.REPLACE);  			replacer.onMalformedInput(CodingErrorAction.REPLACE); -			ByteBuffer bb; +			ByteBuffer bb = ByteBuffer.allocate(BUFFER_SIZE);  			CharBuffer cb = CharBuffer.allocate(BUFFER_SIZE); +			final byte[] bba = bb.array(); +			final char[] cba = cb.array(); +			final byte[] tmpBuff = new byte[BUFFER_SIZE]; +  			int n = 0;  			int offset = 0; @@ -240,9 +241,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  					newConditions = session.waitForCondition(conditions, 0);  					if ((newConditions & ChannelCondition.STDOUT_DATA) != 0) {  						while (stdout.available() > 0) { -							n = offset + stdout.read(b, offset, BUFFER_SIZE - offset); +							n = offset + stdout.read(bba, offset, BUFFER_SIZE - offset); + +							bb.position(0); +							bb.limit(n); -							bb = ByteBuffer.wrap(b, 0, n);  							CoderResult cr = cd.decode(bb, cb, true);  							if (cr.isMalformed()) { @@ -252,20 +255,22 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  									/* There is good data before the malformed section, so  									 * pass this on immediately.  									 */ -									((vt320)buffer).putString(cb.array(), 0, cb.position()); +									((vt320)buffer).putString(cba, 0, cb.position());  								}  								while (bb.position() < n) { -									ByteBuffer replacebb = ByteBuffer.wrap(b, curpos, cr.length()); +									bb.position(curpos); +									bb.limit(curpos + cr.length());  									cb.clear(); -									replacer.decode(replacebb, cb, true); +									replacer.decode(bb, cb, true); -									((vt320) buffer).putString(cb.array(), 0, cb.position()); +									((vt320) buffer).putString(cba, 0, cb.position());  									curpos += cr.length();  									bb.position(curpos); +									cb.limit(n);  									cb.clear();  									cr = cd.decode(bb, cb, true); @@ -277,23 +282,23 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  									 */  									offset = n - bb.position() + cr.length();  									if ((bb.position() - cr.length()) < offset) { -										System.arraycopy(b, bb.position() - cr.length(), tmpBuff, 0, offset); -										System.arraycopy(tmpBuff, 0, b, 0, offset); +										System.arraycopy(bba, bb.position() - cr.length(), tmpBuff, 0, offset); +										System.arraycopy(tmpBuff, 0, bba, 0, offset);  									} else { -										System.arraycopy(b, bb.position() - cr.length(), b, 0, offset); +										System.arraycopy(bba, bb.position() - cr.length(), bba, 0, offset);  									}  									Log.d(TAG, String.format("Copying out %d chars at %d: 0x%02x",  											offset, bb.position() - cr.length(), -											b[bb.position() - cr.length()] +											bba[bb.position() - cr.length()]  									));  								} else {  									// After discarding the previous offset, we only have valid data. -									((vt320)buffer).putString(cb.array(), 0, cb.position()); +									((vt320)buffer).putString(cba, 0, cb.position());  									offset = 0;  								}  							} else {  								// No errors at all. -								((vt320)buffer).putString(cb.array(), 0, cb.position()); +								((vt320)buffer).putString(cba, 0, cb.position());  								offset = 0;  							} @@ -304,11 +309,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  					if ((newConditions & ChannelCondition.STDERR_DATA) != 0) {  						while (stderr.available() > 0) { -							n = stderr.read(b); -							bb = ByteBuffer.wrap(b, 0, n); +							n = stderr.read(bba); +							bb.position(0); +							bb.limit(n);  							replacer.decode(bb, cb, false);  							// TODO I don't know.. do we want this? We were ignoring it before -							Log.d(TAG, String.format("Read data from stderr: %s", new String(cb.array(), 0, cb.position()))); +							Log.d(TAG, String.format("Read data from stderr: %s", new String(cba, 0, cb.position())));  							cb.clear();  						}  					} @@ -405,6 +411,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  			@Override  			public void write(byte[] b) {}  			@Override +			public void write(int b) {} +			@Override  			public void sendTelnetCommand(byte cmd) {}  			@Override  			public void setWindowSize(int c, int r) {} @@ -469,7 +477,17 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal  					if (b != null && stdin != null)  						stdin.write(b);  				} catch (IOException e) { -					Log.e(TAG, "Problem handling incoming data in vt320() thread", e); +					Log.e(TAG, "Problem writing outgoing data in vt320() thread", e); +				} +			} + +			@Override +			public void write(int b) { +				try { +					if (stdin != null) +						stdin.write(b); +				} catch (IOException e) { +					Log.e(TAG, "Problem writing outgoing data in vt320() thread", e);  				}  			} | 
