Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Leherbauer2015-01-27 15:09:11 +0000
committerAnton Leherbauer2015-01-28 08:50:25 +0000
commit53c5808e0091ec7cdd04db2f90bb9b4b2e2eda7c (patch)
treef5c5e0ee18cff44b265922552e368f81639a3065
parent7ff9715a558f381fa72c4233966bb4b0a91ef7a5 (diff)
downloadorg.eclipse.tm-53c5808e0091ec7cdd04db2f90bb9b4b2e2eda7c.tar.gz
org.eclipse.tm-53c5808e0091ec7cdd04db2f90bb9b4b2e2eda7c.tar.xz
org.eclipse.tm-53c5808e0091ec7cdd04db2f90bb9b4b2e2eda7c.zip
Bug 458402 - [terminal] Add support for scroll up/down and scroll region
Change-Id: If3c955663f664d34d01ada0763de2eec7b36b7d4 Signed-off-by: Anton Leherbauer <anton.leherbauer@windriver.com>
-rw-r--r--terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java71
-rw-r--r--terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java24
-rw-r--r--terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java16
-rw-r--r--terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java97
-rw-r--r--terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java61
5 files changed, 257 insertions, 12 deletions
diff --git a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
index 9ed477ffa..0a65fd7ba 100644
--- a/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
+++ b/terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackendTest.java
@@ -10,6 +10,7 @@
* Martin Oberhuber (Wind River) - [168197] Fix Terminal for CDC-1.1/Foundation-1.1
* Anton Leherbauer (Wind River) - [453393] Add support for copying wrapped lines without line break
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
+ * Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
*******************************************************************************/
package org.eclipse.tm.internal.terminal.emulator;
@@ -1307,4 +1308,74 @@ public class VT100EmulatorBackendTest extends TestCase {
assertEquals("abc123", new String(term.getChars(0)));
}
+ public void testScrollRegion() {
+ ITerminalTextData term=makeITerminalTextData();
+ IVT100EmulatorBackend vt100=makeBakend(term);
+ term.setMaxHeight(10);
+ vt100.setDimensions(8, 6);
+ vt100.appendString("123");
+ vt100.setCursorColumn(0);
+ vt100.processNewline();
+ vt100.appendString("456");
+ vt100.setCursorColumn(0);
+ vt100.processNewline();
+ vt100.appendString("789");
+ vt100.setCursorColumn(0);
+ vt100.processNewline();
+ vt100.appendString("abc");
+ vt100.setCursorColumn(0);
+ vt100.processNewline();
+ vt100.appendString("def");
+ vt100.setCursorColumn(0);
+ vt100.processNewline();
+ vt100.appendString("ghi");
+
+ // test scroll within region
+ vt100.setCursorLine(1);
+ vt100.setScrollRegion(1, 4);
+ vt100.scrollUp(1);
+ assertEquals("123", new String(term.getChars(0)));
+ assertEquals("789", new String(term.getChars(1)));
+ assertEquals("abc", new String(term.getChars(2)));
+ assertEquals("def", new String(term.getChars(3)));
+ assertNull(term.getChars(4));
+ assertEquals("ghi", new String(term.getChars(5)));
+ vt100.scrollDown(1);
+ assertEquals("123", new String(term.getChars(0)));
+ assertNull(term.getChars(1));
+ assertEquals("789", new String(term.getChars(2)));
+ assertEquals("abc", new String(term.getChars(3)));
+ assertEquals("def", new String(term.getChars(4)));
+ assertEquals("ghi", new String(term.getChars(5)));
+
+ // test scroll without region
+ vt100.setScrollRegion(-1, -1);
+ vt100.scrollDown(1);
+ assertNull(term.getChars(0));
+ assertEquals("123", new String(term.getChars(1)));
+ assertNull(term.getChars(2));
+ assertEquals("789", new String(term.getChars(3)));
+ assertEquals("abc", new String(term.getChars(4)));
+ assertEquals("def", new String(term.getChars(5)));
+ assertEquals("ghi", new String(term.getChars(6)));
+ vt100.scrollUp(1);
+ assertEquals("123", new String(term.getChars(0)));
+ assertNull(term.getChars(1));
+ assertEquals("789", new String(term.getChars(2)));
+ assertEquals("abc", new String(term.getChars(3)));
+ assertEquals("def", new String(term.getChars(4)));
+ assertEquals("ghi", new String(term.getChars(5)));
+
+ // test scroll by newline
+ vt100.setScrollRegion(1, 4);
+ vt100.setCursorLine(4);
+ vt100.processNewline();
+ assertEquals("123", new String(term.getChars(0)));
+ assertEquals("789", new String(term.getChars(1)));
+ assertEquals("abc", new String(term.getChars(2)));
+ assertEquals("def", new String(term.getChars(3)));
+ assertNull(term.getChars(4));
+ assertEquals("ghi", new String(term.getChars(5)));
+ }
+
}
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java
index ef38f82e0..aff90891b 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/IVT100EmulatorBackend.java
@@ -9,13 +9,13 @@
* Michael Scharf (Wind River) - initial API and implementation
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
+ * Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
*******************************************************************************/
package org.eclipse.tm.internal.terminal.emulator;
import org.eclipse.tm.terminal.model.Style;
/**
- * @author toni
*
*/
public interface IVT100EmulatorBackend {
@@ -197,4 +197,26 @@ public interface IVT100EmulatorBackend {
* @param enable whether to enable insert mode
*/
void setInsertMode(boolean enable);
+
+ /**
+ * Set scrolling region. Negative values reset the scroll region.
+ *
+ * @param top top line of scroll region
+ * @param bottom bottom line of scroll region
+ */
+ void setScrollRegion(int top, int bottom);
+
+ /**
+ * Scroll text upwards.
+ *
+ * @param lines number of lines to scroll
+ */
+ void scrollUp(int lines);
+
+ /**
+ * Scroll text downwards.
+ *
+ * @param lines number of lines to scroll
+ */
+ void scrollDown(int lines);
}
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java
index c108986e1..78531437e 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100BackendTraceDecorator.java
@@ -9,6 +9,7 @@
* Michael Scharf (Wind River) - initial API and implementation
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
+ * Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
*******************************************************************************/
package org.eclipse.tm.internal.terminal.emulator;
@@ -157,4 +158,19 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend {
fBackend.setInsertMode(enable);
}
+ public void setScrollRegion(int top, int bottom) {
+ fWriter.println("setScrollRegion("+top+','+bottom+")"); //$NON-NLS-1$ //$NON-NLS-2$
+ fBackend.setScrollRegion(top, bottom);
+ }
+
+ public void scrollUp(int lines) {
+ fWriter.println("scrollUp("+lines+")"); //$NON-NLS-1$ //$NON-NLS-2$
+ fBackend.scrollUp(lines);
+ }
+
+ public void scrollDown(int lines) {
+ fWriter.println("scrollDown("+lines+")"); //$NON-NLS-1$ //$NON-NLS-2$
+ fBackend.scrollDown(lines);
+ }
+
}
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java
index cc9e6cfa4..eba03390c 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java
@@ -23,6 +23,7 @@
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
* Anton Leherbauer (Wind River) - [458398] Add support for normal/application cursor keys mode
+ * Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
*******************************************************************************/
package org.eclipse.tm.internal.terminal.emulator;
@@ -77,6 +78,12 @@ public class VT100Emulator implements ControlListener {
*/
private static final int ANSISTATE_EXPECTING_DEC_PRIVATE_COMMAND = 4;
+ /**
+ * This is a character processing state: We've seen one of ()*+-./ after an escape
+ * character. Expecting a character set designation character.
+ */
+ private static final int ANSISTATE_EXPECTING_CHARSET_DESIGNATION = 5;
+
/**
* This field holds the current state of the Finite TerminalState Automaton (FSA)
@@ -341,6 +348,16 @@ public class VT100Emulator implements ControlListener {
ansiOsCommand.delete(0, ansiOsCommand.length());
break;
+ case ')':
+ case '(':
+ case '*':
+ case '+':
+ case '-':
+ case '.':
+ case '/':
+ ansiState = ANSISTATE_EXPECTING_CHARSET_DESIGNATION;
+ break;
+
case '7':
// Save cursor position and character attributes
@@ -413,6 +430,12 @@ public class VT100Emulator implements ControlListener {
}
break;
+ case ANSISTATE_EXPECTING_CHARSET_DESIGNATION:
+ if (character != '%')
+ ansiState = ANSISTATE_INITIAL;
+ // Character set designation commands are ignored
+ break;
+
default:
// This should never happen! If it does happen, it means there is a
// bug in the FSA. For robustness, we return to the initial
@@ -483,6 +506,11 @@ public class VT100Emulator implements ControlListener {
processAnsiCommand_D();
break;
+ case 'd':
+ // Line Position Absolute [row] (default = [1,column]) (VPA).
+ processAnsiCommand_d();
+ break;
+
case 'E':
// Move cursor to first column of Nth next line (default 1).
processAnsiCommand_E();
@@ -548,16 +576,19 @@ public class VT100Emulator implements ControlListener {
processAnsiCommand_P();
break;
+ case 'r':
+ // Set Scrolling Region.
+ processAnsiCommand_r();
+ break;
+
case 'S':
// Scroll up.
- // Emacs, vi, and GNU readline don't seem to use this command, so we ignore
- // it for now.
+ processAnsiCommand_S();
break;
case 'T':
// Scroll down.
- // Emacs, vi, and GNU readline don't seem to use this command, so we ignore
- // it for now.
+ processAnsiCommand_T();
break;
case 'X':
@@ -647,6 +678,14 @@ public class VT100Emulator implements ControlListener {
}
/**
+ * This method moves the cursor to a specific row.
+ */
+ private void processAnsiCommand_d() {
+ // Line Position Absolute [row] (default = [1,column]) (VPA).
+ text.setCursorLine(getAnsiParameter(0) - 1);
+ }
+
+ /**
* This method moves the cursor to the first column of the Nth next line,
* where N is specified by the ANSI parameter (default 1).
*/
@@ -967,17 +1006,63 @@ public class VT100Emulator implements ControlListener {
text.deleteCharacters(getAnsiParameter(0));
}
+ /**
+ * Set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM).
+ */
+ private void processAnsiCommand_r() {
+ int top = 0;
+ int bottom = 0;
+ if (ansiParameters[0].length() > 0 && ansiParameters[1].length() > 0) {
+ top = getAnsiParameter(0);
+ bottom = getAnsiParameter(1);
+ }
+ text.setScrollRegion(top-1, bottom-1);
+ }
+
+ /**
+ * Scroll up n lines (default = 1 line).
+ */
+ private void processAnsiCommand_S() {
+ text.scrollUp(getAnsiParameter(0));
+ }
+
+ /**
+ * Scroll down n lines (default = 1 line).
+ */
+ private void processAnsiCommand_T() {
+ text.scrollDown(getAnsiParameter(0));
+ }
+
private void processDecPrivateCommand_h() {
- if (getAnsiParameter(0) == 1) {
+ int param = getAnsiParameter(0);
+ switch (param) {
+ case 1:
// Enable Application Cursor Keys (DECCKM)
terminal.enableApplicationCursorKeys(true);
+ break;
+ case 47:
+ // Use Alternate Screen Buffer (ignored).
+ break;
+ default:
+ Logger.log("Unsupported command parameter: CSI ?" + param + 'h'); //$NON-NLS-1$
+ break;
}
}
private void processDecPrivateCommand_l() {
- if (getAnsiParameter(0) == 1) {
+ int param = getAnsiParameter(0);
+ switch (param) {
+ case 1:
// Enable Normal Cursor Keys (DECCKM)
terminal.enableApplicationCursorKeys(false);
+ break;
+ case 47:
+ // Use Normal Screen Buffer (ignored, but reset scroll region).
+ text.setScrollRegion(-1, -1);
+ break;
+ default:
+ Logger.log("Unsupported command parameter: CSI ?" + param + 'l'); //$NON-NLS-1$
+ break;
}
}
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java
index 2387d20f6..36140d600 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorBackend.java
@@ -10,6 +10,7 @@
* Anton Leherbauer (Wind River) - [206329] Changing terminal size right after connect does not scroll properly
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
+ * Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
*******************************************************************************/
package org.eclipse.tm.internal.terminal.emulator;
@@ -21,6 +22,28 @@ import org.eclipse.tm.terminal.model.Style;
*/
public class VT100EmulatorBackend implements IVT100EmulatorBackend {
+ private static class ScrollRegion {
+ static final ScrollRegion FULL_WINDOW = new ScrollRegion(0, Integer.MAX_VALUE-1);
+ private final int fTop;
+ private final int fBottom;
+ ScrollRegion(int top, int bottom) {
+ fTop = top;
+ fBottom = bottom;
+ }
+ boolean contains(int line) {
+ return line >= fTop && line <= fBottom;
+ }
+ int getTopLine() {
+ return fTop;
+ }
+ int getBottomLine() {
+ return fBottom;
+ }
+ int getHeight() {
+ return fBottom - fTop + 1;
+ }
+ }
+
/**
* This field holds the number of the column in which the cursor is
* logically positioned. The leftmost column on the screen is column 0, and
@@ -62,6 +85,8 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
int fColumns;
final private ITerminalTextData fTerminal;
private boolean fVT100LineWrapping;
+ private ScrollRegion fScrollRegion = ScrollRegion.FULL_WINDOW;
+
public VT100EmulatorBackend(ITerminalTextData terminal) {
fTerminal=terminal;
}
@@ -210,7 +235,7 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
return;
assert n>0;
int line=toAbsoluteLine(fCursorLine);
- int nLines=fTerminal.getHeight()-line;
+ int nLines=Math.min(fTerminal.getHeight()-line, fScrollRegion.getBottomLine()-fCursorLine+1);
fTerminal.scroll(line, nLines, n);
}
}
@@ -240,13 +265,12 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
return;
assert n>0;
int line=toAbsoluteLine(fCursorLine);
- int nLines=fTerminal.getHeight()-line;
+ int nLines=Math.min(fTerminal.getHeight()-line, fScrollRegion.getBottomLine()-fCursorLine+1);
fTerminal.scroll(line, nLines, -n);
}
}
private boolean isCusorInScrollingRegion() {
- // TODO Auto-generated method stub
- return true;
+ return fScrollRegion.contains(fCursorLine);
}
/* (non-Javadoc)
@@ -333,7 +357,9 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
* MUST be called from a synchronized block!
*/
private void doNewline() {
- if(fCursorLine+1>=fLines) {
+ if (fCursorLine == fScrollRegion.getBottomLine())
+ scrollUp(1);
+ else if (fCursorLine+1>=fLines) {
int h=fTerminal.getHeight();
fTerminal.addLine();
if(h!=fTerminal.getHeight())
@@ -440,4 +466,29 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
public void setInsertMode(boolean enable) {
fInsertMode = enable;
}
+
+ public void setScrollRegion(int top, int bottom) {
+ if (top < 0 || bottom < 0)
+ fScrollRegion = ScrollRegion.FULL_WINDOW;
+ else if (top < bottom)
+ fScrollRegion = new ScrollRegion(top, bottom);
+ }
+
+ public void scrollUp(int n) {
+ assert n>0;
+ synchronized (fTerminal) {
+ int line = toAbsoluteLine(fScrollRegion.getTopLine());
+ int nLines = Math.min(fTerminal.getHeight()-line, fScrollRegion.getHeight());
+ fTerminal.scroll(line, nLines, -n);
+ }
+ }
+
+ public void scrollDown(int n) {
+ assert n>0;
+ synchronized (fTerminal) {
+ int line = toAbsoluteLine(fScrollRegion.getTopLine());
+ int nLines = Math.min(fTerminal.getHeight()-line, fScrollRegion.getHeight());
+ fTerminal.scroll(line, nLines, n);
+ }
+ }
}

Back to the top