X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fbackend%2FECMA48Terminal.java;h=ae356107ee9c05f3d049f8bbb8b969a1aea50135;hb=eb29bbb5ec70c43895dd0f053630c7e3cd402cba;hp=13704151df3037585b4d4d0f442593444a880834;hpb=42873e30bf487bc0b695d60652dba44f82185dbb;p=nikiroo-utils.git diff --git a/src/jexer/backend/ECMA48Terminal.java b/src/jexer/backend/ECMA48Terminal.java index 1370415..ae35610 100644 --- a/src/jexer/backend/ECMA48Terminal.java +++ b/src/jexer/backend/ECMA48Terminal.java @@ -40,7 +40,6 @@ import java.io.PrintWriter; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.LinkedList; @@ -195,6 +194,16 @@ public final class ECMA48Terminal extends LogicalScreen */ private Object listener; + /** + * Set listener to a different Object. + * + * @param listener the new listening object that run() wakes up on new + * input + */ + public void setListener(final Object listener) { + this.listener = listener; + } + /** * Get the output writer. * @@ -281,6 +290,37 @@ public final class ECMA48Terminal extends LogicalScreen } } + /** + * Constructor sets up state for getEvent(). + * + * @param listener the object this backend needs to wake up when new + * input comes in + * @param input an InputStream connected to the remote user, or null for + * System.in. If System.in is used, then on non-Windows systems it will + * be put in raw mode; shutdown() will (blindly!) put System.in in cooked + * mode. input is always converted to a Reader with UTF-8 encoding. + * @param output an OutputStream connected to the remote user, or null + * for System.out. output is always converted to a Writer with UTF-8 + * encoding. + * @param windowWidth the number of text columns to start with + * @param windowHeight the number of text rows to start with + * @throws UnsupportedEncodingException if an exception is thrown when + * creating the InputStreamReader + */ + public ECMA48Terminal(final Object listener, final InputStream input, + final OutputStream output, final int windowWidth, + final int windowHeight) throws UnsupportedEncodingException { + + this(listener, input, output); + + // Send dtterm/xterm sequences, which will probably not work because + // allowWindowOps is defaulted to false. + String resizeString = String.format("\033[8;%d;%dt", windowHeight, + windowWidth); + this.output.write(resizeString); + this.output.flush(); + } + /** * Constructor sets up state for getEvent(). * @@ -342,6 +382,11 @@ public final class ECMA48Terminal extends LogicalScreen this.output.printf("%s%s", mouse(true), xtermMetaSendsEscape(true)); this.output.flush(); + // Query the screen size + sessionInfo.queryWindowSize(); + setDimensions(sessionInfo.getWindowWidth(), + sessionInfo.getWindowHeight()); + // Hang onto the window size windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN, sessionInfo.getWindowWidth(), sessionInfo.getWindowHeight()); @@ -350,6 +395,8 @@ public final class ECMA48Terminal extends LogicalScreen if (System.getProperty("jexer.ECMA48.rgbColor") != null) { if (System.getProperty("jexer.ECMA48.rgbColor").equals("true")) { doRgbColor = true; + } else { + doRgbColor = false; } } @@ -358,10 +405,6 @@ public final class ECMA48Terminal extends LogicalScreen readerThread = new Thread(this); readerThread.start(); - // Query the screen size - setDimensions(sessionInfo.getWindowWidth(), - sessionInfo.getWindowHeight()); - // Clear the screen this.output.write(clearAll()); this.output.flush(); @@ -429,6 +472,11 @@ public final class ECMA48Terminal extends LogicalScreen this.output.printf("%s%s", mouse(true), xtermMetaSendsEscape(true)); this.output.flush(); + // Query the screen size + sessionInfo.queryWindowSize(); + setDimensions(sessionInfo.getWindowWidth(), + sessionInfo.getWindowHeight()); + // Hang onto the window size windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN, sessionInfo.getWindowWidth(), sessionInfo.getWindowHeight()); @@ -437,6 +485,8 @@ public final class ECMA48Terminal extends LogicalScreen if (System.getProperty("jexer.ECMA48.rgbColor") != null) { if (System.getProperty("jexer.ECMA48.rgbColor").equals("true")) { doRgbColor = true; + } else { + doRgbColor = false; } } @@ -445,10 +495,6 @@ public final class ECMA48Terminal extends LogicalScreen readerThread = new Thread(this); readerThread.start(); - // Query the screen size - setDimensions(sessionInfo.getWindowWidth(), - sessionInfo.getWindowHeight()); - // Clear the screen this.output.write(clearAll()); this.output.flush(); @@ -696,11 +742,6 @@ public final class ECMA48Terminal extends LogicalScreen * physical screen */ private String flushString() { - if (!dirty) { - assert (!reallyCleared); - return ""; - } - CellAttributes attr = null; StringBuilder sb = new StringBuilder(); @@ -713,7 +754,6 @@ public final class ECMA48Terminal extends LogicalScreen flushLine(y, sb, attr); } - dirty = false; reallyCleared = false; String result = sb.toString(); @@ -730,6 +770,8 @@ public final class ECMA48Terminal extends LogicalScreen public void flushPhysical() { String result = flushString(); if ((cursorVisible) + && (cursorY >= 0) + && (cursorX >= 0) && (cursorY <= height - 1) && (cursorX <= width - 1) ) { @@ -1088,29 +1130,38 @@ public final class ECMA48Terminal extends LogicalScreen * @param queue list to append new events to */ private void getIdleEvents(final List queue) { - Date now = new Date(); + long nowTime = System.currentTimeMillis(); // Check for new window size - long windowSizeDelay = now.getTime() - windowSizeTime; + long windowSizeDelay = nowTime - windowSizeTime; if (windowSizeDelay > 1000) { sessionInfo.queryWindowSize(); int newWidth = sessionInfo.getWindowWidth(); int newHeight = sessionInfo.getWindowHeight(); + if ((newWidth != windowResize.getWidth()) || (newHeight != windowResize.getHeight()) ) { + + if (debugToStderr) { + System.err.println("Screen size changed, old size " + + windowResize); + System.err.println(" new size " + + newWidth + " x " + newHeight); + } + TResizeEvent event = new TResizeEvent(TResizeEvent.Type.SCREEN, newWidth, newHeight); windowResize = new TResizeEvent(TResizeEvent.Type.SCREEN, newWidth, newHeight); queue.add(event); } - windowSizeTime = now.getTime(); + windowSizeTime = nowTime; } // ESCDELAY type timeout if (state == ParseState.ESCAPE) { - long escDelay = now.getTime() - escapeTime; + long escDelay = nowTime - escapeTime; if (escDelay > 100) { // After 0.1 seconds, assume a true escape character queue.add(controlChar((char)0x1B, false)); @@ -1174,9 +1225,9 @@ public final class ECMA48Terminal extends LogicalScreen private void processChar(final List events, final char ch) { // ESCDELAY type timeout - Date now = new Date(); + long nowTime = System.currentTimeMillis(); if (state == ParseState.ESCAPE) { - long escDelay = now.getTime() - escapeTime; + long escDelay = nowTime - escapeTime; if (escDelay > 250) { // After 0.25 seconds, assume a true escape character events.add(controlChar((char)0x1B, false)); @@ -1196,7 +1247,7 @@ public final class ECMA48Terminal extends LogicalScreen if (ch == 0x1B) { state = ParseState.ESCAPE; - escapeTime = now.getTime(); + escapeTime = nowTime; return; } @@ -1859,14 +1910,27 @@ public final class ECMA48Terminal extends LogicalScreen // We assume that if inputStream has bytes available, then // input won't block on read(). int n = inputStream.available(); + + /* + System.err.printf("inputStream.available(): %d\n", n); + System.err.flush(); + */ + if (n > 0) { if (readBuffer.length < n) { // The buffer wasn't big enough, make it huger readBuffer = new char[readBuffer.length * 2]; } + // System.err.printf("BEFORE read()\n"); System.err.flush(); + int rc = input.read(readBuffer, 0, readBuffer.length); - // System.err.printf("read() %d", rc); System.err.flush(); + + /* + System.err.printf("AFTER read() %d\n", rc); + System.err.flush(); + */ + if (rc == -1) { // This is EOF done = true; @@ -1882,8 +1946,10 @@ public final class ECMA48Terminal extends LogicalScreen synchronized (eventQueue) { eventQueue.addAll(events); } - synchronized (listener) { - listener.notifyAll(); + if (listener != null) { + synchronized (listener) { + listener.notifyAll(); + } } events.clear(); } @@ -1894,14 +1960,16 @@ public final class ECMA48Terminal extends LogicalScreen synchronized (eventQueue) { eventQueue.addAll(events); } - events.clear(); - synchronized (listener) { - listener.notifyAll(); + if (listener != null) { + synchronized (listener) { + listener.notifyAll(); + } } + events.clear(); } - // Wait 10 millis for more data - Thread.sleep(10); + // Wait 20 millis for more data + Thread.sleep(20); } // System.err.println("end while loop"); System.err.flush(); } catch (InterruptedException e) {