From d6764b7763e7857273b65048b4eb37a3c65efade Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Wed, 21 Nov 2007 05:32:39 +0000 Subject: Merging back in the jcterm branch --- src/org/theb/ssh/JTATerminalView.java | 323 ++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 src/org/theb/ssh/JTATerminalView.java (limited to 'src/org/theb/ssh/JTATerminalView.java') diff --git a/src/org/theb/ssh/JTATerminalView.java b/src/org/theb/ssh/JTATerminalView.java new file mode 100644 index 0000000..2238f02 --- /dev/null +++ b/src/org/theb/ssh/JTATerminalView.java @@ -0,0 +1,323 @@ +package org.theb.ssh; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import de.mud.terminal.SoftFont; +import de.mud.terminal.VDUBuffer; +import de.mud.terminal.VDUDisplay; +import de.mud.terminal.vt320; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.graphics.Paint.FontMetricsInt; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; + +public class JTATerminalView extends View implements VDUDisplay, Terminal, Runnable { + private Paint paint; + private Canvas canvas; + private Bitmap bitmap; + + protected vt320 emulation; + private VDUBuffer buffer; + + private InputStream in; + private OutputStream out; + + private String encoding = "ASCII"; + private SoftFont sf = new SoftFont(); + + private Thread reader = null; + + private int charWidth; + private int charHeight; + private int charDescent; + + private int termWidth; + private int termHeight; + + private int color[] = { + Color.BLACK, + Color.RED, + Color.GREEN, + Color.YELLOW, + Color.BLUE, + Color.MAGENTA, + Color.CYAN, + Color.WHITE, + }; + + private final static int COLOR_FG_STD = 7; + private final static int COLOR_BG_STD = 0; + + public JTATerminalView(Context context) { + super(context); + + paint = new Paint(); + paint.setAntiAlias(true); + setFont(Typeface.MONOSPACE, 8); + + emulation = new vt320() { + public void write(byte[] b) { + try { + JTATerminalView.this.write(b); + } catch (IOException e) { + Log.e("SSH", "couldn't write" + b.toString()); + reader = null; + } + } + + public void sendTelnetCommand(byte cmd) { + // TODO: implement telnet command sending + } + + public void setWindowSize(int c, int r) { + // TODO: implement window sizing + } + }; + + setVDUBuffer(emulation); + emulation.setDisplay(this); + } + + @Override + protected void onDraw(Canvas canvas) { + if (bitmap != null) { + canvas.drawBitmap(bitmap, 0, 0, null); + /* + if (charHeight > 0 && y > charHeight) { + // Invert pixels for cursor position. + Bitmap cursor = Bitmap.createBitmap(mBitmap, x, y - mCharHeight, mCharWidth, mCharHeight); + for (int cy = 0; cy < mCharHeight; cy++) + for (int cx = 0; cx < mCharWidth; cx++) + cursor.setPixel(cx, cy, (~cursor.getPixel(cx, cy) & 0xFFFFFFFF) | 0xFF000000); + canvas.drawBitmap(cursor, x, y - mCharHeight, null); + cursor = null; + } + */ + } + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + Log.d("SSH/TerminalView", "onSizeChanged called"); + Bitmap newBitmap = Bitmap.createBitmap(w, h, false); + Canvas newCanvas = new Canvas(); + + newCanvas.setDevice(newBitmap); + + if (bitmap != null) + newCanvas.drawBitmap(bitmap, 0, 0, paint); + + bitmap = newBitmap; + canvas = newCanvas; + + setSize(w, h); + } + + private void setSize(int w, int h) { + termWidth = w / charWidth; + termHeight = h / charHeight; + + buffer.setScreenSize(termWidth, buffer.height = termHeight, true); + } + + private void setFont(Typeface typeface, int size) { + paint.setTypeface(typeface); + paint.setTextSize(size); + + FontMetricsInt fm = paint.getFontMetricsInt(); + + charDescent = fm.descent; + + float[] widths = new float[1]; + paint.getTextWidths("X", widths); + charWidth = (int)widths[0]; + + charHeight = Math.abs(fm.top) + Math.abs(fm.descent); + } + + public void write(byte[] b) throws IOException { + Log.e("SSH/JTATerm/write", "Trying to write" + b.toString()); + out.write(b); + } + + public int getColumnCount() { + return termWidth; + } + + public InputStream getInput() { + return in; + } + + public byte[] getKeyCode(int keyCode, int meta) { + switch (keyCode) { + case KeyEvent.KEYCODE_NEWLINE: + emulation.keyTyped(vt320.KEY_ENTER, ' ', meta); + break; + case KeyEvent.KEYCODE_DPAD_LEFT: + emulation.keyPressed(vt320.KEY_LEFT, ' ', meta); + break; + case KeyEvent.KEYCODE_DPAD_UP: + emulation.keyPressed(vt320.KEY_UP, ' ', meta); + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + emulation.keyPressed(vt320.KEY_DOWN, ' ', meta) ; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + emulation.keyPressed(vt320.KEY_RIGHT, ' ', meta); + break; + } + return null; + } + + public OutputStream getOutput() { + return out; + } + + public int getRowCount() { + return termHeight; + } + + private int darken(int color) { + return Color.argb(0xFF, + (int)(Color.red(color) * 0.8), + (int)(Color.green(color) * 0.8), + (int)(Color.blue(color) * 0.8) + ); + } + + /* + private int brighten(int color) { + return Color.argb(0xFF, + (int)(Color.red(color) * 1.2), + (int)(Color.green(color) * 1.2), + (int)(Color.blue(color) * 1.2) + ); + } + */ + + public void redraw() { + // Make sure the buffer is in the center of the screen. + int xoffset = (getWidth() - buffer.width * charWidth) / 2; + int yoffset = (getHeight() - buffer.height * charHeight) / 2; + + // Draw the mouse-selection + //int selectStartLine = selectBegin.y - buffer.windowBase; + //int selectEndLine = selectEnd.y - buffer.windowBase; + + int fg, bg; + + for (int l = 0; l < buffer.height; l++) { + if (!buffer.update[0] && !buffer.update[l + 1]) continue; + + for (int c = 0; c < buffer.width; c++) { + int addr = 0; + int currAttr = buffer.charAttributes[buffer.windowBase + l][c]; + + fg = darken(color[COLOR_FG_STD]); + bg = darken(color[COLOR_BG_STD]); + + if ((currAttr & VDUBuffer.COLOR_FG) != 0) + fg = darken(color[((currAttr & VDUBuffer.COLOR_FG) >> VDUBuffer.COLOR_FG_SHIFT) - 1]); + if ((currAttr & VDUBuffer.COLOR_BG) != 0) + bg = darken(darken(color[((currAttr & VDUBuffer.COLOR_BG) >> VDUBuffer.COLOR_BG_SHIFT) - 1])); + paint.setFakeBoldText((currAttr & VDUBuffer.BOLD) != 0); + + if ((currAttr & VDUBuffer.LOW) != 0) + fg = darken(fg); + + if ((currAttr & VDUBuffer.INVERT) != 0) { + int swapc = bg; + bg = fg; + fg = swapc; + } + + // If this character is in the special font, print it and continue to the next character. + if (sf.inSoftFont(buffer.charArray[buffer.windowBase + l][c])) { + paint.setColor(bg); + canvas.drawRect(c * charWidth + xoffset, l * charHeight + yoffset, + c * (charWidth + 1) + xoffset, (l+1) * charHeight + yoffset, paint); + paint.setColor(fg); + paint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0); + if ((currAttr & VDUBuffer.INVISIBLE) == 0) + sf.drawChar(canvas, paint, buffer.charArray[buffer.windowBase + l][c], xoffset + c * charWidth, l * charHeight + yoffset, charWidth, charHeight); + continue; + } + + // Determine the amount of continuous characters with the same settings and print them all at once. + while ((c + addr < buffer.width) && + ((buffer.charArray[buffer.windowBase + l][c + addr] < ' ') || + (buffer.charAttributes[buffer.windowBase + l][c + addr] == currAttr)) && + !sf.inSoftFont(buffer.charArray[buffer.windowBase + l][c + addr])) { + if (buffer.charArray[buffer.windowBase + l][c + addr] < ' ') { + buffer.charArray[buffer.windowBase + l][c + addr] = ' '; + buffer.charAttributes[buffer.windowBase + l][c + addr] = 0; + continue; + } + addr++; + } + + paint.setColor(bg); + canvas.drawRect(c * charWidth + xoffset, l * charHeight + yoffset, + addr * (charWidth + 1) + xoffset, (l+1) * charHeight + yoffset, paint); + paint.setColor(fg); + + paint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0); + if ((currAttr & VDUBuffer.INVISIBLE) == 0) + canvas.drawText(buffer.charArray[buffer.windowBase + l], + c, addr, + c * charWidth + xoffset, + (l + 1) * charHeight - charDescent + yoffset, + paint); + + c += addr - 1; + } + } + + buffer.update[0] = false; + + postInvalidate(); + } + + public void updateScrollBar() { + // TODO Auto-generated method stub + } + + public void start(InputStream in, OutputStream out) { + this.in = in; + this.out = out; + + reader = new Thread(this); + reader.start(); + } + + public VDUBuffer getVDUBuffer() { + return buffer; + } + + public void setVDUBuffer(VDUBuffer buffer) { + this.buffer = buffer; + } + + public void run() { + byte[] b = new byte[256]; + int n = 0; + while (n >= 0) + try { + n = in.read(b); + if (n > 0) emulation.putString(new String(b, 0, n, encoding)); + redraw(); + } catch (IOException e) { + reader = null; + break; + } + } +} -- cgit v1.2.3