- public List<TInputEvent> getEvents(char ch, boolean noChar) {
- List<TInputEvent> events = new LinkedList<TInputEvent>();
-
- TKeypressEvent keypress;
- Date now = new Date();
-
- // ESCDELAY type timeout
- if (state == ParseState.ESCAPE) {
- long escDelay = now.getTime() - escapeTime;
- if (escDelay > 250) {
- // After 0.25 seconds, assume a true escape character
- events.add(controlChar((char)0x1B));
- reset();
- }
- }
-
- if (noChar == true) {
- int newWidth = session.getWindowWidth();
- int newHeight = session.getWindowHeight();
- if ((newWidth != windowResize.width) ||
- (newHeight != windowResize.height)) {
- TResizeEvent event = new TResizeEvent(TResizeEvent.Type.Screen,
- newWidth, newHeight);
- windowResize.width = newWidth;
- windowResize.height = newHeight;
- events.add(event);
- }
-
- // Nothing else to do, bail out
- return events;
- }
-
- // System.err.printf("state: %s ch %c\r\n", state, ch);
-
- switch (state) {
- case GROUND:
-
- if (ch == 0x1B) {
- state = ParseState.ESCAPE;
- escapeTime = now.getTime();
- return events;
- }
-
- if (ch <= 0x1F) {
- // Control character
- events.add(controlChar(ch));
- reset();
- return events;
- }
-
- if (ch >= 0x20) {
- // Normal character
- keypress = new TKeypressEvent();
- keypress.key.isKey = false;
- keypress.key.ch = ch;
- events.add(keypress);
- reset();
- return events;
- }
-
- break;
-
- case ESCAPE:
- if (ch <= 0x1F) {
- // ALT-Control character
- keypress = controlChar(ch);
- keypress.key.alt = true;
- events.add(keypress);
- reset();
- return events;
- }
-
- if (ch == 'O') {
- // This will be one of the function keys
- state = ParseState.ESCAPE_INTERMEDIATE;
- return events;
- }
-
- // '[' goes to CSI_ENTRY
- if (ch == '[') {
- state = ParseState.CSI_ENTRY;
- return events;
- }
-
- // Everything else is assumed to be Alt-keystroke
- keypress = new TKeypressEvent();
- keypress.key.isKey = false;
- keypress.key.ch = ch;
- keypress.key.alt = true;
- if ((ch >= 'A') && (ch <= 'Z')) {
- keypress.key.shift = true;
- }
- events.add(keypress);
- reset();
- return events;
-
- case ESCAPE_INTERMEDIATE:
- if ((ch >= 'P') && (ch <= 'S')) {
- // Function key
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- switch (ch) {
- case 'P':
- keypress.key.fnKey = TKeypress.F1;
- break;
- case 'Q':
- keypress.key.fnKey = TKeypress.F2;
- break;
- case 'R':
- keypress.key.fnKey = TKeypress.F3;
- break;
- case 'S':
- keypress.key.fnKey = TKeypress.F4;
- break;
- default:
- break;
- }
- events.add(keypress);
- reset();
- return events;
- }
-
- // Unknown keystroke, ignore
- reset();
- return events;
-
- case CSI_ENTRY:
- // Numbers - parameter values
- if ((ch >= '0') && (ch <= '9')) {
- params.set(paramI, params.get(paramI) + ch);
- state = ParseState.CSI_PARAM;
- return events;
- }
- // Parameter separator
- if (ch == ';') {
- paramI++;
- params.set(paramI, "");
- return events;
- }
-
- if ((ch >= 0x30) && (ch <= 0x7E)) {
- switch (ch) {
- case 'A':
- // Up
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.UP;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'B':
- // Down
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.DOWN;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'C':
- // Right
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.RIGHT;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'D':
- // Left
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.LEFT;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'H':
- // Home
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.HOME;
- events.add(keypress);
- reset();
- return events;
- case 'F':
- // End
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.END;
- events.add(keypress);
- reset();
- return events;
- case 'Z':
- // CBT - Cursor backward X tab stops (default 1)
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.BTAB;
- events.add(keypress);
- reset();
- return events;
- case 'M':
- // Mouse position
- state = ParseState.MOUSE;
- return events;
- default:
- break;
- }
- }
-
- // Unknown keystroke, ignore
- reset();
- return events;
-
- case CSI_PARAM:
- // Numbers - parameter values
- if ((ch >= '0') && (ch <= '9')) {
- params.set(paramI, params.get(paramI) + ch);
- state = ParseState.CSI_PARAM;
- return events;
- }
- // Parameter separator
- if (ch == ';') {
- paramI++;
- params.set(paramI, "");
- return events;
- }
-
- if (ch == '~') {
- events.add(csiFnKey());
- reset();
- return events;
- }
-
- if ((ch >= 0x30) && (ch <= 0x7E)) {
- switch (ch) {
- case 'A':
- // Up
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.UP;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'B':
- // Down
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.DOWN;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'C':
- // Right
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.RIGHT;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- case 'D':
- // Left
- keypress = new TKeypressEvent();
- keypress.key.isKey = true;
- keypress.key.fnKey = TKeypress.LEFT;
- if (params.size() > 1) {
- if (params.get(1).equals("2")) {
- keypress.key.shift = true;
- }
- if (params.get(1).equals("5")) {
- keypress.key.ctrl = true;
- }
- if (params.get(1).equals("3")) {
- keypress.key.alt = true;
- }
- }
- events.add(keypress);
- reset();
- return events;
- default:
- break;
- }
- }
-
- // Unknown keystroke, ignore
- reset();
- return events;
-
- case MOUSE:
- params.set(0, params.get(paramI) + ch);
- if (params.get(0).length() == 3) {
- // We have enough to generate a mouse event
- events.add(parseMouse());
- reset();
- }
- return events;
-
- default:
- break;
- }
-
- // This "should" be impossible to reach
- return events;
+ private void processChar(final List<TInputEvent> events, final char ch) {
+
+ // ESCDELAY type timeout
+ Date now = new Date();
+ if (state == ParseState.ESCAPE) {
+ long escDelay = now.getTime() - escapeTime;
+ if (escDelay > 250) {
+ // After 0.25 seconds, assume a true escape character
+ events.add(controlChar((char)0x1B, false));
+ reset();
+ }
+ }
+
+ // TKeypress fields
+ boolean ctrl = false;
+ boolean alt = false;
+ boolean shift = false;
+
+ // System.err.printf("state: %s ch %c\r\n", state, ch);
+
+ switch (state) {
+ case GROUND:
+
+ if (ch == 0x1B) {
+ state = ParseState.ESCAPE;
+ escapeTime = now.getTime();
+ return;
+ }
+
+ if (ch <= 0x1F) {
+ // Control character
+ events.add(controlChar(ch, false));
+ reset();
+ return;
+ }
+
+ if (ch >= 0x20) {
+ // Normal character
+ events.add(new TKeypressEvent(false, 0, ch,
+ false, false, false));
+ reset();
+ return;
+ }
+
+ break;
+
+ case ESCAPE:
+ if (ch <= 0x1F) {
+ // ALT-Control character
+ events.add(controlChar(ch, true));
+ reset();
+ return;
+ }
+
+ if (ch == 'O') {
+ // This will be one of the function keys
+ state = ParseState.ESCAPE_INTERMEDIATE;
+ return;
+ }
+
+ // '[' goes to CSI_ENTRY
+ if (ch == '[') {
+ state = ParseState.CSI_ENTRY;
+ return;
+ }
+
+ // Everything else is assumed to be Alt-keystroke
+ if ((ch >= 'A') && (ch <= 'Z')) {
+ shift = true;
+ }
+ alt = true;
+ events.add(new TKeypressEvent(false, 0, ch, alt, ctrl, shift));
+ reset();
+ return;
+
+ case ESCAPE_INTERMEDIATE:
+ if ((ch >= 'P') && (ch <= 'S')) {
+ // Function key
+ switch (ch) {
+ case 'P':
+ events.add(new TKeypressEvent(kbF1));
+ break;
+ case 'Q':
+ events.add(new TKeypressEvent(kbF2));
+ break;
+ case 'R':
+ events.add(new TKeypressEvent(kbF3));
+ break;
+ case 'S':
+ events.add(new TKeypressEvent(kbF4));
+ break;
+ default:
+ break;
+ }
+ reset();
+ return;
+ }
+
+ // Unknown keystroke, ignore
+ reset();
+ return;
+
+ case CSI_ENTRY:
+ // Numbers - parameter values
+ if ((ch >= '0') && (ch <= '9')) {
+ params.set(params.size() - 1,
+ params.get(params.size() - 1) + ch);
+ state = ParseState.CSI_PARAM;
+ return;
+ }
+ // Parameter separator
+ if (ch == ';') {
+ params.add("");
+ return;
+ }
+
+ if ((ch >= 0x30) && (ch <= 0x7E)) {
+ switch (ch) {
+ case 'A':
+ // Up
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbUp, alt, ctrl, shift));
+ reset();
+ return;
+ case 'B':
+ // Down
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbDown, alt, ctrl, shift));
+ reset();
+ return;
+ case 'C':
+ // Right
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbRight, alt, ctrl, shift));
+ reset();
+ return;
+ case 'D':
+ // Left
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbLeft, alt, ctrl, shift));
+ reset();
+ return;
+ case 'H':
+ // Home
+ events.add(new TKeypressEvent(kbHome));
+ reset();
+ return;
+ case 'F':
+ // End
+ events.add(new TKeypressEvent(kbEnd));
+ reset();
+ return;
+ case 'Z':
+ // CBT - Cursor backward X tab stops (default 1)
+ events.add(new TKeypressEvent(kbBackTab));
+ reset();
+ return;
+ case 'M':
+ // Mouse position
+ state = ParseState.MOUSE;
+ return;
+ case '<':
+ // Mouse position, SGR (1006) coordinates
+ state = ParseState.MOUSE_SGR;
+ return;
+ default:
+ break;
+ }
+ }
+
+ // Unknown keystroke, ignore
+ reset();
+ return;
+
+ case MOUSE_SGR:
+ // Numbers - parameter values
+ if ((ch >= '0') && (ch <= '9')) {
+ params.set(params.size() - 1,
+ params.get(params.size() - 1) + ch);
+ return;
+ }
+ // Parameter separator
+ if (ch == ';') {
+ params.add("");
+ return;
+ }
+
+ switch (ch) {
+ case 'M':
+ // Generate a mouse press event
+ TInputEvent event = parseMouseSGR(false);
+ if (event != null) {
+ events.add(event);
+ }
+ reset();
+ return;
+ case 'm':
+ // Generate a mouse release event
+ event = parseMouseSGR(true);
+ if (event != null) {
+ events.add(event);
+ }
+ reset();
+ return;
+ default:
+ break;
+ }
+
+ // Unknown keystroke, ignore
+ reset();
+ return;
+
+ case CSI_PARAM:
+ // Numbers - parameter values
+ if ((ch >= '0') && (ch <= '9')) {
+ params.set(params.size() - 1,
+ params.get(params.size() - 1) + ch);
+ state = ParseState.CSI_PARAM;
+ return;
+ }
+ // Parameter separator
+ if (ch == ';') {
+ params.add("");
+ return;
+ }
+
+ if (ch == '~') {
+ events.add(csiFnKey());
+ reset();
+ return;
+ }
+
+ if ((ch >= 0x30) && (ch <= 0x7E)) {
+ switch (ch) {
+ case 'A':
+ // Up
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbUp, alt, ctrl, shift));
+ reset();
+ return;
+ case 'B':
+ // Down
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbDown, alt, ctrl, shift));
+ reset();
+ return;
+ case 'C':
+ // Right
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbRight, alt, ctrl, shift));
+ reset();
+ return;
+ case 'D':
+ // Left
+ if (params.size() > 1) {
+ if (params.get(1).equals("2")) {
+ shift = true;
+ }
+ if (params.get(1).equals("5")) {
+ ctrl = true;
+ }
+ if (params.get(1).equals("3")) {
+ alt = true;
+ }
+ }
+ events.add(new TKeypressEvent(kbLeft, alt, ctrl, shift));
+ reset();
+ return;
+ default:
+ break;
+ }
+ }
+
+ // Unknown keystroke, ignore
+ reset();
+ return;
+
+ case MOUSE:
+ params.set(0, params.get(params.size() - 1) + ch);
+ if (params.get(0).length() == 3) {
+ // We have enough to generate a mouse event
+ events.add(parseMouse());
+ reset();
+ }
+ return;
+
+ default:
+ break;
+ }
+
+ // This "should" be impossible to reach
+ return;