X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fbackend%2FSwingTerminal.java;h=a98063867e75479c2b18d91e2872fb2fdadec4a5;hb=be9987235887cb73637b91ab6921158ecaef9d95;hp=6e902195fa59d40a8306fc1f27a713440992c364;hpb=3e0743556d1f31723a11a6019b5c2b018b4b2104;p=fanfix.git diff --git a/src/jexer/backend/SwingTerminal.java b/src/jexer/backend/SwingTerminal.java index 6e90219..a980638 100644 --- a/src/jexer/backend/SwingTerminal.java +++ b/src/jexer/backend/SwingTerminal.java @@ -36,6 +36,7 @@ import java.awt.Graphics2D; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.KeyEvent; @@ -50,7 +51,6 @@ import java.awt.event.WindowListener; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.InputStream; -import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -241,11 +241,22 @@ public final class SwingTerminal extends LogicalScreen private CursorStyle cursorStyle = CursorStyle.UNDERLINE; /** - * The number of millis to wait before switching the blink from - * visible to invisible. + * The number of millis to wait before switching the blink from visible + * to invisible. Set to 0 or negative to disable blinking. */ private long blinkMillis = 500; + /** + * Get the number of millis to wait before switching the blink from + * visible to invisible. + * + * @return the number of milli to wait before switching the blink from + * visible to invisible + */ + public long getBlinkMillis() { + return blinkMillis; + } + /** * If true, the cursor should be visible right now based on the blink * time. @@ -633,6 +644,8 @@ public final class SwingTerminal extends LogicalScreen private void drawCursor(final Graphics gr) { if (cursorVisible + && (cursorY >= 0) + && (cursorX >= 0) && (cursorY <= height - 1) && (cursorX <= width - 1) && cursorBlinkVisible @@ -657,6 +670,14 @@ public final class SwingTerminal extends LogicalScreen } } + /** + * Reset the blink timer. + */ + private void resetBlinkTimer() { + lastBlinkTime = System.currentTimeMillis(); + cursorBlinkVisible = true; + } + /** * Paint redraws the whole screen. * @@ -666,21 +687,12 @@ public final class SwingTerminal extends LogicalScreen if (gotFontDimensions == false) { // Lazy-load the text width/height - // System.err.println("calling getFontDimensions..."); getFontDimensions(gr); /* System.err.println("textWidth " + textWidth + " textHeight " + textHeight); System.err.println("FONT: " + swing.getFont() + " font " + font); */ - // resizeToScreen(); - } - - // See if it is time to flip the blink time. - long nowTime = (new Date()).getTime(); - if (nowTime > blinkMillis + lastBlinkTime) { - lastBlinkTime = nowTime; - cursorBlinkVisible = !cursorBlinkVisible; } int xCellMin = 0; @@ -750,7 +762,6 @@ public final class SwingTerminal extends LogicalScreen } drawCursor(gr); - dirty = false; reallyCleared = false; } // synchronized (this) } @@ -767,9 +778,39 @@ public final class SwingTerminal extends LogicalScreen */ @Override public void flushPhysical() { + // See if it is time to flip the blink time. + long nowTime = System.currentTimeMillis(); + if (nowTime >= blinkMillis + lastBlinkTime) { + lastBlinkTime = nowTime; + cursorBlinkVisible = !cursorBlinkVisible; + // System.err.println("New lastBlinkTime: " + lastBlinkTime); + } + + if ((swing.getFrame() != null) + && (swing.getBufferStrategy() != null) + ) { + do { + do { + drawToSwing(); + } while (swing.getBufferStrategy().contentsRestored()); + + swing.getBufferStrategy().show(); + Toolkit.getDefaultToolkit().sync(); + } while (swing.getBufferStrategy().contentsLost()); + + } else { + // Non-triple-buffered, call drawToSwing() once + drawToSwing(); + } + } + + /** + * Push the logical screen to the physical device. + */ + private void drawToSwing() { /* - System.err.printf("flushPhysical(): reallyCleared %s dirty %s\n", + System.err.printf("drawToSwing(): reallyCleared %s dirty %s\n", reallyCleared, dirty); */ @@ -783,8 +824,7 @@ public final class SwingTerminal extends LogicalScreen swing.paint(gr); gr.dispose(); swing.getBufferStrategy().show(); - // sync() doesn't seem to help the tearing for me. - // Toolkit.getDefaultToolkit().sync(); + Toolkit.getDefaultToolkit().sync(); return; } else if (((swing.getFrame() != null) && (swing.getBufferStrategy() == null)) @@ -796,19 +836,7 @@ public final class SwingTerminal extends LogicalScreen return; } - // Do nothing if nothing happened. - if (!dirty) { - return; - } - if ((swing.getFrame() != null) && (swing.getBufferStrategy() != null)) { - // See if it is time to flip the blink time. - long nowTime = (new Date()).getTime(); - if (nowTime > blinkMillis + lastBlinkTime) { - lastBlinkTime = nowTime; - cursorBlinkVisible = !cursorBlinkVisible; - } - Graphics gr = swing.getBufferStrategy().getDrawGraphics(); synchronized (this) { @@ -836,8 +864,7 @@ public final class SwingTerminal extends LogicalScreen gr.dispose(); swing.getBufferStrategy().show(); - // sync() doesn't seem to help the tearing for me. - // Toolkit.getDefaultToolkit().sync(); + Toolkit.getDefaultToolkit().sync(); return; } @@ -904,48 +931,13 @@ public final class SwingTerminal extends LogicalScreen swing.paint(gr); gr.dispose(); swing.getBufferStrategy().show(); - // sync() doesn't seem to help the tearing for me. - // Toolkit.getDefaultToolkit().sync(); + Toolkit.getDefaultToolkit().sync(); } else { // Repaint on the Swing thread. swing.repaint(xMin, yMin, xMax - xMin, yMax - yMin); } } - /** - * Put the cursor at (x,y). - * - * @param visible if true, the cursor should be visible - * @param x column coordinate to put the cursor on - * @param y row coordinate to put the cursor on - */ - @Override - public void putCursor(final boolean visible, final int x, final int y) { - - if ((visible == cursorVisible) && ((x == cursorX) && (y == cursorY))) { - // See if it is time to flip the blink time. - long nowTime = (new Date()).getTime(); - if (nowTime < blinkMillis + lastBlinkTime) { - // Nothing has changed, so don't do anything. - return; - } - } - - if (cursorVisible - && (cursorY <= height - 1) - && (cursorX <= width - 1) - ) { - // Make the current cursor position dirty - if (physical[cursorX][cursorY].getChar() == 'Q') { - physical[cursorX][cursorY].setChar('X'); - } else { - physical[cursorX][cursorY].setChar('Q'); - } - } - - super.putCursor(visible, x, y); - } - /** * Convert pixel column position to text cell column position. * @@ -1251,6 +1243,9 @@ public final class SwingTerminal extends LogicalScreen component.setLayout(new BorderLayout()); component.add(newComponent); + // Allow key events to be received + component.setFocusable(true); + // Get the Swing component SwingTerminal.this.swing = new SwingComponent(component); @@ -1494,8 +1489,7 @@ public final class SwingTerminal extends LogicalScreen alt, ctrl, shift); break; case KeyEvent.VK_BACK_SPACE: - // Special case: return it as kbBackspace (Ctrl-H) - keypress = new TKeypress(false, 0, 'H', false, true, false); + keypress = kbBackspace; break; default: // Unsupported, ignore @@ -1506,7 +1500,15 @@ public final class SwingTerminal extends LogicalScreen if (keypress == null) { switch (ch) { case 0x08: - keypress = kbBackspace; + // Disambiguate ^H from Backspace. + if (KeyEvent.getKeyText(key.getKeyCode()).equals("H")) { + // This is ^H. + keypress = kbBackspace; + } else { + // We are emulating Xterm here, where the backspace key + // on the keyboard returns ^?. + keypress = kbBackspaceDel; + } break; case 0x0A: keypress = kbEnter; @@ -1539,6 +1541,7 @@ public final class SwingTerminal extends LogicalScreen // Save it and we are done. synchronized (eventQueue) { eventQueue.add(new TKeypressEvent(keypress)); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1577,6 +1580,7 @@ public final class SwingTerminal extends LogicalScreen // Drop a cmAbort and walk away synchronized (eventQueue) { eventQueue.add(new TCommandEvent(cmAbort)); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1667,6 +1671,7 @@ public final class SwingTerminal extends LogicalScreen TResizeEvent windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN, sessionInfo.getWindowWidth(), sessionInfo.getWindowHeight()); eventQueue.add(windowResize); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1705,6 +1710,7 @@ public final class SwingTerminal extends LogicalScreen synchronized (eventQueue) { eventQueue.add(mouseEvent); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1733,6 +1739,7 @@ public final class SwingTerminal extends LogicalScreen synchronized (eventQueue) { eventQueue.add(mouseEvent); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1798,6 +1805,7 @@ public final class SwingTerminal extends LogicalScreen synchronized (eventQueue) { eventQueue.add(mouseEvent); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1845,6 +1853,7 @@ public final class SwingTerminal extends LogicalScreen synchronized (eventQueue) { eventQueue.add(mouseEvent); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) { @@ -1891,6 +1900,7 @@ public final class SwingTerminal extends LogicalScreen synchronized (eventQueue) { eventQueue.add(mouseEvent); + resetBlinkTimer(); } if (listener != null) { synchronized (listener) {