#51 complete
[fanfix.git] / src / jexer / tterminal / ECMA48.java
index 93ae3cd91930ca2f12bea2c38024b2c3408a0b33..e3e7c929397a9b417324933a1057b057638ac57f 100644 (file)
@@ -871,10 +871,10 @@ public class ECMA48 implements Runnable {
         case XTERM:
             // "I am a VT220" - 7 bit version
             if (!s8c1t) {
-                return "\033[?62;1;6c";
+                return "\033[?62;1;6;9;4c";
             }
             // "I am a VT220" - 8 bit version
-            return "\u009b?62;1;6c";
+            return "\u009b?62;1;6;9;4c";
         default:
             throw new IllegalArgumentException("Invalid device type: " + type);
         }
@@ -1078,6 +1078,64 @@ public class ECMA48 implements Runnable {
         return display;
     }
 
+    /**
+     * Get the visible display + scrollback buffer, offset by a specified
+     * number of rows from the bottom.
+     *
+     * @param visibleHeight the total height of the display to show
+     * @param scrollBottom the number of rows from the bottom to scroll back
+     * @return a copy of the display + scrollback buffers
+     */
+    public final List<DisplayLine> getVisibleDisplay(final int visibleHeight,
+        final int scrollBottom) {
+
+        assert (visibleHeight >= 0);
+        assert (scrollBottom >= 0);
+
+        int visibleBottom = scrollback.size() + display.size() - scrollBottom;
+
+        List<DisplayLine> preceedingBlankLines = new ArrayList<DisplayLine>();
+        int visibleTop = visibleBottom - visibleHeight;
+        if (visibleTop < 0) {
+            for (int i = visibleTop; i < 0; i++) {
+                preceedingBlankLines.add(getBlankDisplayLine());
+            }
+            visibleTop = 0;
+        }
+        assert (visibleTop >= 0);
+
+        List<DisplayLine> displayLines = new ArrayList<DisplayLine>();
+        displayLines.addAll(scrollback);
+        displayLines.addAll(display);
+
+        List<DisplayLine> visibleLines = new ArrayList<DisplayLine>();
+        visibleLines.addAll(preceedingBlankLines);
+        visibleLines.addAll(displayLines.subList(visibleTop, visibleBottom));
+
+        // Fill in the blank lines on bottom
+        int bottomBlankLines = visibleHeight - visibleLines.size();
+        assert (bottomBlankLines >= 0);
+        for (int i = 0; i < bottomBlankLines; i++) {
+            visibleLines.add(getBlankDisplayLine());
+        }
+
+        return copyBuffer(visibleLines);
+    }
+
+    /**
+     * Copy a display buffer.
+     *
+     * @param buffer the buffer to copy
+     * @return a deep copy of the buffer's data
+     */
+    private List<DisplayLine> copyBuffer(final List<DisplayLine> buffer) {
+        ArrayList<DisplayLine> result = new ArrayList<DisplayLine>(buffer.size());
+        for (DisplayLine line: buffer) {
+            result.add(new DisplayLine(line));
+        }
+        return result;
+    }
+
     /**
      * Get the display width.
      *
@@ -1092,7 +1150,7 @@ public class ECMA48 implements Runnable {
      *
      * @param width the new width
      */
-    public final void setWidth(final int width) {
+    public final synchronized void setWidth(final int width) {
         this.width = width;
         rightMargin = width - 1;
         if (currentState.cursorX >= width) {
@@ -1117,7 +1175,7 @@ public class ECMA48 implements Runnable {
      *
      * @param height the new height
      */
-    public final void setHeight(final int height) {
+    public final synchronized void setHeight(final int height) {
         int delta = height - this.height;
         this.height = height;
         scrollRegionBottom += delta;
@@ -4721,10 +4779,26 @@ public class ECMA48 implements Runnable {
         int i = getCsiParam(0, 0);
 
         if (!xtermPrivateModeFlag) {
-            if (i == 14) {
-                // Report xterm window in pixels as CSI 4 ; height ; width t
+            switch (i) {
+            case 14:
+                // Report xterm text area size in pixels as CSI 4 ; height ;
+                // width t
                 writeRemote(String.format("\033[4;%d;%dt", textHeight * height,
                         textWidth * width));
+                break;
+            case 16:
+                // Report character size in pixels as CSI 6 ; height ; width
+                // t
+                writeRemote(String.format("\033[6;%d;%dt", textHeight,
+                        textWidth));
+                break;
+            case 18:
+                // Report the text are size in characters as CSI 8 ; height ;
+                // width t
+                writeRemote(String.format("\033[8;%d;%dt", height, width));
+                break;
+            default:
+                break;
             }
         }
     }