aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2008-11-02 11:44:39 +0000
committerKenny Root <kenny@the-b.org>2008-11-02 11:44:39 +0000
commitccc3a32792175a561fc2c75ccc4fd9f441295830 (patch)
tree05d90f9f69fb4bda76cbdf0dfa7fcfd88dcad94d
parent4432df30987dd217ef639020c0198aa06925ba0f (diff)
downloadconnectbot-ccc3a32792175a561fc2c75ccc4fd9f441295830.tar.gz
connectbot-ccc3a32792175a561fc2c75ccc4fd9f441295830.tar.bz2
connectbot-ccc3a32792175a561fc2c75ccc4fd9f441295830.zip
* Allow users to force screen size to specific dimensions.
-rw-r--r--res/layout/dia_resize.xml52
-rw-r--r--res/values/strings.xml2
-rw-r--r--src/org/connectbot/ConsoleActivity.java25
-rw-r--r--src/org/connectbot/TerminalView.java21
-rw-r--r--src/org/connectbot/service/TerminalBridge.java107
5 files changed, 198 insertions, 9 deletions
diff --git a/res/layout/dia_resize.xml b/res/layout/dia_resize.xml
new file mode 100644
index 0000000..208e7a4
--- /dev/null
+++ b/res/layout/dia_resize.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ConnectBot: simple, powerful, open-source SSH client for Android
+ Copyright (C) 2007-2008 Kenny Root, Jeffrey Sharkey
+
+ This program 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.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dip"
+ android:paddingRight="10dip"
+ >
+
+ <EditText
+ android:id="@+id/width"
+ android:layout_width="100dip"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:numeric="integer" android:text="80"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="x"
+ android:paddingLeft="10dip"
+ android:paddingRight="10dip"
+ android:gravity="right|bottom"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ />
+
+
+ <EditText
+ android:id="@+id/height"
+ android:layout_width="100dip"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:numeric="integer" android:text="25"/>
+</LinearLayout> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fed7924..598d3d9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -44,6 +44,7 @@
<string name="button_cancel">Cancel</string>
<string name="button_change">Change</string>
<string name="button_generate">Generate Key</string>
+ <string name="button_resize">Resize</string>
<string name="alert_disconnect_msg">Connection Lost</string>
@@ -73,6 +74,7 @@
<string name="console_menu_copy">Copy</string>
<string name="console_menu_paste">Paste</string>
<string name="console_menu_tunnel">Tunnel</string>
+ <string name="console_menu_resize">Force Size</string>
<string name="tunnel_pos">Create tunnel</string>
<string name="tunnel_neg">Cancel</string>
diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java
index 35b8949..76793a6 100644
--- a/src/org/connectbot/ConsoleActivity.java
+++ b/src/org/connectbot/ConsoleActivity.java
@@ -572,7 +572,7 @@ public class ConsoleActivity extends Activity {
}
- protected MenuItem disconnect, copy, paste, tunnel;
+ protected MenuItem disconnect, copy, paste, tunnel, resize;
protected boolean copying = false;
protected TerminalView copySource = null;
@@ -662,6 +662,29 @@ public class ConsoleActivity extends Activity {
return true;
}
});
+
+ resize = menu.add(R.string.console_menu_resize);
+ resize.setIcon(android.R.drawable.ic_menu_crop);
+ resize.setEnabled(activeTerminal);
+ resize.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ final TerminalView terminal = (TerminalView)view;
+
+ final View resizeView = inflater.inflate(R.layout.dia_resize, null, false);
+ new AlertDialog.Builder(ConsoleActivity.this)
+ .setView(resizeView)
+ .setPositiveButton(R.string.button_resize, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ int width = Integer.parseInt(((EditText)resizeView.findViewById(R.id.width)).getText().toString());
+ int height = Integer.parseInt(((EditText)resizeView.findViewById(R.id.height)).getText().toString());
+
+ terminal.forceSize(width, height);
+ }
+ }).create().show();
+
+ return true;
+ }
+ });
return true;
diff --git a/src/org/connectbot/TerminalView.java b/src/org/connectbot/TerminalView.java
index 23c6770..d544344 100644
--- a/src/org/connectbot/TerminalView.java
+++ b/src/org/connectbot/TerminalView.java
@@ -27,6 +27,7 @@ import android.graphics.Paint;
import android.graphics.PixelXorXfermode;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
+import android.widget.Toast;
/**
* User interface {@link View} for showing a TerminalBridge in an
@@ -42,6 +43,8 @@ public class TerminalView extends View {
protected final Paint paint;
protected final Paint cursorPaint;
+ private Toast notification = null;
+
public int top = -1, bottom = -1, left = -1, right = -1;
public void resetSelected() {
@@ -112,4 +115,22 @@ public class TerminalView extends View {
}
+ public void notifyUser(String message) {
+ if (notification != null) {
+ notification.setText(message);
+ notification.show();
+ } else {
+ notification = Toast.makeText(context, message, Toast.LENGTH_SHORT);
+ notification.show();
+ }
+ }
+
+ /**
+ * Ask the {@link TerminalBridge} we're connected to to resize to a specific size.
+ * @param width
+ * @param height
+ */
+ public void forceSize(int width, int height) {
+ this.bridge.resizeComputed(width, height, getWidth(), getHeight());
+ }
}
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index 2712c49..6d7a51c 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -117,7 +117,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public Bitmap bitmap = null;
public VDUBuffer buffer = null;
- protected View parent = null;
+ protected TerminalView parent = null;
protected Canvas canvas = new Canvas();
private boolean ctrlPressed = false;
@@ -129,6 +129,10 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
final int COL_NICKNAME, COL_TYPE, COL_PRIVATE, COL_PUBLIC, COL_ENCRYPTED;
private boolean pubkeysExhausted = false;
+ private boolean forcedSize = false;
+ private int termWidth;
+ private int termHeight;
+
public class HostKeyVerifier implements ServerHostKeyVerifier {
public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm, byte[] serverHostKey) throws Exception {
@@ -531,9 +535,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// check for terminal resizing keys
// TODO: see if there is a way to make sure we dont "blip"
if(keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
+ this.forcedSize = false;
this.setFontSize(this.fontSize + 2);
return true;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ this.forcedSize = false;
this.setFontSize(this.fontSize - 2);
return true;
}
@@ -681,24 +687,28 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* parent, or maybe it's an updated font size. We should recalculate
* terminal size information and request a PTY resize.
*/
- public synchronized void parentChanged(View parent) {
+ public synchronized void parentChanged(TerminalView parent) {
this.parent = parent;
int width = parent.getWidth();
int height = parent.getHeight();
// recalculate buffer size
- int termWidth = width / charWidth;
- int termHeight = height / charHeight;
-
- // convert our height/width to integral values
- width = termWidth * charWidth;
- height = termHeight * charHeight;
+ int termWidth, termHeight;
+
+ if (this.forcedSize) {
+ termWidth = this.termWidth;
+ termHeight = this.termHeight;
+ } else {
+ termWidth = width / charWidth;
+ termHeight = height / charHeight;
+ }
// reallocate new bitmap if needed
boolean newBitmap = (this.bitmap == null);
if(this.bitmap != null)
newBitmap = (this.bitmap.getWidth() != width || this.bitmap.getHeight() != height);
+
if(newBitmap) {
this.bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
this.canvas.setBitmap(this.bitmap);
@@ -708,6 +718,19 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
this.defaultPaint.setColor(Color.BLACK);
this.canvas.drawRect(0, 0, width, height, this.defaultPaint);
+ // Stroke the border of the terminal if the size is being forced;
+ if (this.forcedSize) {
+ int borderX = (termWidth * charWidth) + 1;
+ int borderY = (termHeight * charHeight) + 1;
+
+ this.defaultPaint.setColor(Color.GRAY);
+ this.defaultPaint.setStrokeWidth(0.0f);
+ if (width >= borderX)
+ this.canvas.drawLine(borderX, 0, borderX, borderY + 1, defaultPaint);
+ if (height >= borderY)
+ this.canvas.drawLine(0, borderY, borderX + 1, borderY, defaultPaint);
+ }
+
try {
// request a terminal pty resize
buffer.setScreenSize(termWidth, termHeight, true);
@@ -721,6 +744,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
this.fullRedraw = true;
this.redraw();
+ this.parent.notifyUser(String.format("%d x %d", termWidth, termHeight));
+
Log.i(TAG, String.format("parentChanged() now width=%d, height=%d", termWidth, termHeight));
}
@@ -840,6 +865,72 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
this.disconnect();
}
+ /**
+ * Resize terminal to fit [rows]x[cols] in screen of size [width]x[height]
+ * @param rows
+ * @param cols
+ * @param width
+ * @param height
+ */
+ public void resizeComputed(int cols, int rows, int width, int height) {
+ float size = 8.0f;
+ float step = 8.0f;
+ float limit = 0.125f;
+
+ int direction;
+
+ while ((direction = fontSizeCompare(size, cols, rows, width, height)) < 0)
+ size += step;
+
+ if (direction == 0) {
+ Log.d("fontsize", String.format("Found match at %f", size));
+ return;
+ }
+
+ step /= 2.0f;
+ size -= step;
+
+ while ((direction = fontSizeCompare(size, cols, rows, width, height)) != 0
+ && step >= limit) {
+ step /= 2.0f;
+ if (direction > 0) {
+ size -= step;
+ } else {
+ size += step;
+ }
+ }
+
+ if (direction > 0)
+ size -= step;
+
+ this.forcedSize = true;
+ this.termWidth = cols;
+ this.termHeight = rows;
+ setFontSize(size);
+ }
+
+ private int fontSizeCompare(float size, int cols, int rows, int width, int height) {
+ // read new metrics to get exact pixel dimensions
+ this.defaultPaint.setTextSize(size);
+ FontMetricsInt fm = this.defaultPaint.getFontMetricsInt();
+
+ float[] widths = new float[1];
+ this.defaultPaint.getTextWidths("X", widths);
+ int termWidth = (int)widths[0] * cols;
+ int termHeight = (Math.abs(fm.top) + Math.abs(fm.descent) + 1) * rows;
+
+ Log.d("fontsize", String.format("font size %f resulted in %d x %d", size, termWidth, termHeight));
+
+ // Check to see if it fits in resolution specified.
+ if (termWidth > width || termHeight > height)
+ return 1;
+
+ if (termWidth == width || termHeight == height)
+ return 0;
+
+ return -1;
+ }
+
}