aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Klein <jklein24@gmail.com>2015-10-01 15:25:59 -0700
committerJeremy Klein <jklein24@gmail.com>2015-10-01 15:25:59 -0700
commit4c0ca79b464af40b5a41e39bcd3d7968abde5c9a (patch)
tree4b4d219d6b53c62492580c9aa27ca8fd5b7501a1
parentf5ff9f7bda5d05434471050533d404452275a38e (diff)
parentd531902ab57cdca8f4b40ecc4bbf290b56562649 (diff)
downloadconnectbot-4c0ca79b464af40b5a41e39bcd3d7968abde5c9a.tar.gz
connectbot-4c0ca79b464af40b5a41e39bcd3d7968abde5c9a.tar.bz2
connectbot-4c0ca79b464af40b5a41e39bcd3d7968abde5c9a.zip
Merge pull request #267 from jklein24/mouseevents
Forward mouseevents to the terminal when appropriate.
-rw-r--r--app/src/main/java/de/mud/terminal/VDUInput.java14
-rw-r--r--app/src/main/java/de/mud/terminal/vt320.java76
-rw-r--r--app/src/main/java/org/connectbot/ConsoleActivity.java111
-rw-r--r--app/src/main/java/org/connectbot/TerminalView.java18
4 files changed, 198 insertions, 21 deletions
diff --git a/app/src/main/java/de/mud/terminal/VDUInput.java b/app/src/main/java/de/mud/terminal/VDUInput.java
index 43c88de..e1bce90 100644
--- a/app/src/main/java/de/mud/terminal/VDUInput.java
+++ b/app/src/main/java/de/mud/terminal/VDUInput.java
@@ -57,13 +57,23 @@ public interface VDUInput {
void mousePressed(int x, int y, int modifiers);
/**
+ * Passes mouse wheel events to the terminal.
+ * @param down True if scrolling down the page. False if scrolling up.
+ * @param x
+ * @param y
+ * @param ctrl
+ * @param shift
+ * @param meta
+ */
+ public void mouseWheel(boolean down, int x, int y, boolean ctrl, boolean shift, boolean meta);
+
+ /**
* Terminal is mouse-aware and requires the coordinates and button
* of the release.
* @param x
* @param y
- * @param modifiers
*/
- void mouseReleased(int x, int y, int modifiers);
+ void mouseReleased(int x, int y);
/**
* Override the standard key codes used by the terminal emulation.
diff --git a/app/src/main/java/de/mud/terminal/vt320.java b/app/src/main/java/de/mud/terminal/vt320.java
index 73369af..ab4a90d 100644
--- a/app/src/main/java/de/mud/terminal/vt320.java
+++ b/app/src/main/java/de/mud/terminal/vt320.java
@@ -336,6 +336,10 @@ public void setScreenSize(int c, int r, boolean broadcast) {
this(80, 24);
}
+ public boolean isMouseReportEnabled() {
+ return mouserpt != 0;
+ }
+
/**
* Terminal is mouse-aware and requires (x,y) coordinates of
* on the terminal (character coordinates) and the button clicked.
@@ -372,13 +376,81 @@ public void setScreenSize(int c, int r, boolean broadcast) {
}
/**
+ * Passes mouse wheel events to the terminal.
+ * @param down True if scrolling down the page. False if scrolling up.
+ * @param x
+ * @param y
+ * @param ctrl
+ * @param shift
+ * @param meta
+ */
+ public void mouseWheel(boolean down, int x, int y, boolean ctrl, boolean shift, boolean meta) {
+ if (mouserpt == 0 || mouserpt == 9)
+ return;
+
+ int mods = 0;
+ if (ctrl) mods |= 16;
+ if (shift) mods |= 4;
+ if (meta) mods |= 8;
+
+ int mousecode = ((down ? 0 : 1) + 96) | 0x20 | mods;
+
+ byte b[] = new byte[6];
+
+ b[0] = 27;
+ b[1] = (byte) '[';
+ b[2] = (byte) 'M';
+ b[3] = (byte) mousecode;
+ b[4] = (byte) (0x20 + x + 1);
+ b[5] = (byte) (0x20 + y + 1);
+
+ write(b); // FIXME: writeSpecial here
+ }
+
+ /**
+ * Passes mouse move events to the terminal.
+ * @param button The mouse button pressed. 3 indicates no button is pressed.
+ * @param x
+ * @param y
+ * @param ctrl
+ * @param shift
+ * @param meta
+ */
+ public void mouseMoved(int button, int x, int y, boolean ctrl, boolean shift, boolean meta) {
+ if (mouserpt != 1002 && mouserpt != 1003)
+ return;
+
+ // 1002 only reports drags. 1003 reports any movement.
+ if (mouserpt == 1002 && button == 3)
+ return;
+
+ int mods = 0;
+ if (ctrl) mods |= 16;
+ if (shift) mods |= 4;
+ if (meta) mods |= 8;
+
+ // Normal mouse code plus additional 32 to indicate movement.
+ int mousecode = (button + 0x40) | mods;
+
+ byte b[] = new byte[6];
+
+ b[0] = 27;
+ b[1] = (byte) '[';
+ b[2] = (byte) 'M';
+ b[3] = (byte) mousecode;
+ b[4] = (byte) (0x20 + x + 1);
+ b[5] = (byte) (0x20 + y + 1);
+
+ write(b); // FIXME: writeSpecial here
+ }
+
+ /**
* Terminal is mouse-aware and requires the coordinates and button
* of the release.
* @param x
* @param y
- * @param modifiers
*/
- public void mouseReleased(int x, int y, int modifiers) {
+ public void mouseReleased(int x, int y) {
if (mouserpt == 0)
return;
diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java
index 5258bef..d628a07 100644
--- a/app/src/main/java/org/connectbot/ConsoleActivity.java
+++ b/app/src/main/java/org/connectbot/ConsoleActivity.java
@@ -30,6 +30,7 @@ import org.connectbot.service.TerminalKeyListener;
import org.connectbot.service.TerminalManager;
import org.connectbot.util.PreferenceConstants;
+import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
@@ -743,32 +744,21 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
pager.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
+ TerminalBridge bridge = adapter.getCurrentTerminalView().bridge;
// Handle mouse-specific actions.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH &&
- MotionEventCompat.getSource(event) == InputDevice.SOURCE_MOUSE &&
- event.getAction() == MotionEvent.ACTION_DOWN) {
- switch (event.getButtonState()) {
- case MotionEvent.BUTTON_PRIMARY:
- // Automatically start copy mode if using a mouse.
- startCopyMode();
- break;
- case MotionEvent.BUTTON_SECONDARY:
- openContextMenu(pager);
- return true;
- case MotionEvent.BUTTON_TERTIARY:
- // Middle click pastes.
- pasteIntoTerminal();
+ MotionEventCompat.getSource(event) == InputDevice.SOURCE_MOUSE) {
+ if (onMouseEvent(event, bridge)) {
return true;
}
}
// when copying, highlight the area
if (copySource != null && copySource.isSelectingForCopy()) {
- int row = (int) Math.floor(event.getY() / copySource.charHeight);
- int col = (int) Math.floor(event.getX() / copySource.charWidth);
-
SelectionArea area = copySource.getSelectionArea();
+ int row = (int) Math.floor(event.getY() / bridge.charHeight);
+ int col = (int) Math.floor(event.getX() / bridge.charWidth);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
@@ -838,10 +828,99 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
return detect.onTouchEvent(event);
}
+ /**
+ * @param event
+ * @param bridge
+ * @return True if the event is handled.
+ */
+ @TargetApi(14)
+ private boolean onMouseEvent(MotionEvent event, TerminalBridge bridge) {
+ int row = (int) Math.floor(event.getY() / bridge.charHeight);
+ int col = (int) Math.floor(event.getX() / bridge.charWidth);
+ int meta = event.getMetaState();
+ boolean shiftOn = (meta & KeyEvent.META_SHIFT_ON) != 0;
+ boolean mouseReport = ((vt320) bridge.buffer).isMouseReportEnabled();
+
+ // MouseReport can be "defeated" using the shift key.
+ if ((!mouseReport || shiftOn)) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ switch (event.getButtonState()) {
+ case MotionEvent.BUTTON_PRIMARY:
+ // Automatically start copy mode if using a mouse.
+ startCopyMode();
+ break;
+ case MotionEvent.BUTTON_SECONDARY:
+ openContextMenu(pager);
+ return true;
+ case MotionEvent.BUTTON_TERTIARY:
+ // Middle click pastes.
+ pasteIntoTerminal();
+ return true;
+ }
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ ((vt320) bridge.buffer).mousePressed(
+ col, row, mouseEventToJavaModifiers(event));
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ ((vt320) bridge.buffer).mouseReleased(col, row);
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ int buttonState = event.getButtonState();
+ int button = (buttonState & MotionEvent.BUTTON_PRIMARY) != 0 ? 0 :
+ (buttonState & MotionEvent.BUTTON_SECONDARY) != 0 ? 1 :
+ (buttonState & MotionEvent.BUTTON_TERTIARY) != 0 ? 2 : 3;
+ ((vt320) bridge.buffer).mouseMoved(
+ button,
+ col,
+ row,
+ (meta & KeyEvent.META_CTRL_ON) != 0,
+ (meta & KeyEvent.META_SHIFT_ON) != 0,
+ (meta & KeyEvent.META_META_ON) != 0);
+ return true;
+ }
+
+ return false;
+ }
+
});
}
/**
+ * Takes an android mouse event and produces a Java InputEvent modifiers int which can be
+ * passed to vt320.
+ * @param mouseEvent The {@link MotionEvent} which should be a mouse click or release.
+ * @return A Java InputEvent modifier int. See
+ * http://docs.oracle.com/javase/7/docs/api/java/awt/event/InputEvent.html
+ */
+ @TargetApi(14)
+ private static int mouseEventToJavaModifiers(MotionEvent mouseEvent) {
+ if (MotionEventCompat.getSource(mouseEvent) != InputDevice.SOURCE_MOUSE) return 0;
+
+ int mods = 0;
+
+ // See http://docs.oracle.com/javase/7/docs/api/constant-values.html
+ int buttonState = mouseEvent.getButtonState();
+ if ((buttonState & MotionEvent.BUTTON_PRIMARY) != 0)
+ mods |= 16;
+ if ((buttonState & MotionEvent.BUTTON_SECONDARY) != 0)
+ mods |= 8;
+ if ((buttonState & MotionEvent.BUTTON_TERTIARY) != 0)
+ mods |= 4;
+
+ // Note: Meta and Ctrl are intentionally swapped here to keep logic in vt320 simple.
+ int meta = mouseEvent.getMetaState();
+ if ((meta & KeyEvent.META_META_ON) != 0)
+ mods |= 2;
+ if ((meta & KeyEvent.META_SHIFT_ON) != 0)
+ mods |= 1;
+ if ((meta & KeyEvent.META_CTRL_ON) != 0)
+ mods |= 4;
+
+ return mods;
+ }
+
+ /**
* Ties the {@link TabLayout} to the {@link ViewPager}.
*
* <p>This method will:
diff --git a/app/src/main/java/org/connectbot/TerminalView.java b/app/src/main/java/org/connectbot/TerminalView.java
index 261407c..7c4f51f 100644
--- a/app/src/main/java/org/connectbot/TerminalView.java
+++ b/app/src/main/java/org/connectbot/TerminalView.java
@@ -26,6 +26,7 @@ import org.connectbot.service.FontSizeChangedListener;
import org.connectbot.service.TerminalBridge;
import org.connectbot.service.TerminalKeyListener;
+import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -52,6 +53,7 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Toast;
import de.mud.terminal.VDUBuffer;
+import de.mud.terminal.vt320;
/**
* User interface {@link View} for showing a TerminalBridge in an
@@ -323,13 +325,27 @@ public class TerminalView extends View implements FontSizeChangedListener {
}
@Override
+ @TargetApi(12)
public boolean onGenericMotionEvent(MotionEvent event) {
if ((MotionEventCompat.getSource(event) & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
// Process scroll wheel movement:
float yDistance = MotionEventCompat.getAxisValue(event, MotionEvent.AXIS_VSCROLL);
- if (yDistance != 0) {
+ boolean mouseReport = ((vt320) bridge.buffer).isMouseReportEnabled();
+ if (mouseReport) {
+ int row = (int) Math.floor(event.getY() / bridge.charHeight);
+ int col = (int) Math.floor(event.getX() / bridge.charWidth);
+
+ ((vt320) bridge.buffer).mouseWheel(
+ yDistance > 0,
+ col,
+ row,
+ (event.getMetaState() & KeyEvent.META_CTRL_ON) != 0,
+ (event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0,
+ (event.getMetaState() & KeyEvent.META_META_ON) != 0);
+ return true;
+ } else if (yDistance != 0) {
int base = bridge.buffer.getWindowBase();
bridge.buffer.setWindowBase(base - Math.round(yDistance));
return true;