mouse support inside terminal
[nikiroo-utils.git] / src / jexer / io / AWTTerminal.java
index d7716c6c8cb299f17a62d148555c7a5ff0225c45..38f6734b96fcea4c8aac2c97cb5e774c636a7caa 100644 (file)
@@ -45,7 +45,6 @@ import java.util.List;
 import java.util.LinkedList;
 
 import jexer.TKeypress;
-import jexer.bits.Color;
 import jexer.event.TCommandEvent;
 import jexer.event.TInputEvent;
 import jexer.event.TKeypressEvent;
@@ -82,6 +81,11 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         return sessionInfo;
     }
 
+    /**
+     * The listening object that run() wakes up on new input.
+     */
+    private Object listener;
+
     /**
      * The event queue, filled up by a thread reading on input.
      */
@@ -92,6 +96,16 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
      */
     private Thread readerThread;
 
+    /**
+     * The last reported mouse X position.
+     */
+    private int oldMouseX = -1;
+
+    /**
+     * The last reported mouse Y position.
+     */
+    private int oldMouseY = -1;
+
     /**
      * true if mouse1 was down.  Used to report mouse1 on the release event.
      */
@@ -121,9 +135,12 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
     /**
      * Constructor sets up state for getEvent().
      *
+     * @param listener the object this backend needs to wake up when new
+     * input comes in
      * @param screen the top-level AWT frame
      */
-    public AWTTerminal(final AWTScreen screen) {
+    public AWTTerminal(final Object listener, final AWTScreen screen) {
+        this.listener    = listener;
         this.screen      = screen;
         mouse1           = false;
         mouse2           = false;
@@ -163,26 +180,6 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         }
     }
 
-    /**
-     * Return any events in the IO queue due to timeout.
-     *
-     * @param queue list to append new events to
-     */
-    public void getIdleEvents(final List<TInputEvent> queue) {
-
-        // Insert any polling action here...
-
-        // Return any events that showed up
-        synchronized (eventQueue) {
-            if (eventQueue.size() > 0) {
-                synchronized (queue) {
-                    queue.addAll(eventQueue);
-                }
-                eventQueue.clear();
-            }
-        }
-    }
-
     /**
      * Pass AWT keystrokes into the event queue.
      *
@@ -232,7 +229,7 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         System.err.printf("   ctrl: %s\n", ctrl);
         System.err.printf("   shift: %s\n", shift);
         System.err.printf("   ch: %s\n", ch);
-         */
+        */
 
         // Special case: not return the bare modifier presses
         switch (key.getKeyCode()) {
@@ -375,9 +372,15 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
             case 0x0A:
                 keypress = kbEnter;
                 break;
+            case 0x1B:
+                keypress = kbEsc;
+                break;
             case 0x0D:
                 keypress = kbEnter;
                 break;
+            case 0x09:
+                keypress = kbTab;
+                break;
             case 0x7F:
                 keypress = kbDel;
                 break;
@@ -394,9 +397,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(new TKeypressEvent(keypress));
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -407,7 +409,10 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
      */
     @Override
     public void windowActivated(final WindowEvent event) {
-        // Ignore
+        // Force a total repaint
+        synchronized (screen) {
+            screen.clearPhysical();
+        }
     }
 
     /**
@@ -431,9 +436,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(new TCommandEvent(cmAbort));
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -521,9 +525,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
                 sessionInfo.getWindowWidth(), sessionInfo.getWindowHeight());
             eventQueue.add(windowResize);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -550,8 +553,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         mouse1 = eventMouse1;
         mouse2 = eventMouse2;
         mouse3 = eventMouse3;
-        int x = sessionInfo.textColumn(mouse.getX());
-        int y = sessionInfo.textRow(mouse.getY());
+        int x = screen.textColumn(mouse.getX());
+        int y = screen.textRow(mouse.getY());
 
         TMouseEvent mouseEvent = new TMouseEvent(TMouseEvent.Type.MOUSE_MOTION,
             x, y, x, y, mouse1, mouse2, mouse3, false, false);
@@ -559,9 +562,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(mouseEvent);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -572,17 +574,23 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
      */
     @Override
     public void mouseMoved(final MouseEvent mouse) {
-        int x = sessionInfo.textColumn(mouse.getX());
-        int y = sessionInfo.textRow(mouse.getY());
+        int x = screen.textColumn(mouse.getX());
+        int y = screen.textRow(mouse.getY());
+        if ((x == oldMouseX) && (y == oldMouseY)) {
+            // Bail out, we've moved some pixels but not a whole text cell.
+            return;
+        }
+        oldMouseX = x;
+        oldMouseY = y;
+
         TMouseEvent mouseEvent = new TMouseEvent(TMouseEvent.Type.MOUSE_MOTION,
             x, y, x, y, mouse1, mouse2, mouse3, false, false);
 
         synchronized (eventQueue) {
             eventQueue.add(mouseEvent);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -639,8 +647,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         mouse1 = eventMouse1;
         mouse2 = eventMouse2;
         mouse3 = eventMouse3;
-        int x = sessionInfo.textColumn(mouse.getX());
-        int y = sessionInfo.textRow(mouse.getY());
+        int x = screen.textColumn(mouse.getX());
+        int y = screen.textRow(mouse.getY());
 
         TMouseEvent mouseEvent = new TMouseEvent(TMouseEvent.Type.MOUSE_DOWN,
             x, y, x, y, mouse1, mouse2, mouse3, false, false);
@@ -648,9 +656,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(mouseEvent);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -686,8 +693,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
             mouse3 = false;
             eventMouse3 = true;
         }
-        int x = sessionInfo.textColumn(mouse.getX());
-        int y = sessionInfo.textRow(mouse.getY());
+        int x = screen.textColumn(mouse.getX());
+        int y = screen.textRow(mouse.getY());
 
         TMouseEvent mouseEvent = new TMouseEvent(TMouseEvent.Type.MOUSE_UP,
             x, y, x, y, eventMouse1, eventMouse2, eventMouse3, false, false);
@@ -695,9 +702,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(mouseEvent);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }
 
@@ -726,8 +732,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         mouse1 = eventMouse1;
         mouse2 = eventMouse2;
         mouse3 = eventMouse3;
-        int x = sessionInfo.textColumn(mouse.getX());
-        int y = sessionInfo.textRow(mouse.getY());
+        int x = screen.textColumn(mouse.getX());
+        int y = screen.textRow(mouse.getY());
         if (mouse.getWheelRotation() > 0) {
             mouseWheelDown = true;
         }
@@ -741,9 +747,8 @@ public final class AWTTerminal implements ComponentListener, KeyListener,
         synchronized (eventQueue) {
             eventQueue.add(mouseEvent);
         }
-        // Wake up the backend
-        synchronized (this) {
-            this.notifyAll();
+        synchronized (listener) {
+            listener.notifyAll();
         }
     }