* This class reads keystrokes and mouse events and emits output to ANSI
* X3.64 / ECMA-48 type terminals e.g. xterm, linux, vt100, ansi.sys, etc.
*/
-public class ECMA48Terminal implements Runnable {
+public final class ECMA48Terminal implements Runnable {
/**
* The session information.
*
* @return the SessionInfo
*/
- public final SessionInfo getSessionInfo() {
+ public SessionInfo getSessionInfo() {
return sessionInfo;
}
*/
private long escapeTime;
+ /**
+ * The time we last checked the window size. We try not to spawn stty
+ * more than once per second.
+ */
+ private long windowSizeTime;
+
/**
* true if mouse1 was down. Used to report mouse1 on the release event.
*/
};
try {
Process process;
- if (mode == true) {
+ if (mode) {
process = Runtime.getRuntime().exec(cmdRaw);
} else {
process = Runtime.getRuntime().exec(cmdCooked);
// Unknown modifier, bail out
return null;
}
-
+
switch (key) {
case 1:
return new TKeypressEvent(kbHome, alt, ctrl, shift);
y = windowResize.getHeight() - 1;
}
- TMouseEvent event = new TMouseEvent(TMouseEvent.Type.MOUSE_DOWN);
- event.x = x;
- event.y = y;
- event.absoluteX = x;
- event.absoluteY = y;
+ TMouseEvent.Type eventType = TMouseEvent.Type.MOUSE_DOWN;
+ boolean eventMouse1 = false;
+ boolean eventMouse2 = false;
+ boolean eventMouse3 = false;
+ boolean eventMouseWheelUp = false;
+ boolean eventMouseWheelDown = false;
// System.err.printf("buttons: %04x\r\n", buttons);
switch (buttons) {
case 0:
- event.mouse1 = true;
+ eventMouse1 = true;
mouse1 = true;
break;
case 1:
- event.mouse2 = true;
+ eventMouse2 = true;
mouse2 = true;
break;
case 2:
- event.mouse3 = true;
+ eventMouse3 = true;
mouse3 = true;
break;
case 3:
// Release or Move
if (!mouse1 && !mouse2 && !mouse3) {
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
} else {
- event.type = TMouseEvent.Type.MOUSE_UP;
+ eventType = TMouseEvent.Type.MOUSE_UP;
}
if (mouse1) {
mouse1 = false;
- event.mouse1 = true;
+ eventMouse1 = true;
}
if (mouse2) {
mouse2 = false;
- event.mouse2 = true;
+ eventMouse2 = true;
}
if (mouse3) {
mouse3 = false;
- event.mouse3 = true;
+ eventMouse3 = true;
}
break;
case 32:
// Dragging with mouse1 down
- event.mouse1 = true;
+ eventMouse1 = true;
mouse1 = true;
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
case 33:
// Dragging with mouse2 down
- event.mouse2 = true;
+ eventMouse2 = true;
mouse2 = true;
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
case 34:
// Dragging with mouse3 down
- event.mouse3 = true;
+ eventMouse3 = true;
mouse3 = true;
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
case 96:
// Dragging with mouse2 down after wheelUp
- event.mouse2 = true;
+ eventMouse2 = true;
mouse2 = true;
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
case 97:
// Dragging with mouse2 down after wheelDown
- event.mouse2 = true;
+ eventMouse2 = true;
mouse2 = true;
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
case 64:
- event.mouseWheelUp = true;
+ eventMouseWheelUp = true;
break;
case 65:
- event.mouseWheelDown = true;
+ eventMouseWheelDown = true;
break;
default:
// Unknown, just make it motion
- event.type = TMouseEvent.Type.MOUSE_MOTION;
+ eventType = TMouseEvent.Type.MOUSE_MOTION;
break;
}
- return event;
+ return new TMouseEvent(eventType, x, y, x, y,
+ eventMouse1, eventMouse2, eventMouse3,
+ eventMouseWheelUp, eventMouseWheelDown);
}
/**
public void getEvents(final List<TInputEvent> queue) {
synchronized (eventQueue) {
if (eventQueue.size() > 0) {
- queue.addAll(eventQueue);
+ synchronized (queue) {
+ queue.addAll(eventQueue);
+ }
eventQueue.clear();
}
}
*
* @param queue list to append new events to
*/
- public void getIdleEvents(final List<TInputEvent> queue) {
+ private void getIdleEvents(final List<TInputEvent> queue) {
+ Date now = new Date();
// Check for new window size
- sessionInfo.queryWindowSize();
- int newWidth = sessionInfo.getWindowWidth();
- int newHeight = sessionInfo.getWindowHeight();
- if ((newWidth != windowResize.getWidth())
- || (newHeight != windowResize.getHeight())
- ) {
- TResizeEvent event = new TResizeEvent(TResizeEvent.Type.SCREEN,
- newWidth, newHeight);
- windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN,
- newWidth, newHeight);
- synchronized (eventQueue) {
- eventQueue.add(event);
+ long windowSizeDelay = now.getTime() - windowSizeTime;
+ if (windowSizeDelay > 1000) {
+ sessionInfo.queryWindowSize();
+ int newWidth = sessionInfo.getWindowWidth();
+ int newHeight = sessionInfo.getWindowHeight();
+ if ((newWidth != windowResize.getWidth())
+ || (newHeight != windowResize.getHeight())
+ ) {
+ TResizeEvent event = new TResizeEvent(TResizeEvent.Type.SCREEN,
+ newWidth, newHeight);
+ windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN,
+ newWidth, newHeight);
+ queue.add(event);
}
+ windowSizeTime = now.getTime();
}
- synchronized (eventQueue) {
- if (eventQueue.size() > 0) {
- queue.addAll(eventQueue);
- eventQueue.clear();
+ // ESCDELAY type timeout
+ if (state == ParseState.ESCAPE) {
+ long escDelay = now.getTime() - escapeTime;
+ if (escDelay > 100) {
+ // After 0.1 seconds, assume a true escape character
+ queue.add(controlChar((char)0x1B, false));
+ reset();
}
}
}
// Parameter separator
if (ch == ';') {
paramI++;
- params.set(paramI, "");
+ params.add("");
return;
}
// Parameter separator
if (ch == ';') {
paramI++;
- params.set(paramI, "");
+ params.add(paramI, "");
return;
}
}
}
} else {
- // Wait 5 millis for more data
- Thread.sleep(5);
+ getIdleEvents(events);
+ if (events.size() > 0) {
+ synchronized (eventQueue) {
+ eventQueue.addAll(events);
+ }
+ events.clear();
+ }
+
+ // Wait 10 millis for more data
+ Thread.sleep(10);
}
// System.err.println("end while loop"); System.err.flush();
} catch (InterruptedException e) {