misc cleanup
[fanfix.git] / src / jexer / io / ECMA48Terminal.java
index 064c4ec99f98b7d85963adc1429316751bcb4601..d466646d5d129b312a8d93aa85c61812502738ec 100644 (file)
@@ -61,7 +61,7 @@ import static jexer.TKeypress.*;
  * 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.
@@ -73,7 +73,7 @@ public class ECMA48Terminal implements Runnable {
      *
      * @return the SessionInfo
      */
-    public final SessionInfo getSessionInfo() {
+    public SessionInfo getSessionInfo() {
         return sessionInfo;
     }
 
@@ -127,6 +127,12 @@ public class ECMA48Terminal implements Runnable {
      */
     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.
      */
@@ -243,7 +249,7 @@ public class ECMA48Terminal implements Runnable {
         };
         try {
             Process process;
-            if (mode == true) {
+            if (mode) {
                 process = Runtime.getRuntime().exec(cmdRaw);
             } else {
                 process = Runtime.getRuntime().exec(cmdCooked);
@@ -634,7 +640,9 @@ public class ECMA48Terminal implements Runnable {
     public void getEvents(final List<TInputEvent> queue) {
         synchronized (eventQueue) {
             if (eventQueue.size() > 0) {
-                queue.addAll(eventQueue);
+                synchronized (queue) {
+                    queue.addAll(eventQueue);
+                }
                 eventQueue.clear();
             }
         }
@@ -645,28 +653,34 @@ public class ECMA48Terminal implements Runnable {
      *
      * @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();
             }
         }
     }
@@ -792,7 +806,7 @@ public class ECMA48Terminal implements Runnable {
             // Parameter separator
             if (ch == ';') {
                 paramI++;
-                params.set(paramI, "");
+                params.add("");
                 return;
             }
 
@@ -900,7 +914,7 @@ public class ECMA48Terminal implements Runnable {
             // Parameter separator
             if (ch == ';') {
                 paramI++;
-                params.set(paramI, "");
+                params.add(paramI, "");
                 return;
             }
 
@@ -1445,8 +1459,16 @@ public class ECMA48Terminal implements Runnable {
                         }
                     }
                 } 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) {