1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.grouper.app.gsh.jline;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.fusesource.jansi.internal.WindowsSupport;
24 import org.fusesource.jansi.internal.Kernel32.INPUT_RECORD;
25 import org.fusesource.jansi.internal.Kernel32.KEY_EVENT_RECORD;
26
27 import edu.internet2.middleware.grouper.app.gsh.GrouperShell;
28
29 import jline.AnsiWindowsTerminal;
30
31 public class WindowsTerminal extends AnsiWindowsTerminal {
32
33
34
35
36 public WindowsTerminal() throws Exception {
37 super();
38 }
39
40 @Override
41 public InputStream wrapInIfNeeded(InputStream in) throws IOException {
42
43 String groovyPreloadString = GrouperShell.getGroovyPreloadString() + "\n";
44 final ByteArrayInputStream groovyPreload = new ByteArrayInputStream(groovyPreloadString.getBytes("UTF-8"));
45
46 return new InputStream() {
47 private byte[] buf = null;
48 int bufIdx = 0;
49
50 @Override
51 public int read() throws IOException {
52 if (groovyPreload.available() > 0) {
53 return groovyPreload.read();
54 }
55
56 while (buf == null || bufIdx == buf.length) {
57 buf = readConsoleInput();
58 bufIdx = 0;
59 }
60 int c = buf[bufIdx] & 0xFF;
61 bufIdx++;
62 return c;
63 }
64 };
65 }
66
67
68 private byte[] readConsoleInput() {
69
70 INPUT_RECORD[] events = null;
71 try {
72 events = WindowsSupport.readConsoleInput(1);
73 } catch (IOException e) {
74
75 }
76 if (events == null) {
77 return new byte[0];
78 }
79 StringBuilder sb = new StringBuilder();
80 for (int i = 0; i < events.length; i++ ) {
81 KEY_EVENT_RECORD keyEvent = events[i].keyEvent;
82
83 if (keyEvent.keyDown) {
84 if (keyEvent.uchar > 0) {
85
86
87 final int altState = KEY_EVENT_RECORD.LEFT_ALT_PRESSED | KEY_EVENT_RECORD.RIGHT_ALT_PRESSED;
88
89
90 final int ctrlState = KEY_EVENT_RECORD.LEFT_CTRL_PRESSED | KEY_EVENT_RECORD.RIGHT_CTRL_PRESSED;
91 if (((keyEvent.uchar >= '@' && keyEvent.uchar <= '_') || (keyEvent.uchar >= 'a' && keyEvent.uchar <= 'z'))
92 && ((keyEvent.controlKeyState & altState) != 0) && ((keyEvent.controlKeyState & ctrlState) == 0)) {
93 sb.append('\u001B');
94 }
95
96 sb.append(keyEvent.uchar);
97 continue;
98 }
99
100
101 String escapeSequence = null;
102 switch (keyEvent.keyCode) {
103 case 0x21:
104 escapeSequence = "\u001B[5~";
105 break;
106 case 0x22:
107 escapeSequence = "\u001B[6~";
108 break;
109 case 0x23:
110 escapeSequence = "\u001B[4~";
111 break;
112 case 0x24:
113 escapeSequence = "\u001B[1~";
114 break;
115 case 0x25:
116 escapeSequence = "\u001B[D";
117 break;
118 case 0x26:
119 escapeSequence = "\u001B[A";
120 break;
121 case 0x27:
122 escapeSequence = "\u001B[C";
123 break;
124 case 0x28:
125 escapeSequence = "\u001B[B";
126 break;
127 case 0x2D:
128 escapeSequence = "\u001B[2~";
129 break;
130 case 0x2E:
131 escapeSequence = "\u001B[3~";
132 break;
133 default:
134 break;
135 }
136 if (escapeSequence != null) {
137 for (int k = 0; k < keyEvent.repeatCount; k++) {
138 sb.append(escapeSequence);
139 }
140 }
141 } else {
142
143
144 if (keyEvent.keyCode == 0x12 && keyEvent.uchar > 0) {
145 sb.append(keyEvent.uchar);
146 }
147 }
148 }
149 return sb.toString().getBytes();
150 }
151 }