#35 CJK WIP
[fanfix.git] / src / jexer / backend / ECMA48Terminal.java
index 92758ee6a65e096072af59d53c5bca973f8469c0..e22e4fe91e277e1afd5abbeb0d6e83b917d4743f 100644 (file)
@@ -44,16 +44,17 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
-import java.util.LinkedList;
 
 import jexer.TImage;
 import jexer.bits.Cell;
 import jexer.bits.CellAttributes;
 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 static jexer.TCommand.*;
 import static jexer.TKeypress.*;
 
 /**
@@ -1107,7 +1108,7 @@ public class ECMA48Terminal extends LogicalScreen
         reloadOptions();
 
         // Spin up the input reader
-        eventQueue = new LinkedList<TInputEvent>();
+        eventQueue = new ArrayList<TInputEvent>();
         readerThread = new Thread(this);
         readerThread.start();
 
@@ -1193,7 +1194,7 @@ public class ECMA48Terminal extends LogicalScreen
         reloadOptions();
 
         // Spin up the input reader
-        eventQueue = new LinkedList<TInputEvent>();
+        eventQueue = new ArrayList<TInputEvent>();
         readerThread = new Thread(this);
         readerThread.start();
 
@@ -1390,7 +1391,7 @@ public class ECMA48Terminal extends LogicalScreen
         // available() will often return > 1, so we need to read in chunks to
         // stay caught up.
         char [] readBuffer = new char[128];
-        List<TInputEvent> events = new LinkedList<TInputEvent>();
+        List<TInputEvent> events = new ArrayList<TInputEvent>();
 
         while (!done && !stopReaderThread) {
             try {
@@ -1472,10 +1473,17 @@ public class ECMA48Terminal extends LogicalScreen
             }
         } // while ((done == false) && (stopReaderThread == false))
 
-        // TODO: pass an event up to TApplication to tell it this Backend is
-        // done.
+        // Pass an event up to TApplication to tell it this Backend is done.
+        synchronized (eventQueue) {
+            eventQueue.add(new TCommandEvent(cmBackendDisconnect));
+        }
+        if (listener != null) {
+            synchronized (listener) {
+                listener.notifyAll();
+            }
+        }
 
-        System.err.println("*** run() exiting..."); System.err.flush();
+        // System.err.println("*** run() exiting..."); System.err.flush();
     }
 
     // ------------------------------------------------------------------------
@@ -2843,7 +2851,9 @@ public class ECMA48Terminal extends LogicalScreen
 
         int [] rgbArray;
         for (int i = 0; i < cells.size() - 1; i++) {
-            if (cells.get(i).isInvertedImage()) {
+            if (false && cells.get(i).isInvertedImage()) {
+                // I used to put an all-white cell over the cursor, don't do
+                // that anymore.
                 rgbArray = new int[imageWidth * imageHeight];
                 for (int j = 0; j < rgbArray.length; j++) {
                     rgbArray[j] = 0xFFFFFF;
@@ -2875,7 +2885,9 @@ public class ECMA48Terminal extends LogicalScreen
             }
         }
         totalWidth -= ((cells.size() - 1) * imageWidth);
-        if (cells.get(cells.size() - 1).isInvertedImage()) {
+        if (false && cells.get(cells.size() - 1).isInvertedImage()) {
+            // I used to put an all-white cell over the cursor, don't do that
+            // anymore.
             rgbArray = new int[totalWidth * imageHeight];
             for (int j = 0; j < rgbArray.length; j++) {
                 rgbArray[j] = 0xFFFFFF;
@@ -2950,6 +2962,8 @@ public class ECMA48Terminal extends LogicalScreen
                 // colored pixels, and select the color.
                 sb.append(String.format("$#%d", i));
 
+                int oldData = -1;
+                int oldDataCount = 0;
                 for (int imageX = 0; imageX < image.getWidth(); imageX++) {
 
                     // Add up all the pixels that match this color.
@@ -2982,10 +2996,32 @@ public class ECMA48Terminal extends LogicalScreen
                         }
                     }
                     assert (data >= 0);
-                    assert (data < 127);
+                    assert (data < 64);
                     data += 63;
-                    sb.append((char) data);
+
+                    if (data == oldData) {
+                        oldDataCount++;
+                    } else {
+                        if (oldDataCount == 1) {
+                            sb.append((char) oldData);
+                        } else if (oldDataCount > 1) {
+                            sb.append(String.format("!%d", oldDataCount));
+                            sb.append((char) oldData);
+                        }
+                        oldDataCount = 1;
+                        oldData = data;
+                    }
+
                 } // for (int imageX = 0; imageX < image.getWidth(); imageX++)
+
+                // Emit the last sequence.
+                if (oldDataCount == 1) {
+                    sb.append((char) oldData);
+                } else if (oldDataCount > 1) {
+                    sb.append(String.format("!%d", oldDataCount));
+                    sb.append((char) oldData);
+                }
+
             } // for (int i = 0; i < MAX_COLOR_REGISTERS; i++)
 
             // Advance to the next scan line.
@@ -3004,6 +3040,15 @@ public class ECMA48Terminal extends LogicalScreen
         return (startSixel(x, y) + sb.toString() + endSixel());
     }
 
+    /**
+     * Get the sixel support flag.
+     *
+     * @return true if this terminal is emitting sixel
+     */
+    public boolean hasSixel() {
+        return sixel;
+    }
+
     // ------------------------------------------------------------------------
     // End sixel output support -----------------------------------------------
     // ------------------------------------------------------------------------