aboutsummaryrefslogtreecommitdiffstats
path: root/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/org')
-rw-r--r--src/org/theb/ssh/HostsList.java4
-rw-r--r--src/org/theb/ssh/JTATerminalView.java77
-rw-r--r--src/org/theb/ssh/Preferences.java134
-rw-r--r--src/org/theb/ssh/PreferencesDialog.java42
-rw-r--r--src/org/theb/ssh/TouchEntropy.java86
5 files changed, 273 insertions, 70 deletions
diff --git a/src/org/theb/ssh/HostsList.java b/src/org/theb/ssh/HostsList.java
index 7114497..5ac7ed9 100644
--- a/src/org/theb/ssh/HostsList.java
+++ b/src/org/theb/ssh/HostsList.java
@@ -227,8 +227,8 @@ public class HostsList extends ListActivity {
}
private void showPreferences() {
- // TODO Auto-generated method stub
-
+ Intent intent = new Intent(this, Preferences.class);
+ this.startActivity(intent);
}
private void showAbout() {
diff --git a/src/org/theb/ssh/JTATerminalView.java b/src/org/theb/ssh/JTATerminalView.java
index 2238f02..84e08f7 100644
--- a/src/org/theb/ssh/JTATerminalView.java
+++ b/src/org/theb/ssh/JTATerminalView.java
@@ -14,6 +14,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.PixelXorXfermode;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetricsInt;
import android.util.Log;
@@ -22,6 +23,8 @@ import android.view.View;
public class JTATerminalView extends View implements VDUDisplay, Terminal, Runnable {
private Paint paint;
+ private Paint cursorPaint;
+
private Canvas canvas;
private Bitmap bitmap;
@@ -40,8 +43,8 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
private int charHeight;
private int charDescent;
- private int termWidth;
- private int termHeight;
+ private int xoffset = 0;
+ private int yoffset = 0;
private int color[] = {
Color.BLACK,
@@ -62,6 +65,12 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
paint = new Paint();
paint.setAntiAlias(true);
+
+ cursorPaint = new Paint();
+ cursorPaint.setAntiAlias(true);
+ cursorPaint.setColor(darken(color[COLOR_FG_STD]));
+ cursorPaint.setXfermode(new PixelXorXfermode(color[COLOR_BG_STD]));
+
setFont(Typeface.MONOSPACE, 8);
emulation = new vt320() {
@@ -84,24 +93,20 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
};
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;
+
+ if (buffer.isCursorVisible() &&
+ (buffer.screenBase + buffer.getCursorRow() >= buffer.windowBase &&
+ buffer.screenBase + buffer.getCursorRow() < buffer.windowBase + buffer.height)) {
+ int x = buffer.getCursorColumn() * charWidth + xoffset;
+ int y = (buffer.getCursorRow() + buffer.screenBase - buffer.windowBase) * charHeight + yoffset;
+ canvas.drawRect(x, y, x + charWidth, y + charHeight, cursorPaint);
}
- */
}
}
@@ -120,11 +125,15 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
canvas = newCanvas;
setSize(w, h);
+
+ // Make sure the buffer is in the center of the screen.
+ xoffset = (getWidth() - buffer.width * charWidth) / 2;
+ yoffset = (getHeight() - buffer.height * charHeight) / 2;
}
private void setSize(int w, int h) {
- termWidth = w / charWidth;
- termHeight = h / charHeight;
+ int termWidth = w / charWidth;
+ int termHeight = h / charHeight;
buffer.setScreenSize(termWidth, buffer.height = termHeight, true);
}
@@ -150,7 +159,11 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
}
public int getColumnCount() {
- return termWidth;
+ return buffer.width;
+ }
+
+ public int getRowCount() {
+ return buffer.height;
}
public InputStream getInput() {
@@ -182,10 +195,6 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
return out;
}
- public int getRowCount() {
- return termHeight;
- }
-
private int darken(int color) {
return Color.argb(0xFF,
(int)(Color.red(color) * 0.8),
@@ -194,7 +203,7 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
);
}
- /*
+ /* Not used.
private int brighten(int color) {
return Color.argb(0xFF,
(int)(Color.red(color) * 1.2),
@@ -205,17 +214,15 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
*/
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++) {
+ // Check to see if the entire buffer is dirty or if this line is dirty.
+ // If neither is dirty, continue.
if (!buffer.update[0] && !buffer.update[l + 1]) continue;
for (int c = 0; c < buffer.width; c++) {
@@ -225,15 +232,21 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
fg = darken(color[COLOR_FG_STD]);
bg = darken(color[COLOR_BG_STD]);
+ // Check if foreground color attribute is set.
if ((currAttr & VDUBuffer.COLOR_FG) != 0)
fg = darken(color[((currAttr & VDUBuffer.COLOR_FG) >> VDUBuffer.COLOR_FG_SHIFT) - 1]);
+
+ // Check if background color attribute is set.
if ((currAttr & VDUBuffer.COLOR_BG) != 0)
bg = darken(darken(color[((currAttr & VDUBuffer.COLOR_BG) >> VDUBuffer.COLOR_BG_SHIFT) - 1]));
+
+ // Check if bold attribute is set.
paint.setFakeBoldText((currAttr & VDUBuffer.BOLD) != 0);
if ((currAttr & VDUBuffer.LOW) != 0)
fg = darken(fg);
+ // Support character inversion by swapping background and foreground color.
if ((currAttr & VDUBuffer.INVERT) != 0) {
int swapc = bg;
bg = fg;
@@ -241,12 +254,18 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
}
// If this character is in the special font, print it and continue to the next character.
+ // We can't use the optimization below for special characters.
if (sf.inSoftFont(buffer.charArray[buffer.windowBase + l][c])) {
+ // Clear out the space where the character will be printed.
paint.setColor(bg);
canvas.drawRect(c * charWidth + xoffset, l * charHeight + yoffset,
c * (charWidth + 1) + xoffset, (l+1) * charHeight + yoffset, paint);
paint.setColor(fg);
+
+ // FIXME: this won't work since we're not calling drawText()
paint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0);
+
+ // Draw the text if it's not invisible.
if ((currAttr & VDUBuffer.INVISIBLE) == 0)
sf.drawChar(canvas, paint, buffer.charArray[buffer.windowBase + l][c], xoffset + c * charWidth, l * charHeight + yoffset, charWidth, charHeight);
continue;
@@ -265,12 +284,16 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
addr++;
}
+ // Clear the background in preparation for writing text.
paint.setColor(bg);
canvas.drawRect(c * charWidth + xoffset, l * charHeight + yoffset,
addr * (charWidth + 1) + xoffset, (l+1) * charHeight + yoffset, paint);
paint.setColor(fg);
+ // Check for the underline attribute and set the brush accordingly.
paint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0);
+
+ // Write the text string starting at 'c' for 'addr' number of characters.
if ((currAttr & VDUBuffer.INVISIBLE) == 0)
canvas.drawText(buffer.charArray[buffer.windowBase + l],
c, addr,
@@ -278,6 +301,7 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
(l + 1) * charHeight - charDescent + yoffset,
paint);
+ // Advance to the next text block with different characteristics.
c += addr - 1;
}
}
@@ -305,6 +329,7 @@ public class JTATerminalView extends View implements VDUDisplay, Terminal, Runna
public void setVDUBuffer(VDUBuffer buffer) {
this.buffer = buffer;
+ buffer.setDisplay(this);
}
public void run() {
diff --git a/src/org/theb/ssh/Preferences.java b/src/org/theb/ssh/Preferences.java
new file mode 100644
index 0000000..cfc0156
--- /dev/null
+++ b/src/org/theb/ssh/Preferences.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 Kenny Root (kenny at the-b.org)
+ *
+ * This file is part of Connectbot.
+ *
+ * Connectbot is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Connectbot is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Connectbot. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.theb.ssh;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.concurrent.Semaphore;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class Preferences extends Activity {
+ private static SecureRandom mSecRand = null;
+ private static KeyStore mKeyStore = null;
+ private Thread kgThread = null;
+
+ private static final int GATHER_ENTROPY = 0;
+
+ protected Semaphore entropyGathered;
+ protected String entropySeed;
+
+ protected Button generateButton;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.preferences);
+
+ generateButton = (Button) findViewById(R.id.generate);
+ generateButton.setOnClickListener(mGenerateListener);
+
+ Button okButton = (Button) findViewById(R.id.ok);
+ okButton.setOnClickListener(mCommitListener);
+
+ Button cancelButton = (Button) findViewById(R.id.cancel);
+ cancelButton.setOnClickListener(mCancelListener);
+ }
+
+ final Runnable mKeyGen = new Runnable() {
+ public void run() {
+ // TODO Auto-generated method stub
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+ try {
+ mSecRand = SecureRandom.getInstance("SHA1PRNG");
+
+ entropyGathered = new Semaphore(0);
+ gatherEntropy();
+ entropyGathered.acquire();
+ mSecRand.setSeed(entropySeed.getBytes());
+ entropyGathered = null;
+
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
+ keyGen.initialize(512, mSecRand);
+
+ KeyPair pair = keyGen.generateKeyPair();
+ PrivateKey priv = pair.getPrivate();
+ PublicKey pub = pair.getPublic();
+
+ byte[] encPriv = priv.getEncoded();
+ byte[] encPub = pub.getEncoded();
+ Log.e("SSH/priv", new String(encPriv));
+ Log.d("SSH/pub", new String(encPub));
+ } catch (Exception ex) {
+ Log.e("SSH/keygen", ex.getMessage());
+ }
+ }
+ };
+
+ OnClickListener mGenerateListener = new OnClickListener() {
+ public void onClick(View v) {
+ kgThread = new Thread(mKeyGen);
+ kgThread.start();
+ }
+ };
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode,
+ String data, Bundle extras)
+ {
+ if (requestCode == GATHER_ENTROPY) {
+ entropySeed = data;
+ entropyGathered.release();
+ }
+ }
+
+ protected void gatherEntropy() {
+ generateButton.setEnabled(false);
+ Intent intent = new Intent(this, TouchEntropy.class);
+ startSubActivity(intent, GATHER_ENTROPY);
+ }
+
+ OnClickListener mCommitListener = new OnClickListener() {
+ public void onClick(View v) {
+ // When the user clicks, just finish this activity.
+ // onPause will be called, and we save our data there.
+ finish();
+ }
+ };
+
+ OnClickListener mCancelListener = new OnClickListener() {
+ public void onClick(View v) {
+ //cancelEdit();
+ finish();
+ }
+ };
+}
diff --git a/src/org/theb/ssh/PreferencesDialog.java b/src/org/theb/ssh/PreferencesDialog.java
deleted file mode 100644
index 06bc229..0000000
--- a/src/org/theb/ssh/PreferencesDialog.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007 Kenny Root (kenny at the-b.org)
- *
- * This file is part of Connectbot.
- *
- * Connectbot is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Connectbot is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Connectbot. If not, see <http://www.gnu.org/licenses/>.
- */
-package org.theb.ssh;
-
-import android.app.Dialog;
-import android.content.Context;
-
-public class PreferencesDialog extends Dialog {
-
- public PreferencesDialog(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
-
- public PreferencesDialog(Context context, int theme) {
- super(context, theme);
- // TODO Auto-generated constructor stub
- }
-
- public PreferencesDialog(Context context, boolean cancelable,
- OnCancelListener cancelListener) {
- super(context, cancelable, cancelListener);
- // TODO Auto-generated constructor stub
- }
-
-}
diff --git a/src/org/theb/ssh/TouchEntropy.java b/src/org/theb/ssh/TouchEntropy.java
new file mode 100644
index 0000000..33ad499
--- /dev/null
+++ b/src/org/theb/ssh/TouchEntropy.java
@@ -0,0 +1,86 @@
+package org.theb.ssh;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.graphics.Paint.FontMetrics;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class TouchEntropy extends Activity {
+ protected String mEntropy;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mEntropy = new String();
+ setContentView(new TouchView(this));
+ }
+
+ class TouchView extends View {
+ Paint mPaint;
+ FontMetrics mFontMetrics;
+
+ private boolean mFlipFlop = false;
+ private long mLastTime = 0;
+
+ public TouchView(Context c) {
+ super(c);
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setTypeface(Typeface.DEFAULT);
+ mPaint.setTextAlign(Paint.Align.CENTER);
+ mPaint.setTextSize(16);
+ mPaint.setColor(Color.WHITE);
+ mFontMetrics = mPaint.getFontMetrics();
+ }
+
+ @Override
+ public void onDraw(Canvas c) {
+ String prompt = getResources().getString(R.string.prompt_touch);
+ c.drawText(prompt + " " + (int)(100.0 * (mEntropy.length() / 20.0)) + "% done",
+ getWidth() / 2,
+ getHeight() / 2 - (mFontMetrics.ascent + mFontMetrics.descent) / 2,
+ mPaint);
+ }
+
+ @Override
+ public boolean onMotionEvent(MotionEvent event) {
+ // Only get entropy every 200 milliseconds to ensure the user has moved around.
+ long now = System.currentTimeMillis();
+ if ((now - mLastTime) < 200)
+ return true;
+ else
+ mLastTime = now;
+
+ Log.d("SSH", "Last time was " + mLastTime);
+
+
+ // Get the lowest 4 bits of each X, Y input and concat to the entropy-gathering
+ // string.
+ if (mFlipFlop)
+ mEntropy += (byte)(((int)event.getX() & 0xF0) | ((int)event.getY() & 0x0F));
+ else
+ mEntropy += (byte)(((int)event.getY() & 0xF0) | ((int)event.getX() & 0x0F));
+
+ mFlipFlop = !mFlipFlop;
+
+ // SHA1PRNG only keeps 20 bytes (160 bits) of entropy.
+ if (mEntropy.length() > 20) {
+ TouchEntropy.this.setResult(RESULT_OK, mEntropy);
+ TouchEntropy.this.finish();
+ }
+
+ invalidate();
+
+ return true;
+ }
+ }
+}