X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fio%2FAWTTerminal.java;h=8b542402daf5b7321de855fbeffd8d31f09559c7;hb=091d8a06c7f9f91c2a15c9350b6502cf4c10f5a3;hp=fd03487a61d7f092950d31fb7d7ba4dbbc0ce6fa;hpb=84614868e6bcbe374c0c1ba248ad046ff25ccb2b;p=nikiroo-utils.git diff --git a/src/jexer/io/AWTTerminal.java b/src/jexer/io/AWTTerminal.java index fd03487..8b54240 100644 --- a/src/jexer/io/AWTTerminal.java +++ b/src/jexer/io/AWTTerminal.java @@ -30,27 +30,37 @@ */ package jexer.io; -import java.awt.event.KeyListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.WindowEvent; import java.awt.event.WindowListener; 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; import jexer.event.TMouseEvent; import jexer.event.TResizeEvent; import jexer.session.SessionInfo; -import jexer.session.TSessionInfo; +import jexer.session.AWTSessionInfo; +import static jexer.TCommand.*; import static jexer.TKeypress.*; /** * This class reads keystrokes and mouse events from an AWT Frame. */ -public final class AWTTerminal implements KeyListener { +public final class AWTTerminal implements ComponentListener, KeyListener, + MouseListener, MouseMotionListener, + MouseWheelListener, WindowListener { /** * The backend Screen. @@ -60,7 +70,7 @@ public final class AWTTerminal implements KeyListener { /** * The session information. */ - private SessionInfo sessionInfo; + private AWTSessionInfo sessionInfo; /** * Getter for sessionInfo. @@ -71,35 +81,40 @@ public final class AWTTerminal implements 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. */ private List eventQueue; /** - * If true, we want the reader thread to exit gracefully. + * The last reported mouse X position. */ - private boolean stopReaderThread; + private int oldMouseX = -1; /** - * The reader thread. + * The last reported mouse Y position. */ - private Thread readerThread; + private int oldMouseY = -1; /** * true if mouse1 was down. Used to report mouse1 on the release event. */ - private boolean mouse1; + private boolean mouse1 = false; /** * true if mouse2 was down. Used to report mouse2 on the release event. */ - private boolean mouse2; + private boolean mouse2 = false; /** * true if mouse3 was down. Used to report mouse3 on the release event. */ - private boolean mouse3; + private boolean mouse3 = false; /** * Check if there are events in the queue. @@ -115,18 +130,25 @@ public final class AWTTerminal implements 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; mouse3 = false; - stopReaderThread = false; - sessionInfo = new TSessionInfo(); + sessionInfo = screen.getSessionInfo(); eventQueue = new LinkedList(); screen.frame.addKeyListener(this); + screen.frame.addWindowListener(this); + screen.frame.addComponentListener(this); + screen.frame.addMouseListener(this); + screen.frame.addMouseMotionListener(this); + screen.frame.addMouseWheelListener(this); } /** @@ -153,26 +175,6 @@ public final class AWTTerminal implements KeyListener { } } - /** - * Return any events in the IO queue due to timeout. - * - * @param queue list to append new events to - */ - public void getIdleEvents(final List 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. * @@ -205,7 +207,6 @@ public final class AWTTerminal implements KeyListener { boolean ctrl = false; char ch = ' '; boolean isKey = false; - int fnKey = 0; if (key.isActionKey()) { isKey = true; } else { @@ -222,7 +223,7 @@ public final class AWTTerminal implements 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()) { @@ -312,7 +313,7 @@ public final class AWTTerminal implements KeyListener { alt, ctrl, shift); break; case KeyEvent.VK_DELETE: - keypress = new TKeypress(true, TKeypress.F1, ' ', + keypress = new TKeypress(true, TKeypress.DEL, ' ', alt, ctrl, shift); break; case KeyEvent.VK_RIGHT: @@ -365,12 +366,25 @@ public final class AWTTerminal implements KeyListener { case 0x0A: keypress = kbEnter; break; + case 0x1B: + keypress = kbEsc; + break; case 0x0D: keypress = kbEnter; break; + case 0x09: + if (shift) { + keypress = kbShiftTab; + } else { + keypress = kbTab; + } + break; + case 0x7F: + keypress = kbDel; + break; default: if (!alt && ctrl && !shift) { - ch = key.getKeyText(key.getKeyCode()).charAt(0); + ch = KeyEvent.getKeyText(key.getKeyCode()).charAt(0); } // Not a special key, put it together keypress = new TKeypress(false, 0, ch, alt, ctrl, shift); @@ -381,5 +395,359 @@ public final class AWTTerminal implements KeyListener { synchronized (eventQueue) { eventQueue.add(new TKeypressEvent(keypress)); } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowActivated(final WindowEvent event) { + // Force a total repaint + synchronized (screen) { + screen.clearPhysical(); + } } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowClosed(final WindowEvent event) { + // Ignore + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowClosing(final WindowEvent event) { + // Drop a cmAbort and walk away + synchronized (eventQueue) { + eventQueue.add(new TCommandEvent(cmAbort)); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowDeactivated(final WindowEvent event) { + // Ignore + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowDeiconified(final WindowEvent event) { + // Ignore + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowIconified(final WindowEvent event) { + // Ignore + } + + /** + * Pass window events into the event queue. + * + * @param event window event received + */ + @Override + public void windowOpened(final WindowEvent event) { + // Ignore + } + + /** + * Pass component events into the event queue. + * + * @param event component event received + */ + @Override + public void componentHidden(final ComponentEvent event) { + // Ignore + } + + /** + * Pass component events into the event queue. + * + * @param event component event received + */ + @Override + public void componentShown(final ComponentEvent event) { + // Ignore + } + + /** + * Pass component events into the event queue. + * + * @param event component event received + */ + @Override + public void componentMoved(final ComponentEvent event) { + // Ignore + } + + /** + * Pass component events into the event queue. + * + * @param event component event received + */ + @Override + public void componentResized(final ComponentEvent event) { + // Drop a new TResizeEvent into the queue + sessionInfo.queryWindowSize(); + synchronized (eventQueue) { + TResizeEvent windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN, + sessionInfo.getWindowWidth(), sessionInfo.getWindowHeight()); + eventQueue.add(windowResize); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseDragged(final MouseEvent mouse) { + int modifiers = mouse.getModifiersEx(); + boolean eventMouse1 = false; + boolean eventMouse2 = false; + boolean eventMouse3 = false; + if ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) { + eventMouse1 = true; + } + if ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) { + eventMouse2 = true; + } + if ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) { + eventMouse3 = true; + } + mouse1 = eventMouse1; + mouse2 = eventMouse2; + mouse3 = eventMouse3; + 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); + + synchronized (eventQueue) { + eventQueue.add(mouseEvent); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseMoved(final MouseEvent mouse) { + 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); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseClicked(final MouseEvent mouse) { + // Ignore + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseEntered(final MouseEvent mouse) { + // Ignore + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseExited(final MouseEvent mouse) { + // Ignore + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mousePressed(final MouseEvent mouse) { + int modifiers = mouse.getModifiersEx(); + boolean eventMouse1 = false; + boolean eventMouse2 = false; + boolean eventMouse3 = false; + if ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) { + eventMouse1 = true; + } + if ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) { + eventMouse2 = true; + } + if ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) { + eventMouse3 = true; + } + mouse1 = eventMouse1; + mouse2 = eventMouse2; + mouse3 = eventMouse3; + 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); + + synchronized (eventQueue) { + eventQueue.add(mouseEvent); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseReleased(final MouseEvent mouse) { + int modifiers = mouse.getModifiersEx(); + boolean eventMouse1 = false; + boolean eventMouse2 = false; + boolean eventMouse3 = false; + if ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) { + eventMouse1 = true; + } + if ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) { + eventMouse2 = true; + } + if ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) { + eventMouse3 = true; + } + if (mouse1) { + mouse1 = false; + eventMouse1 = true; + } + if (mouse2) { + mouse2 = false; + eventMouse2 = true; + } + if (mouse3) { + mouse3 = false; + eventMouse3 = true; + } + 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); + + synchronized (eventQueue) { + eventQueue.add(mouseEvent); + } + synchronized (listener) { + listener.notifyAll(); + } + } + + /** + * Pass mouse events into the event queue. + * + * @param mouse mouse event received + */ + @Override + public void mouseWheelMoved(final MouseWheelEvent mouse) { + int modifiers = mouse.getModifiersEx(); + boolean eventMouse1 = false; + boolean eventMouse2 = false; + boolean eventMouse3 = false; + boolean mouseWheelUp = false; + boolean mouseWheelDown = false; + if ((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) { + eventMouse1 = true; + } + if ((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) { + eventMouse2 = true; + } + if ((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) { + eventMouse3 = true; + } + mouse1 = eventMouse1; + mouse2 = eventMouse2; + mouse3 = eventMouse3; + int x = screen.textColumn(mouse.getX()); + int y = screen.textRow(mouse.getY()); + if (mouse.getWheelRotation() > 0) { + mouseWheelDown = true; + } + if (mouse.getWheelRotation() < 0) { + mouseWheelUp = true; + } + + TMouseEvent mouseEvent = new TMouseEvent(TMouseEvent.Type.MOUSE_DOWN, + x, y, x, y, mouse1, mouse2, mouse3, mouseWheelUp, mouseWheelDown); + + synchronized (eventQueue) { + eventQueue.add(mouseEvent); + } + synchronized (listener) { + listener.notifyAll(); + } + } + }