Refactor keyboard management into separate class
git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@490 df292f66-193f-0410-a5fc-6d59da041ff2master
parent
90632bd675
commit
515c3eab54
|
@ -2,7 +2,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.connectbot"
|
||||
android:versionName="1.7-dev"
|
||||
android:versionCode="261">
|
||||
android:versionCode="262">
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
|
|
|
@ -1032,6 +1032,8 @@ public class ConsoleActivity extends Activity {
|
|||
bound.setResizeAllowed(false);
|
||||
else
|
||||
bound.setResizeAllowed(true);
|
||||
|
||||
bound.hardKeyboardHidden = (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1046,6 @@ public class ConsoleActivity extends Activity {
|
|||
private int addNewTerminalView(TerminalBridge bridge) {
|
||||
// let them know about our prompt handler services
|
||||
bridge.promptHelper.setHandler(promptHandler);
|
||||
bridge.refreshKeymode();
|
||||
|
||||
// inflate each terminal view
|
||||
RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.item_terminal, flip, false);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.connectbot;
|
|||
import org.connectbot.bean.SelectionArea;
|
||||
import org.connectbot.service.FontSizeChangedListener;
|
||||
import org.connectbot.service.TerminalBridge;
|
||||
import org.connectbot.service.TerminalKeyListener;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
@ -110,7 +111,7 @@ public class TerminalView extends View implements FontSizeChangedListener {
|
|||
bridge.addFontSizeChangedListener(this);
|
||||
|
||||
// connect our view up to the bridge
|
||||
setOnKeyListener(bridge);
|
||||
setOnKeyListener(bridge.getKeyHandler());
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
@ -149,14 +150,18 @@ public class TerminalView extends View implements FontSizeChangedListener {
|
|||
// also draw cursor if visible
|
||||
if (bridge.buffer.isCursorVisible()) {
|
||||
int cursorColumn = bridge.buffer.getCursorColumn();
|
||||
int columns = bridge.buffer.getColumns();
|
||||
final int cursorRow = bridge.buffer.getCursorRow();
|
||||
|
||||
final int columns = bridge.buffer.getColumns();
|
||||
|
||||
if (cursorColumn == columns)
|
||||
cursorColumn = columns - 1;
|
||||
|
||||
if (cursorColumn < 0 || cursorRow < 0)
|
||||
return;
|
||||
|
||||
int currentAttribute = bridge.buffer.getAttributes(
|
||||
cursorColumn,
|
||||
bridge.buffer.getCursorRow());
|
||||
cursorColumn, cursorRow);
|
||||
boolean onWideCharacter = (currentAttribute & VDUBuffer.FULLWIDTH) != 0;
|
||||
|
||||
int x = cursorColumn * bridge.charWidth;
|
||||
|
@ -176,21 +181,21 @@ public class TerminalView extends View implements FontSizeChangedListener {
|
|||
// Make sure we scale our decorations to the correct size.
|
||||
canvas.concat(scaleMatrix);
|
||||
|
||||
int metaState = bridge.getMetaState();
|
||||
int metaState = bridge.getKeyHandler().getMetaState();
|
||||
|
||||
if ((metaState & TerminalBridge.META_SHIFT_ON) != 0)
|
||||
if ((metaState & TerminalKeyListener.META_SHIFT_ON) != 0)
|
||||
canvas.drawPath(shiftCursor, cursorStrokePaint);
|
||||
else if ((metaState & TerminalBridge.META_SHIFT_LOCK) != 0)
|
||||
else if ((metaState & TerminalKeyListener.META_SHIFT_LOCK) != 0)
|
||||
canvas.drawPath(shiftCursor, cursorPaint);
|
||||
|
||||
if ((metaState & TerminalBridge.META_ALT_ON) != 0)
|
||||
if ((metaState & TerminalKeyListener.META_ALT_ON) != 0)
|
||||
canvas.drawPath(altCursor, cursorStrokePaint);
|
||||
else if ((metaState & TerminalBridge.META_ALT_LOCK) != 0)
|
||||
else if ((metaState & TerminalKeyListener.META_ALT_LOCK) != 0)
|
||||
canvas.drawPath(altCursor, cursorPaint);
|
||||
|
||||
if ((metaState & TerminalBridge.META_CTRL_ON) != 0)
|
||||
if ((metaState & TerminalKeyListener.META_CTRL_ON) != 0)
|
||||
canvas.drawPath(ctrlCursor, cursorStrokePaint);
|
||||
else if ((metaState & TerminalBridge.META_CTRL_LOCK) != 0)
|
||||
else if ((metaState & TerminalKeyListener.META_CTRL_LOCK) != 0)
|
||||
canvas.drawPath(ctrlCursor, cursorPaint);
|
||||
|
||||
// Restore previous clip region
|
||||
|
|
|
@ -32,10 +32,8 @@ import org.connectbot.bean.SelectionArea;
|
|||
import org.connectbot.transport.AbsTransport;
|
||||
import org.connectbot.transport.TransportFactory;
|
||||
import org.connectbot.util.HostDatabase;
|
||||
import org.connectbot.util.PreferenceConstants;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
|
@ -45,10 +43,6 @@ import android.graphics.Bitmap.Config;
|
|||
import android.graphics.Paint.FontMetrics;
|
||||
import android.text.ClipboardManager;
|
||||
import android.util.Log;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnKeyListener;
|
||||
import de.mud.terminal.VDUBuffer;
|
||||
import de.mud.terminal.VDUDisplay;
|
||||
import de.mud.terminal.vt320;
|
||||
|
@ -63,10 +57,11 @@ import de.mud.terminal.vt320;
|
|||
* This class also provides SSH hostkey verification prompting, and password
|
||||
* prompting.
|
||||
*/
|
||||
public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
||||
public class TerminalBridge implements VDUDisplay {
|
||||
public final static String TAG = "ConnectBot.TerminalBridge";
|
||||
|
||||
public final static int DEFAULT_FONT_SIZE = 10;
|
||||
private final static int FONT_SIZE_STEP = 2;
|
||||
|
||||
public Integer[] color;
|
||||
|
||||
|
@ -77,7 +72,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
|
||||
public HostBean host;
|
||||
|
||||
private AbsTransport transport;
|
||||
/* package */ AbsTransport transport;
|
||||
|
||||
final Paint defaultPaint;
|
||||
|
||||
|
@ -92,26 +87,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
private TerminalView parent = null;
|
||||
private final Canvas canvas = new Canvas();
|
||||
|
||||
private int metaState = 0;
|
||||
|
||||
public final static int META_CTRL_ON = 0x01;
|
||||
public final static int META_CTRL_LOCK = 0x02;
|
||||
public final static int META_ALT_ON = 0x04;
|
||||
public final static int META_ALT_LOCK = 0x08;
|
||||
public final static int META_SHIFT_ON = 0x10;
|
||||
public final static int META_SHIFT_LOCK = 0x20;
|
||||
public final static int META_SLASH = 0x40;
|
||||
public final static int META_TAB = 0x80;
|
||||
|
||||
// The bit mask of momentary and lock states for each
|
||||
public final static int META_CTRL_MASK = META_CTRL_ON | META_CTRL_LOCK;
|
||||
public final static int META_ALT_MASK = META_ALT_ON | META_ALT_LOCK;
|
||||
public final static int META_SHIFT_MASK = META_SHIFT_ON | META_SHIFT_LOCK;
|
||||
|
||||
// All the transient key codes
|
||||
public final static int META_TRANSIENT = META_CTRL_ON | META_ALT_ON
|
||||
| META_SHIFT_ON;
|
||||
|
||||
private boolean disconnected = false;
|
||||
private boolean awaitingClose = false;
|
||||
|
||||
|
@ -119,16 +94,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
private int columns;
|
||||
private int rows;
|
||||
|
||||
private String keymode = null;
|
||||
|
||||
private boolean hardKeyboard = false;
|
||||
/* package */ final TerminalKeyListener keyListener;
|
||||
|
||||
private boolean selectingForCopy = false;
|
||||
private final SelectionArea selectionArea;
|
||||
private ClipboardManager clipboard;
|
||||
|
||||
protected KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
|
||||
|
||||
public int charWidth = -1;
|
||||
public int charHeight = -1;
|
||||
private int charTop = -1;
|
||||
|
@ -179,6 +150,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
fontSizeChangedListeners = new LinkedList<FontSizeChangedListener>();
|
||||
|
||||
transport = null;
|
||||
|
||||
keyListener = new TerminalKeyListener(manager, this, buffer, host);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,7 +160,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
* and password authentication.
|
||||
*/
|
||||
public TerminalBridge(final TerminalManager manager, final HostBean host) throws IOException {
|
||||
|
||||
this.manager = manager;
|
||||
this.host = host;
|
||||
|
||||
|
@ -270,8 +242,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
|
||||
selectionArea = new SelectionArea();
|
||||
|
||||
hardKeyboard = (manager.res.getConfiguration().keyboard
|
||||
== Configuration.KEYBOARD_QWERTY);
|
||||
keyListener = new TerminalKeyListener(manager, this, buffer, host);
|
||||
}
|
||||
|
||||
public PromptHelper getPromptHelper() {
|
||||
|
@ -482,394 +453,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
}
|
||||
}
|
||||
|
||||
public void refreshKeymode() {
|
||||
keymode = manager.getKeyMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle onKey() events coming down from a {@link TerminalView} above us.
|
||||
* Modify the keys to make more sense to a host then pass it to the transport.
|
||||
*/
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
try {
|
||||
|
||||
boolean hardKeyboardHidden =
|
||||
manager.res.getConfiguration().hardKeyboardHidden ==
|
||||
Configuration.HARDKEYBOARDHIDDEN_YES;
|
||||
|
||||
// Ignore all key-up events except for the special keys
|
||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
// There's nothing here for virtual keyboard users.
|
||||
if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden))
|
||||
return false;
|
||||
|
||||
// skip keys if we aren't connected yet or have been disconnected
|
||||
if (disconnected || transport == null)
|
||||
return false;
|
||||
|
||||
if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT
|
||||
&& (metaState & META_SLASH) != 0) {
|
||||
metaState &= ~(META_SLASH | META_TRANSIENT);
|
||||
transport.write('/');
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
|
||||
&& (metaState & META_TAB) != 0) {
|
||||
metaState &= ~(META_TAB | META_TRANSIENT);
|
||||
transport.write(0x09);
|
||||
return true;
|
||||
}
|
||||
} else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ALT_LEFT
|
||||
&& (metaState & META_SLASH) != 0) {
|
||||
metaState &= ~(META_SLASH | META_TRANSIENT);
|
||||
transport.write('/');
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
|
||||
&& (metaState & META_TAB) != 0) {
|
||||
metaState &= ~(META_TAB | META_TRANSIENT);
|
||||
transport.write(0x09);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for terminal resizing keys
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||
forcedSize = false;
|
||||
setFontSize(fontSize + 2);
|
||||
return true;
|
||||
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
|
||||
forcedSize = false;
|
||||
setFontSize(fontSize - 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip keys if we aren't connected yet or have been disconnected
|
||||
if (disconnected || transport == null)
|
||||
return false;
|
||||
|
||||
// if we're in scrollback, scroll to bottom of window on input
|
||||
if (buffer.windowBase != buffer.screenBase)
|
||||
buffer.setWindowBase(buffer.screenBase);
|
||||
|
||||
boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE);
|
||||
|
||||
// otherwise pass through to existing session
|
||||
// print normal keys
|
||||
if (printing) {
|
||||
int curMetaState = event.getMetaState();
|
||||
|
||||
metaState &= ~(META_SLASH | META_TAB);
|
||||
|
||||
if ((metaState & META_SHIFT_MASK) != 0) {
|
||||
curMetaState |= KeyEvent.META_SHIFT_ON;
|
||||
metaState &= ~META_SHIFT_ON;
|
||||
redraw();
|
||||
}
|
||||
|
||||
if ((metaState & META_ALT_MASK) != 0) {
|
||||
curMetaState |= KeyEvent.META_ALT_ON;
|
||||
metaState &= ~META_ALT_ON;
|
||||
redraw();
|
||||
}
|
||||
|
||||
int key = keymap.get(keyCode, curMetaState);
|
||||
|
||||
if ((metaState & META_CTRL_MASK) != 0) {
|
||||
metaState &= ~META_CTRL_ON;
|
||||
redraw();
|
||||
|
||||
if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden))
|
||||
&& sendFunctionKey(keyCode))
|
||||
return true;
|
||||
|
||||
// Support CTRL-a through CTRL-z
|
||||
if (key >= 0x61 && key <= 0x7A)
|
||||
key -= 0x60;
|
||||
// Support CTRL-A through CTRL-_
|
||||
else if (key >= 0x41 && key <= 0x5F)
|
||||
key -= 0x40;
|
||||
else if (key == 0x20)
|
||||
key = 0x00;
|
||||
else if (key == 0x3F)
|
||||
key = 0x7F;
|
||||
}
|
||||
|
||||
// handle pressing f-keys
|
||||
if ((hardKeyboard && !hardKeyboardHidden)
|
||||
&& (curMetaState & KeyEvent.META_SHIFT_ON) != 0
|
||||
&& sendFunctionKey(keyCode))
|
||||
return true;
|
||||
|
||||
if (key < 0x80)
|
||||
transport.write(key);
|
||||
else
|
||||
// TODO write encoding routine that doesn't allocate each time
|
||||
transport.write(new String(Character.toChars(key))
|
||||
.getBytes(host.getEncoding()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_UNKNOWN &&
|
||||
event.getAction() == KeyEvent.ACTION_MULTIPLE) {
|
||||
byte[] input = event.getCharacters().getBytes(host.getEncoding());
|
||||
transport.write(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
// try handling keymode shortcuts
|
||||
if (hardKeyboard && !hardKeyboardHidden &&
|
||||
event.getRepeatCount() == 0) {
|
||||
if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaState |= META_SLASH;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaState |= META_TAB;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
}
|
||||
} else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
metaState |= META_SLASH;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
metaState |= META_TAB;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for special chars
|
||||
switch(keyCode) {
|
||||
case KeyEvent.KEYCODE_CAMERA:
|
||||
|
||||
// check to see which shortcut the camera button triggers
|
||||
String camera = manager.prefs.getString(
|
||||
PreferenceConstants.CAMERA,
|
||||
PreferenceConstants.CAMERA_CTRLA_SPACE);
|
||||
if(PreferenceConstants.CAMERA_CTRLA_SPACE.equals(camera)) {
|
||||
transport.write(0x01);
|
||||
transport.write(' ');
|
||||
} else if(PreferenceConstants.CAMERA_CTRLA.equals(camera)) {
|
||||
transport.write(0x01);
|
||||
} else if(PreferenceConstants.CAMERA_ESC.equals(camera)) {
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KeyEvent.KEYCODE_DEL:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_BACK_SPACE, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ENTER, ' ', 0);
|
||||
metaState &= ~META_TRANSIENT;
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.decrementColumn();
|
||||
redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_LEFT, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.decrementRow();
|
||||
redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_UP, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.incrementRow();
|
||||
redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_DOWN, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.incrementColumn();
|
||||
redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (selectingForCopy) {
|
||||
if (selectionArea.isSelectingOrigin())
|
||||
selectionArea.finishSelectingOrigin();
|
||||
else {
|
||||
if (parent != null && clipboard != null) {
|
||||
// copy selected area to clipboard
|
||||
String copiedText = selectionArea.copyFrom(buffer);
|
||||
|
||||
clipboard.setText(copiedText);
|
||||
parent.notifyUser(parent.getContext().getString(
|
||||
R.string.console_copy_done,
|
||||
copiedText.length()));
|
||||
|
||||
selectingForCopy = false;
|
||||
selectionArea.reset();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((metaState & META_CTRL_ON) != 0) {
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0);
|
||||
metaState &= ~META_CTRL_ON;
|
||||
} else
|
||||
metaState |= META_CTRL_ON;
|
||||
}
|
||||
|
||||
redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Problem while trying to handle an onKey() event", e);
|
||||
try {
|
||||
transport.flush();
|
||||
} catch (IOException ioe) {
|
||||
Log.d(TAG, "Our transport was closed, dispatching disconnect event");
|
||||
dispatchDisconnect(false);
|
||||
}
|
||||
} catch (NullPointerException npe) {
|
||||
Log.d(TAG, "Input before connection established ignored.");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return successful
|
||||
*/
|
||||
private boolean sendFunctionKey(int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_1:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F1, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_2:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F2, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_3:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F3, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_4:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F4, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_5:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F5, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_6:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F6, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_7:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F7, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_8:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F8, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_9:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F9, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_0:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F10, ' ', 0);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle meta key presses where the key can be locked on.
|
||||
* <p>
|
||||
* 1st press: next key to have meta state<br />
|
||||
* 2nd press: meta state is locked on<br />
|
||||
* 3rd press: disable meta state
|
||||
*
|
||||
* @param code
|
||||
*/
|
||||
private void metaPress(int code) {
|
||||
if ((metaState & (code << 1)) != 0) {
|
||||
metaState &= ~(code << 1);
|
||||
} else if ((metaState & code) != 0) {
|
||||
metaState &= ~code;
|
||||
metaState |= code << 1;
|
||||
} else
|
||||
metaState |= code;
|
||||
redraw();
|
||||
}
|
||||
|
||||
public int getMetaState() {
|
||||
return metaState;
|
||||
}
|
||||
|
||||
private int getStateForBuffer() {
|
||||
int bufferState = 0;
|
||||
|
||||
if ((metaState & META_CTRL_MASK) != 0)
|
||||
bufferState |= vt320.KEY_CONTROL;
|
||||
if ((metaState & META_SHIFT_MASK) != 0)
|
||||
bufferState |= vt320.KEY_SHIFT;
|
||||
if ((metaState & META_ALT_MASK) != 0)
|
||||
bufferState |= vt320.KEY_ALT;
|
||||
|
||||
return bufferState;
|
||||
}
|
||||
|
||||
public void setSelectingForCopy(boolean selectingForCopy) {
|
||||
this.selectingForCopy = selectingForCopy;
|
||||
}
|
||||
|
@ -890,7 +473,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
* Request a different font size. Will make call to parentChanged() to make
|
||||
* sure we resize PTY if needed.
|
||||
*/
|
||||
private final void setFontSize(float size) {
|
||||
/* package */ final void setFontSize(float size) {
|
||||
if (size <= 0.0)
|
||||
return;
|
||||
|
||||
|
@ -915,6 +498,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
|
||||
host.setFontSize((int) fontSize);
|
||||
manager.hostdb.updateFontSize(host);
|
||||
|
||||
forcedSize = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -950,14 +535,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
}
|
||||
|
||||
this.parent = parent;
|
||||
int width = parent.getWidth();
|
||||
int height = parent.getHeight();
|
||||
final int width = parent.getWidth();
|
||||
final int height = parent.getHeight();
|
||||
|
||||
// Something has gone wrong with our layout; we're 0 width or height!
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
clipboard = (ClipboardManager) parent.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
keyListener.setClipboardManager(clipboard);
|
||||
|
||||
if (!forcedSize) {
|
||||
// recalculate buffer size
|
||||
|
@ -1207,10 +793,10 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
if (direction > 0)
|
||||
size -= step;
|
||||
|
||||
forcedSize = true;
|
||||
this.columns = cols;
|
||||
this.rows = rows;
|
||||
setFontSize(size);
|
||||
forcedSize = true;
|
||||
}
|
||||
|
||||
private int fontSizeCompare(float size, int cols, int rows, int width, int height) {
|
||||
|
@ -1359,4 +945,34 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
|
|||
public boolean isUsingNetwork() {
|
||||
return transport.usesNetwork();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public TerminalKeyListener getKeyHandler() {
|
||||
return keyListener;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void resetScrollPosition() {
|
||||
// if we're in scrollback, scroll to bottom of window on input
|
||||
if (buffer.windowBase != buffer.screenBase)
|
||||
buffer.setWindowBase(buffer.screenBase);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void increaseFontSize() {
|
||||
setFontSize(fontSize + FONT_SIZE_STEP);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void decreaseFontSize() {
|
||||
setFontSize(fontSize - FONT_SIZE_STEP);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,486 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.connectbot.service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.connectbot.TerminalView;
|
||||
import org.connectbot.bean.HostBean;
|
||||
import org.connectbot.bean.SelectionArea;
|
||||
import org.connectbot.util.PreferenceConstants;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Configuration;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.ClipboardManager;
|
||||
import android.util.Log;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnKeyListener;
|
||||
import de.mud.terminal.VDUBuffer;
|
||||
import de.mud.terminal.vt320;
|
||||
|
||||
/**
|
||||
* @author kenny
|
||||
*
|
||||
*/
|
||||
public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceChangeListener {
|
||||
private static final String TAG = "ConnectBot.OnKeyListener";
|
||||
|
||||
public final static int META_CTRL_ON = 0x01;
|
||||
public final static int META_CTRL_LOCK = 0x02;
|
||||
public final static int META_ALT_ON = 0x04;
|
||||
public final static int META_ALT_LOCK = 0x08;
|
||||
public final static int META_SHIFT_ON = 0x10;
|
||||
public final static int META_SHIFT_LOCK = 0x20;
|
||||
public final static int META_SLASH = 0x40;
|
||||
public final static int META_TAB = 0x80;
|
||||
|
||||
// The bit mask of momentary and lock states for each
|
||||
public final static int META_CTRL_MASK = META_CTRL_ON | META_CTRL_LOCK;
|
||||
public final static int META_ALT_MASK = META_ALT_ON | META_ALT_LOCK;
|
||||
public final static int META_SHIFT_MASK = META_SHIFT_ON | META_SHIFT_LOCK;
|
||||
|
||||
// All the transient key codes
|
||||
public final static int META_TRANSIENT = META_CTRL_ON | META_ALT_ON
|
||||
| META_SHIFT_ON;
|
||||
|
||||
private final TerminalManager manager;
|
||||
private final TerminalBridge bridge;
|
||||
private final VDUBuffer buffer;
|
||||
private final HostBean host;
|
||||
|
||||
protected KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
|
||||
|
||||
private String keymode = null;
|
||||
private boolean hardKeyboard = false;
|
||||
|
||||
private int metaState = 0;
|
||||
|
||||
private ClipboardManager clipboard = null;
|
||||
private boolean selectingForCopy = false;
|
||||
private final SelectionArea selectionArea;
|
||||
|
||||
private final SharedPreferences prefs;
|
||||
|
||||
public TerminalKeyListener(TerminalManager manager,
|
||||
TerminalBridge bridge,
|
||||
VDUBuffer buffer,
|
||||
HostBean host) {
|
||||
this.manager = manager;
|
||||
this.bridge = bridge;
|
||||
this.buffer = buffer;
|
||||
this.host = host;
|
||||
|
||||
selectionArea = new SelectionArea();
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(manager);
|
||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
hardKeyboard = (manager.res.getConfiguration().keyboard
|
||||
== Configuration.KEYBOARD_QWERTY);
|
||||
|
||||
updateKeymode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle onKey() events coming down from a {@link TerminalView} above us.
|
||||
* Modify the keys to make more sense to a host then pass it to the transport.
|
||||
*/
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
try {
|
||||
final boolean hardKeyboardHidden = manager.hardKeyboardHidden;
|
||||
|
||||
// Ignore all key-up events except for the special keys
|
||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
// There's nothing here for virtual keyboard users.
|
||||
if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden))
|
||||
return false;
|
||||
|
||||
// skip keys if we aren't connected yet or have been disconnected
|
||||
if (bridge.isDisconnected() || bridge.transport == null)
|
||||
return false;
|
||||
|
||||
if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT
|
||||
&& (metaState & META_SLASH) != 0) {
|
||||
metaState &= ~(META_SLASH | META_TRANSIENT);
|
||||
bridge.transport.write('/');
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
|
||||
&& (metaState & META_TAB) != 0) {
|
||||
metaState &= ~(META_TAB | META_TRANSIENT);
|
||||
bridge.transport.write(0x09);
|
||||
return true;
|
||||
}
|
||||
} else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ALT_LEFT
|
||||
&& (metaState & META_SLASH) != 0) {
|
||||
metaState &= ~(META_SLASH | META_TRANSIENT);
|
||||
bridge.transport.write('/');
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
|
||||
&& (metaState & META_TAB) != 0) {
|
||||
metaState &= ~(META_TAB | META_TRANSIENT);
|
||||
bridge.transport.write(0x09);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for terminal resizing keys
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||
bridge.increaseFontSize();
|
||||
return true;
|
||||
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
|
||||
bridge.decreaseFontSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip keys if we aren't connected yet or have been disconnected
|
||||
if (bridge.isDisconnected() || bridge.transport == null)
|
||||
return false;
|
||||
|
||||
bridge.resetScrollPosition();
|
||||
|
||||
boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE);
|
||||
|
||||
// otherwise pass through to existing session
|
||||
// print normal keys
|
||||
if (printing) {
|
||||
int curMetaState = event.getMetaState();
|
||||
|
||||
metaState &= ~(META_SLASH | META_TAB);
|
||||
|
||||
if ((metaState & META_SHIFT_MASK) != 0) {
|
||||
curMetaState |= KeyEvent.META_SHIFT_ON;
|
||||
metaState &= ~META_SHIFT_ON;
|
||||
bridge.redraw();
|
||||
}
|
||||
|
||||
if ((metaState & META_ALT_MASK) != 0) {
|
||||
curMetaState |= KeyEvent.META_ALT_ON;
|
||||
metaState &= ~META_ALT_ON;
|
||||
bridge.redraw();
|
||||
}
|
||||
|
||||
int key = keymap.get(keyCode, curMetaState);
|
||||
|
||||
if ((metaState & META_CTRL_MASK) != 0) {
|
||||
metaState &= ~META_CTRL_ON;
|
||||
bridge.redraw();
|
||||
|
||||
if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden))
|
||||
&& sendFunctionKey(keyCode))
|
||||
return true;
|
||||
|
||||
// Support CTRL-a through CTRL-z
|
||||
if (key >= 0x61 && key <= 0x7A)
|
||||
key -= 0x60;
|
||||
// Support CTRL-A through CTRL-_
|
||||
else if (key >= 0x41 && key <= 0x5F)
|
||||
key -= 0x40;
|
||||
else if (key == 0x20)
|
||||
key = 0x00;
|
||||
else if (key == 0x3F)
|
||||
key = 0x7F;
|
||||
}
|
||||
|
||||
// handle pressing f-keys
|
||||
if ((hardKeyboard && !hardKeyboardHidden)
|
||||
&& (curMetaState & KeyEvent.META_SHIFT_ON) != 0
|
||||
&& sendFunctionKey(keyCode))
|
||||
return true;
|
||||
|
||||
if (key < 0x80)
|
||||
bridge.transport.write(key);
|
||||
else
|
||||
// TODO write encoding routine that doesn't allocate each time
|
||||
bridge.transport.write(new String(Character.toChars(key))
|
||||
.getBytes(host.getEncoding()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_UNKNOWN &&
|
||||
event.getAction() == KeyEvent.ACTION_MULTIPLE) {
|
||||
byte[] input = event.getCharacters().getBytes(host.getEncoding());
|
||||
bridge.transport.write(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
// try handling keymode shortcuts
|
||||
if (hardKeyboard && !hardKeyboardHidden &&
|
||||
event.getRepeatCount() == 0) {
|
||||
if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaState |= META_SLASH;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaState |= META_TAB;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
}
|
||||
} else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
metaState |= META_SLASH;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
metaState |= META_TAB;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
metaPress(META_ALT_ON);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
metaPress(META_SHIFT_ON);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for special chars
|
||||
switch(keyCode) {
|
||||
case KeyEvent.KEYCODE_CAMERA:
|
||||
|
||||
// check to see which shortcut the camera button triggers
|
||||
String camera = manager.prefs.getString(
|
||||
PreferenceConstants.CAMERA,
|
||||
PreferenceConstants.CAMERA_CTRLA_SPACE);
|
||||
if(PreferenceConstants.CAMERA_CTRLA_SPACE.equals(camera)) {
|
||||
bridge.transport.write(0x01);
|
||||
bridge.transport.write(' ');
|
||||
} else if(PreferenceConstants.CAMERA_CTRLA.equals(camera)) {
|
||||
bridge.transport.write(0x01);
|
||||
} else if(PreferenceConstants.CAMERA_ESC.equals(camera)) {
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KeyEvent.KEYCODE_DEL:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_BACK_SPACE, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ENTER, ' ', 0);
|
||||
metaState &= ~META_TRANSIENT;
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.decrementColumn();
|
||||
bridge.redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_LEFT, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
bridge.tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.decrementRow();
|
||||
bridge.redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_UP, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
bridge.tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.incrementRow();
|
||||
bridge.redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_DOWN, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
bridge.tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
if (selectingForCopy) {
|
||||
selectionArea.incrementColumn();
|
||||
bridge.redraw();
|
||||
} else {
|
||||
((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ',
|
||||
getStateForBuffer());
|
||||
metaState &= ~META_TRANSIENT;
|
||||
bridge.tryKeyVibrate();
|
||||
}
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (selectingForCopy) {
|
||||
if (selectionArea.isSelectingOrigin())
|
||||
selectionArea.finishSelectingOrigin();
|
||||
else {
|
||||
if (clipboard != null) {
|
||||
// copy selected area to clipboard
|
||||
String copiedText = selectionArea.copyFrom(buffer);
|
||||
|
||||
clipboard.setText(copiedText);
|
||||
// XXX STOPSHIP
|
||||
// manager.notifyUser(manager.getString(
|
||||
// R.string.console_copy_done,
|
||||
// copiedText.length()));
|
||||
|
||||
selectingForCopy = false;
|
||||
selectionArea.reset();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((metaState & META_CTRL_ON) != 0) {
|
||||
((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0);
|
||||
metaState &= ~META_CTRL_ON;
|
||||
} else
|
||||
metaState |= META_CTRL_ON;
|
||||
}
|
||||
|
||||
bridge.redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Problem while trying to handle an onKey() event", e);
|
||||
try {
|
||||
bridge.transport.flush();
|
||||
} catch (IOException ioe) {
|
||||
Log.d(TAG, "Our transport was closed, dispatching disconnect event");
|
||||
bridge.dispatchDisconnect(false);
|
||||
}
|
||||
} catch (NullPointerException npe) {
|
||||
Log.d(TAG, "Input before connection established ignored.");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return successful
|
||||
*/
|
||||
private boolean sendFunctionKey(int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_1:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F1, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_2:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F2, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_3:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F3, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_4:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F4, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_5:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F5, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_6:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F6, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_7:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F7, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_8:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F8, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_9:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F9, ' ', 0);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_0:
|
||||
((vt320) buffer).keyPressed(vt320.KEY_F10, ' ', 0);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle meta key presses where the key can be locked on.
|
||||
* <p>
|
||||
* 1st press: next key to have meta state<br />
|
||||
* 2nd press: meta state is locked on<br />
|
||||
* 3rd press: disable meta state
|
||||
*
|
||||
* @param code
|
||||
*/
|
||||
private void metaPress(int code) {
|
||||
if ((metaState & (code << 1)) != 0) {
|
||||
metaState &= ~(code << 1);
|
||||
} else if ((metaState & code) != 0) {
|
||||
metaState &= ~code;
|
||||
metaState |= code << 1;
|
||||
} else
|
||||
metaState |= code;
|
||||
bridge.redraw();
|
||||
}
|
||||
|
||||
public void setTerminalKeyMode(String keymode) {
|
||||
this.keymode = keymode;
|
||||
}
|
||||
|
||||
private int getStateForBuffer() {
|
||||
int bufferState = 0;
|
||||
|
||||
if ((metaState & META_CTRL_MASK) != 0)
|
||||
bufferState |= vt320.KEY_CONTROL;
|
||||
if ((metaState & META_SHIFT_MASK) != 0)
|
||||
bufferState |= vt320.KEY_SHIFT;
|
||||
if ((metaState & META_ALT_MASK) != 0)
|
||||
bufferState |= vt320.KEY_ALT;
|
||||
|
||||
return bufferState;
|
||||
}
|
||||
|
||||
public int getMetaState() {
|
||||
return metaState;
|
||||
}
|
||||
|
||||
public void setClipboardManager(ClipboardManager clipboard) {
|
||||
this.clipboard = clipboard;
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||
String key) {
|
||||
if (PreferenceConstants.KEYMODE.equals(key)) {
|
||||
updateKeymode();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateKeymode() {
|
||||
keymode = prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT);
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
|
@ -115,6 +116,8 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
|
|||
protected List<WeakReference<TerminalBridge>> mPendingReconnect
|
||||
= new LinkedList<WeakReference<TerminalBridge>>();
|
||||
|
||||
public boolean hardKeyboardHidden;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.i(TAG, "Starting background service");
|
||||
|
@ -152,6 +155,9 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
|
|||
wantBellVibration = prefs.getBoolean(PreferenceConstants.BELL_VIBRATE, true);
|
||||
enableMediaPlayer();
|
||||
|
||||
hardKeyboardHidden = (res.getConfiguration().hardKeyboardHidden ==
|
||||
Configuration.HARDKEYBOARDHIDDEN_YES);
|
||||
|
||||
final boolean lockingWifi = prefs.getBoolean(PreferenceConstants.WIFI_LOCK, true);
|
||||
|
||||
connectivityManager = new ConnectivityReceiver(this, lockingWifi);
|
||||
|
@ -259,10 +265,6 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
|
|||
return scrollback;
|
||||
}
|
||||
|
||||
public String getKeyMode() {
|
||||
return prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); // "Use right-side keys"
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new connection by reading parameters from the given URI. Follows
|
||||
* format specified by an individual transport.
|
||||
|
|
|
@ -129,4 +129,10 @@ public class NullTransport extends AbsTransport {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesNetwork() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue