performance
[fanfix.git] / src / jexer / tterminal / ECMA48.java
index bef9cabad620b705ec0c99e1d31182b5c3fa717a..ce06c36bebfb8fd525b262e3097359695c15dd34 100644 (file)
@@ -1025,11 +1025,6 @@ public class ECMA48 implements Runnable {
         // the input streams.
         if (stopReaderThread == false) {
             stopReaderThread = true;
-            try {
-                readerThread.join(1000);
-            } catch (InterruptedException e) {
-                // SQUASH
-            }
         }
 
         // Now close the output stream.
@@ -1686,35 +1681,45 @@ public class ECMA48 implements Runnable {
         if (mouseEncoding == MouseEncoding.SGR) {
             sb.append((char) 0x1B);
             sb.append("[<");
+            int buttons = 0;
 
             if (mouse.isMouse1()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append("32;");
+                    buttons = 32;
                 } else {
-                    sb.append("0;");
+                    buttons = 0;
                 }
             } else if (mouse.isMouse2()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append("33;");
+                    buttons = 33;
                 } else {
-                    sb.append("1;");
+                    buttons = 1;
                 }
             } else if (mouse.isMouse3()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append("34;");
+                    buttons = 34;
                 } else {
-                    sb.append("2;");
+                    buttons = 2;
                 }
             } else if (mouse.isMouseWheelUp()) {
-                sb.append("64;");
+                buttons = 64;
             } else if (mouse.isMouseWheelDown()) {
-                sb.append("65;");
+                buttons = 65;
             } else {
                 // This is motion with no buttons down.
-                sb.append("35;");
+                buttons = 35;
+            }
+            if (mouse.isAlt()) {
+                buttons |= 0x08;
+            }
+            if (mouse.isCtrl()) {
+                buttons |= 0x10;
+            }
+            if (mouse.isShift()) {
+                buttons |= 0x04;
             }
 
-            sb.append(String.format("%d;%d", mouse.getX() + 1,
+            sb.append(String.format("%d;%d;%d", buttons, mouse.getX() + 1,
                     mouse.getY() + 1));
 
             if (mouse.getType() == TMouseEvent.Type.MOUSE_UP) {
@@ -1728,35 +1733,46 @@ public class ECMA48 implements Runnable {
             sb.append((char) 0x1B);
             sb.append('[');
             sb.append('M');
+            int buttons = 0;
             if (mouse.getType() == TMouseEvent.Type.MOUSE_UP) {
-                sb.append((char) (0x03 + 32));
+                buttons = 0x03 + 32;
             } else if (mouse.isMouse1()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append((char) (0x00 + 32 + 32));
+                    buttons = 0x00 + 32 + 32;
                 } else {
-                    sb.append((char) (0x00 + 32));
+                    buttons = 0x00 + 32;
                 }
             } else if (mouse.isMouse2()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append((char) (0x01 + 32 + 32));
+                    buttons = 0x01 + 32 + 32;
                 } else {
-                    sb.append((char) (0x01 + 32));
+                    buttons = 0x01 + 32;
                 }
             } else if (mouse.isMouse3()) {
                 if (mouse.getType() == TMouseEvent.Type.MOUSE_MOTION) {
-                    sb.append((char) (0x02 + 32 + 32));
+                    buttons = 0x02 + 32 + 32;
                 } else {
-                    sb.append((char) (0x02 + 32));
+                    buttons = 0x02 + 32;
                 }
             } else if (mouse.isMouseWheelUp()) {
-                sb.append((char) (0x04 + 64));
+                buttons = 0x04 + 64;
             } else if (mouse.isMouseWheelDown()) {
-                sb.append((char) (0x05 + 64));
+                buttons = 0x05 + 64;
             } else {
                 // This is motion with no buttons down.
-                sb.append((char) (0x03 + 32));
+                buttons = 0x03 + 32;
+            }
+            if (mouse.isAlt()) {
+                buttons |= 0x08;
+            }
+            if (mouse.isCtrl()) {
+                buttons |= 0x10;
+            }
+            if (mouse.isShift()) {
+                buttons |= 0x04;
             }
 
+            sb.append((char) (buttons & 0xFF));
             sb.append((char) (mouse.getX() + 33));
             sb.append((char) (mouse.getY() + 33));
         }
@@ -3178,10 +3194,10 @@ public class ECMA48 implements Runnable {
                     if (decPrivateModeFlag == true) {
                         if (value == true) {
                             // Enable sixel scrolling (default).
-                            // TODO
+                            // Not supported
                         } else {
                             // Disable sixel scrolling.
-                            // TODO
+                            // Not supported
                         }
                     }
                 }
@@ -4016,7 +4032,7 @@ public class ECMA48 implements Runnable {
 
                 case 8:
                     // Invisible
-                    // TODO
+                    // Not supported
                     break;
 
                 case 90:
@@ -4757,13 +4773,22 @@ public class ECMA48 implements Runnable {
     private void oscPut(final char xtermChar) {
         // System.err.println("oscPut: " + xtermChar);
 
+        boolean oscEnd = false;
+
+        if (xtermChar == 0x07) {
+            oscEnd = true;
+        }
+        if ((xtermChar == '\\')
+            && (collectBuffer.charAt(collectBuffer.length() - 1) == '\033')
+        ) {
+            oscEnd = true;
+        }
+
         // Collect first
         collectBuffer.append(xtermChar);
 
         // Xterm cases...
-        if ((xtermChar == 0x07)
-            || (collectBuffer.toString().endsWith("\033\\"))
-        ) {
+        if (oscEnd) {
             String args = null;
             if (xtermChar == 0x07) {
                 args = collectBuffer.substring(0, collectBuffer.length() - 1);
@@ -4846,11 +4871,19 @@ public class ECMA48 implements Runnable {
     private void pmPut(final char pmChar) {
         // System.err.println("pmPut: " + pmChar);
 
+        boolean pmEnd = false;
+
+        if ((pmChar == '\\')
+            && (collectBuffer.charAt(collectBuffer.length() - 1) == '\033')
+        ) {
+            pmEnd = true;
+        }
+
         // Collect first
         collectBuffer.append(pmChar);
 
         // Xterm cases...
-        if (collectBuffer.toString().endsWith("\033\\")) {
+        if (pmEnd) {
             String arg = null;
             arg = collectBuffer.substring(0, collectBuffer.length() - 2);
 
@@ -7111,8 +7144,7 @@ public class ECMA48 implements Runnable {
             return;
         }
 
-        java.util.Base64.Decoder base64 = java.util.Base64.getDecoder();
-        byte [] bytes = base64.decode(data);
+        byte [] bytes = StringUtils.fromBase64(data.getBytes());
         if (bytes.length != (imageWidth * imageHeight * 3)) {
             return;
         }
@@ -7158,8 +7190,7 @@ public class ECMA48 implements Runnable {
         boolean scroll = false;
         BufferedImage image = null;
         try {
-            java.util.Base64.Decoder base64 = java.util.Base64.getDecoder();
-            byte [] bytes = base64.decode(data);
+            byte [] bytes = StringUtils.fromBase64(data.getBytes());
 
             switch (type) {
             case 1:
@@ -7287,9 +7318,10 @@ public class ECMA48 implements Runnable {
             for (int x = 0; x < cellColumns; x++) {
                 assert (currentState.cursorX <= rightMargin);
 
-                // TODO: Render text of current cell first, then image over
-                // it (accounting for blank pixels).  For now, just copy the
-                // cell.
+                // A real sixel terminal would render the text of the current
+                // cell first, then image over it (accounting for blank
+                // pixels).  We do not support that.  A cell is either text,
+                // or image, but not a mix of image-over-text.
                 DisplayLine line = display.get(currentState.cursorY);
                 line.replace(currentState.cursorX, cells[x][y]);