0
|
1 /*
|
|
2 * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform".
|
|
3 *
|
|
4 * (c) Matthias L. Jugel, Marcus Meiner 1996-2005. All Rights Reserved.
|
|
5 *
|
|
6 * Please visit http://javatelnet.org/ for updates and contact.
|
|
7 *
|
|
8 * --LICENSE NOTICE--
|
|
9 * This program is free software; you can redistribute it and/or
|
|
10 * modify it under the terms of the GNU General Public License
|
|
11 * as published by the Free Software Foundation; either version 2
|
|
12 * of the License, or (at your option) any later version.
|
|
13 *
|
|
14 * This program is distributed in the hope that it will be useful,
|
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 * GNU General Public License for more details.
|
|
18 *
|
|
19 * You should have received a copy of the GNU General Public License
|
|
20 * along with this program; if not, write to the Free Software
|
|
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
22 * --LICENSE NOTICE--
|
|
23 *
|
|
24 */
|
|
25
|
|
26 package de.mud.terminal;
|
|
27
|
|
28 import android.text.AndroidCharacter;
|
|
29
|
|
30 import java.util.Properties;
|
|
31
|
|
32 /**
|
|
33 * Implementation of a VT terminal emulation plus ANSI compatible.
|
|
34 * <P>
|
|
35 * <B>Maintainer:</B> Marcus Meißner
|
|
36 *
|
|
37 * @version $Id: vt320.java 507 2005-10-25 10:14:52Z marcus $
|
|
38 * @author Matthias L. Jugel, Marcus Meißner
|
|
39 */
|
|
40 public abstract class vt320 extends VDUBuffer implements VDUInput {
|
|
41
|
|
42 /** the debug level */
|
|
43 private final static int debug = 0;
|
|
44 private StringBuilder debugStr;
|
|
45 public abstract void debug(String notice);
|
|
46
|
|
47 /**
|
|
48 * Write an answer back to the remote host. This is needed to be able to
|
|
49 * send terminal answers requests like status and type information.
|
|
50 * @param b the array of bytes to be sent
|
|
51 */
|
|
52 public abstract void write(byte[] b);
|
|
53
|
|
54 /**
|
|
55 * Write an answer back to the remote host. This is needed to be able to
|
|
56 * send terminal answers requests like status and type information.
|
|
57 * @param b the byte to be sent
|
|
58 */
|
|
59 public abstract void write(int b);
|
|
60
|
|
61 /**
|
|
62 * No more bytes to read from the transport, hook here to test screen changes
|
|
63 */
|
|
64 public void testChanged() {
|
|
65 /* do nothing by default */
|
|
66 }
|
|
67
|
|
68 /**
|
69
|
69 * inject field contents as if typed
|
|
70 */
|
|
71 public void setField(int l, int c, char [] d) {
|
|
72 // ignore line and column, just send the bytes to the host.
|
|
73 int n = d.length;
|
|
74 byte [] b = new byte [n];
|
112
|
75
|
|
76 for (int i = 0; i < n; i++) b[i] = (byte)(d[i] & 0x00ff);
|
|
77
|
69
|
78 write(b);
|
|
79 }
|
|
80
|
148
|
81 public void monitorKey(boolean down) {
|
|
82 // do nothing
|
|
83 }
|
|
84
|
175
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
85 public void keyDepressed(int keyCode, char keyChar, int modifiers) {
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
86 keyPressed(keyCode, keyChar, modifiers);
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
87 }
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
88
|
69
|
89 /**
|
0
|
90 * Play the beep sound ...
|
|
91 */
|
|
92 public void beep() {
|
|
93 /* do nothing by default */
|
|
94 }
|
|
95
|
41
|
96 public void redrawPassthru() {
|
|
97 redraw(); // VDUBuffer.redraw is protected
|
|
98 }
|
|
99
|
0
|
100 /**
|
|
101 * Convenience function for putString(char[], int, int)
|
|
102 */
|
|
103 public void putString(String s) {
|
|
104 int len = s.length();
|
|
105 char[] tmp = new char[len];
|
|
106 s.getChars(0, len, tmp, 0);
|
|
107 putString(tmp, null, 0, len);
|
|
108 }
|
|
109
|
|
110 /**
|
|
111 * Put string at current cursor position. Moves cursor
|
|
112 * according to the String. Does NOT wrap.
|
|
113 * @param s character array
|
|
114 * @param start place to start in array
|
|
115 * @param len number of characters to process
|
|
116 */
|
|
117 public void putString(char[] s, byte[] fullwidths, int start, int len) {
|
|
118 if (len > 0) {
|
|
119 //markLine(R, 1);
|
|
120 int lastChar = -1;
|
|
121 char c;
|
|
122 boolean isWide = false;
|
|
123
|
|
124 for (int i = 0; i < len; i++) {
|
|
125 c = s[start + i];
|
|
126
|
|
127 // Shortcut for my favorite ASCII
|
|
128 if (c <= 0x7F) {
|
|
129 if (lastChar != -1)
|
|
130 putChar((char) lastChar, isWide, false);
|
|
131
|
|
132 lastChar = c;
|
|
133 isWide = false;
|
|
134 }
|
|
135 else if (!Character.isLowSurrogate(c) && !Character.isHighSurrogate(c)) {
|
|
136 if (Character.getType(c) == Character.NON_SPACING_MARK) {
|
|
137 if (lastChar != -1) {
|
|
138 char nc = Precomposer.precompose((char) lastChar, c);
|
|
139 putChar(nc, isWide, false);
|
|
140 lastChar = -1;
|
|
141 }
|
|
142 }
|
|
143 else {
|
|
144 if (lastChar != -1)
|
|
145 putChar((char) lastChar, isWide, false);
|
|
146
|
|
147 lastChar = c;
|
|
148
|
|
149 if (fullwidths != null) {
|
|
150 final byte width = fullwidths[i];
|
|
151 isWide = (width == AndroidCharacter.EAST_ASIAN_WIDTH_WIDE)
|
|
152 || (width == AndroidCharacter.EAST_ASIAN_WIDTH_FULL_WIDTH);
|
|
153 }
|
|
154 }
|
|
155 }
|
|
156 }
|
|
157
|
|
158 if (lastChar != -1)
|
|
159 putChar((char) lastChar, isWide, false);
|
|
160
|
|
161 setCursorPosition(C, R);
|
|
162 redraw();
|
|
163 }
|
|
164 }
|
|
165
|
|
166 protected void sendTelnetCommand(byte cmd) {
|
|
167 /* do nothing by default */
|
|
168 }
|
|
169
|
|
170 /**
|
|
171 * Sent the changed window size from the terminal to all listeners.
|
|
172 */
|
|
173 protected void setWindowSize(int c, int r) {
|
|
174 /* To be overridden by Terminal.java */
|
|
175 }
|
|
176
|
|
177 @Override
|
|
178 public void setScreenSize(int c, int r, boolean broadcast) {
|
|
179 int oldrows = height;
|
|
180
|
|
181 if (debug > 2) {
|
|
182 if (debugStr == null)
|
|
183 debugStr = new StringBuilder();
|
|
184
|
|
185 debugStr.append("setscreensize (")
|
|
186 .append(c)
|
|
187 .append(',')
|
|
188 .append(r)
|
|
189 .append(',')
|
|
190 .append(broadcast)
|
|
191 .append(')');
|
|
192 debug(debugStr.toString());
|
|
193 debugStr.setLength(0);
|
|
194 }
|
|
195
|
|
196 super.setScreenSize(c, r, false);
|
|
197 boolean cursorChanged = false;
|
|
198
|
|
199 // Don't let the cursor go off the screen.
|
|
200 if (C >= c) {
|
|
201 C = c - 1;
|
|
202 cursorChanged = true;
|
|
203 }
|
|
204
|
|
205 if (R >= r) {
|
|
206 R = r - 1;
|
|
207 cursorChanged = true;
|
|
208 }
|
|
209
|
|
210 if (cursorChanged) {
|
|
211 setCursorPosition(C, R);
|
|
212 redraw();
|
|
213 }
|
|
214
|
|
215 if (broadcast) {
|
|
216 setWindowSize(c, r); /* broadcast up */
|
|
217 }
|
|
218 }
|
|
219
|
|
220
|
|
221 /**
|
|
222 * Create a new vt320 terminal and intialize it with useful settings.
|
|
223 */
|
|
224 public vt320(int width, int height) {
|
|
225 super(width, height);
|
|
226 debugStr = new StringBuilder();
|
|
227 setVMS(false);
|
|
228 setIBMCharset(false);
|
|
229 setTerminalID("vt320");
|
|
230 setBufferSize(100);
|
|
231 //setBorder(2, false);
|
|
232 gx = new char[4];
|
|
233 reset();
|
|
234 /* top row of numpad */
|
|
235 PF1 = "\u001bOP";
|
|
236 PF2 = "\u001bOQ";
|
|
237 PF3 = "\u001bOR";
|
|
238 PF4 = "\u001bOS";
|
|
239 /* the 3x2 keyblock on PC keyboards */
|
|
240 Insert = new String[4];
|
|
241 Remove = new String[4];
|
|
242 KeyHome = new String[4];
|
|
243 KeyEnd = new String[4];
|
|
244 NextScn = new String[4];
|
|
245 PrevScn = new String[4];
|
|
246 Escape = new String[4];
|
|
247 BackSpace = new String[4];
|
|
248 TabKey = new String[4];
|
|
249 Insert[0] = Insert[1] = Insert[2] = Insert[3] = "\u001b[2~";
|
|
250 Remove[0] = Remove[1] = Remove[2] = Remove[3] = "\u001b[3~";
|
|
251 PrevScn[0] = PrevScn[1] = PrevScn[2] = PrevScn[3] = "\u001b[5~";
|
|
252 NextScn[0] = NextScn[1] = NextScn[2] = NextScn[3] = "\u001b[6~";
|
|
253 KeyHome[0] = KeyHome[1] = KeyHome[2] = KeyHome[3] = "\u001b[H";
|
|
254 KeyEnd[0] = KeyEnd[1] = KeyEnd[2] = KeyEnd[3] = "\u001b[F";
|
|
255 Escape[0] = Escape[1] = Escape[2] = Escape[3] = "\u001b";
|
|
256
|
|
257 if (vms) {
|
|
258 BackSpace[1] = "" + (char) 10; // VMS shift deletes word back
|
|
259 BackSpace[2] = "\u0018"; // VMS control deletes line back
|
|
260 BackSpace[0] = BackSpace[3] = "\u007f"; // VMS other is delete
|
|
261 }
|
|
262 else {
|
|
263 //BackSpace[0] = BackSpace[1] = BackSpace[2] = BackSpace[3] = "\b";
|
|
264 // ConnectBot modifications.
|
|
265 BackSpace[0] = "\b";
|
|
266 BackSpace[1] = "\u007f";
|
|
267 BackSpace[2] = "\u001b[3~";
|
|
268 BackSpace[3] = "\u001b[2~";
|
|
269 }
|
|
270
|
|
271 /* some more VT100 keys */
|
|
272 Find = "\u001b[1~";
|
|
273 Select = "\u001b[4~";
|
|
274 Help = "\u001b[28~";
|
|
275 Do = "\u001b[29~";
|
|
276 FunctionKey = new String[21];
|
|
277 FunctionKey[0] = "";
|
|
278 FunctionKey[1] = PF1;
|
|
279 FunctionKey[2] = PF2;
|
|
280 FunctionKey[3] = PF3;
|
|
281 FunctionKey[4] = PF4;
|
|
282 /* following are defined differently for vt220 / vt132 ... */
|
|
283 FunctionKey[5] = "\u001b[15~";
|
|
284 FunctionKey[6] = "\u001b[17~";
|
|
285 FunctionKey[7] = "\u001b[18~";
|
|
286 FunctionKey[8] = "\u001b[19~";
|
|
287 FunctionKey[9] = "\u001b[20~";
|
|
288 FunctionKey[10] = "\u001b[21~";
|
|
289 FunctionKey[11] = "\u001b[23~";
|
|
290 FunctionKey[12] = "\u001b[24~";
|
|
291 FunctionKey[13] = "\u001b[25~";
|
|
292 FunctionKey[14] = "\u001b[26~";
|
|
293 FunctionKey[15] = Help;
|
|
294 FunctionKey[16] = Do;
|
|
295 FunctionKey[17] = "\u001b[31~";
|
|
296 FunctionKey[18] = "\u001b[32~";
|
|
297 FunctionKey[19] = "\u001b[33~";
|
|
298 FunctionKey[20] = "\u001b[34~";
|
|
299 FunctionKeyShift = new String[21];
|
|
300 FunctionKeyAlt = new String[21];
|
|
301 FunctionKeyCtrl = new String[21];
|
|
302
|
|
303 for (int i = 0; i < 20; i++) {
|
|
304 FunctionKeyShift[i] = "";
|
|
305 FunctionKeyAlt[i] = "";
|
|
306 FunctionKeyCtrl[i] = "";
|
|
307 }
|
|
308
|
|
309 FunctionKeyShift[15] = Find;
|
|
310 FunctionKeyShift[16] = Select;
|
|
311 TabKey[0] = "\u0009";
|
|
312 TabKey[1] = "\u001bOP\u0009";
|
|
313 TabKey[2] = TabKey[3] = "";
|
|
314 KeyUp = new String[4];
|
|
315 KeyUp[0] = "\u001b[A";
|
|
316 KeyDown = new String[4];
|
|
317 KeyDown[0] = "\u001b[B";
|
|
318 KeyRight = new String[4];
|
|
319 KeyRight[0] = "\u001b[C";
|
|
320 KeyLeft = new String[4];
|
|
321 KeyLeft[0] = "\u001b[D";
|
|
322 Numpad = new String[10];
|
|
323 Numpad[0] = "\u001bOp";
|
|
324 Numpad[1] = "\u001bOq";
|
|
325 Numpad[2] = "\u001bOr";
|
|
326 Numpad[3] = "\u001bOs";
|
|
327 Numpad[4] = "\u001bOt";
|
|
328 Numpad[5] = "\u001bOu";
|
|
329 Numpad[6] = "\u001bOv";
|
|
330 Numpad[7] = "\u001bOw";
|
|
331 Numpad[8] = "\u001bOx";
|
|
332 Numpad[9] = "\u001bOy";
|
|
333 KPMinus = PF4;
|
|
334 KPComma = "\u001bOl";
|
|
335 KPPeriod = "\u001bOn";
|
|
336 KPEnter = "\u001bOM";
|
|
337 NUMPlus = new String[4];
|
|
338 NUMPlus[0] = "+";
|
|
339 NUMDot = new String[4];
|
|
340 NUMDot[0] = ".";
|
|
341 }
|
|
342
|
|
343 public void setBackspace(int type) {
|
|
344 switch (type) {
|
|
345 case DELETE_IS_DEL:
|
|
346 BackSpace[0] = "\u007f";
|
|
347 BackSpace[1] = "\b";
|
|
348 break;
|
|
349
|
|
350 case DELETE_IS_BACKSPACE:
|
|
351 BackSpace[0] = "\b";
|
|
352 BackSpace[1] = "\u007f";
|
|
353 break;
|
|
354 }
|
|
355 }
|
|
356
|
|
357 /**
|
|
358 * Create a default vt320 terminal with 80 columns and 24 lines.
|
|
359 */
|
|
360 public vt320() {
|
|
361 this(80, 24);
|
|
362 }
|
|
363
|
|
364 /**
|
|
365 * Terminal is mouse-aware and requires (x,y) coordinates of
|
|
366 * on the terminal (character coordinates) and the button clicked.
|
|
367 * @param x
|
|
368 * @param y
|
|
369 * @param modifiers
|
|
370 */
|
|
371 public void mousePressed(int x, int y, int modifiers) {
|
|
372 if (mouserpt == 0)
|
|
373 return;
|
|
374
|
|
375 int mods = modifiers;
|
|
376 mousebut = 3;
|
|
377
|
|
378 if ((mods & 16) == 16) mousebut = 0;
|
|
379
|
|
380 if ((mods & 8) == 8) mousebut = 1;
|
|
381
|
|
382 if ((mods & 4) == 4) mousebut = 2;
|
|
383
|
|
384 int mousecode;
|
|
385
|
|
386 if (mouserpt == 9) /* X10 Mouse */
|
|
387 mousecode = 0x20 | mousebut;
|
|
388 else /* normal xterm mouse reporting */
|
|
389 mousecode = mousebut | 0x20 | ((mods & 7) << 2);
|
|
390
|
|
391 byte b[] = new byte[6];
|
|
392 b[0] = 27;
|
|
393 b[1] = (byte) '[';
|
|
394 b[2] = (byte) 'M';
|
|
395 b[3] = (byte) mousecode;
|
|
396 b[4] = (byte)(0x20 + x + 1);
|
|
397 b[5] = (byte)(0x20 + y + 1);
|
|
398 write(b); // FIXME: writeSpecial here
|
|
399 }
|
|
400
|
|
401 /**
|
|
402 * Terminal is mouse-aware and requires the coordinates and button
|
|
403 * of the release.
|
|
404 * @param x
|
|
405 * @param y
|
|
406 * @param modifiers
|
|
407 */
|
|
408 public void mouseReleased(int x, int y, int modifiers) {
|
|
409 if (mouserpt == 0)
|
|
410 return;
|
|
411
|
|
412 /* problem is tht modifiers still have the released button set in them.
|
|
413 int mods = modifiers;
|
|
414 mousebut = 3;
|
|
415 if ((mods & 16)==16) mousebut=0;
|
|
416 if ((mods & 8)==8 ) mousebut=1;
|
|
417 if ((mods & 4)==4 ) mousebut=2;
|
|
418 */
|
|
419 int mousecode;
|
|
420
|
|
421 if (mouserpt == 9)
|
|
422 mousecode = 0x20 + mousebut; /* same as press? appears so. */
|
|
423 else
|
|
424 mousecode = '#';
|
|
425
|
|
426 byte b[] = new byte[6];
|
|
427 b[0] = 27;
|
|
428 b[1] = (byte) '[';
|
|
429 b[2] = (byte) 'M';
|
|
430 b[3] = (byte) mousecode;
|
|
431 b[4] = (byte)(0x20 + x + 1);
|
|
432 b[5] = (byte)(0x20 + y + 1);
|
|
433 write(b); // FIXME: writeSpecial here
|
|
434 mousebut = 0;
|
|
435 }
|
|
436
|
|
437
|
|
438 /** we should do localecho (passed from other modules). false is default */
|
|
439 private boolean localecho = false;
|
|
440
|
|
441 /**
|
|
442 * Enable or disable the local echo property of the terminal.
|
|
443 * @param echo true if the terminal should echo locally
|
|
444 */
|
|
445 public void setLocalEcho(boolean echo) {
|
|
446 localecho = echo;
|
|
447 }
|
|
448
|
|
449 /**
|
|
450 * Enable the VMS mode of the terminal to handle some things differently
|
|
451 * for VMS hosts.
|
|
452 * @param vms true for vms mode, false for normal mode
|
|
453 */
|
|
454 public void setVMS(boolean vms) {
|
|
455 this.vms = vms;
|
|
456 }
|
|
457
|
|
458 /**
|
|
459 * Enable the usage of the IBM character set used by some BBS's. Special
|
|
460 * graphical character are available in this mode.
|
|
461 * @param ibm true to use the ibm character set
|
|
462 */
|
|
463 public void setIBMCharset(boolean ibm) {
|
|
464 useibmcharset = ibm;
|
|
465 }
|
|
466
|
|
467 /**
|
|
468 * Override the standard key codes used by the terminal emulation.
|
|
469 * @param codes a properties object containing key code definitions
|
|
470 */
|
|
471 public void setKeyCodes(Properties codes) {
|
|
472 String res, prefixes[] = {"", "S", "C", "A"};
|
|
473 int i;
|
|
474
|
|
475 for (i = 0; i < 10; i++) {
|
|
476 res = codes.getProperty("NUMPAD" + i);
|
|
477
|
|
478 if (res != null) Numpad[i] = unEscape(res);
|
|
479 }
|
|
480
|
|
481 for (i = 1; i < 20; i++) {
|
|
482 res = codes.getProperty("F" + i);
|
|
483
|
|
484 if (res != null) FunctionKey[i] = unEscape(res);
|
|
485
|
|
486 res = codes.getProperty("SF" + i);
|
|
487
|
|
488 if (res != null) FunctionKeyShift[i] = unEscape(res);
|
|
489
|
|
490 res = codes.getProperty("CF" + i);
|
|
491
|
|
492 if (res != null) FunctionKeyCtrl[i] = unEscape(res);
|
|
493
|
|
494 res = codes.getProperty("AF" + i);
|
|
495
|
|
496 if (res != null) FunctionKeyAlt[i] = unEscape(res);
|
|
497 }
|
|
498
|
|
499 for (i = 0; i < 4; i++) {
|
|
500 res = codes.getProperty(prefixes[i] + "PGUP");
|
|
501
|
|
502 if (res != null) PrevScn[i] = unEscape(res);
|
|
503
|
|
504 res = codes.getProperty(prefixes[i] + "PGDOWN");
|
|
505
|
|
506 if (res != null) NextScn[i] = unEscape(res);
|
|
507
|
|
508 res = codes.getProperty(prefixes[i] + "END");
|
|
509
|
|
510 if (res != null) KeyEnd[i] = unEscape(res);
|
|
511
|
|
512 res = codes.getProperty(prefixes[i] + "HOME");
|
|
513
|
|
514 if (res != null) KeyHome[i] = unEscape(res);
|
|
515
|
|
516 res = codes.getProperty(prefixes[i] + "INSERT");
|
|
517
|
|
518 if (res != null) Insert[i] = unEscape(res);
|
|
519
|
|
520 res = codes.getProperty(prefixes[i] + "REMOVE");
|
|
521
|
|
522 if (res != null) Remove[i] = unEscape(res);
|
|
523
|
|
524 res = codes.getProperty(prefixes[i] + "UP");
|
|
525
|
|
526 if (res != null) KeyUp[i] = unEscape(res);
|
|
527
|
|
528 res = codes.getProperty(prefixes[i] + "DOWN");
|
|
529
|
|
530 if (res != null) KeyDown[i] = unEscape(res);
|
|
531
|
|
532 res = codes.getProperty(prefixes[i] + "LEFT");
|
|
533
|
|
534 if (res != null) KeyLeft[i] = unEscape(res);
|
|
535
|
|
536 res = codes.getProperty(prefixes[i] + "RIGHT");
|
|
537
|
|
538 if (res != null) KeyRight[i] = unEscape(res);
|
|
539
|
|
540 res = codes.getProperty(prefixes[i] + "ESCAPE");
|
|
541
|
|
542 if (res != null) Escape[i] = unEscape(res);
|
|
543
|
|
544 res = codes.getProperty(prefixes[i] + "BACKSPACE");
|
|
545
|
|
546 if (res != null) BackSpace[i] = unEscape(res);
|
|
547
|
|
548 res = codes.getProperty(prefixes[i] + "TAB");
|
|
549
|
|
550 if (res != null) TabKey[i] = unEscape(res);
|
|
551
|
|
552 res = codes.getProperty(prefixes[i] + "NUMPLUS");
|
|
553
|
|
554 if (res != null) NUMPlus[i] = unEscape(res);
|
|
555
|
|
556 res = codes.getProperty(prefixes[i] + "NUMDECIMAL");
|
|
557
|
|
558 if (res != null) NUMDot[i] = unEscape(res);
|
|
559 }
|
|
560 }
|
|
561
|
|
562 /**
|
|
563 * Set the terminal id used to identify this terminal.
|
|
564 * @param terminalID the id string
|
|
565 */
|
|
566 public void setTerminalID(String terminalID) {
|
|
567 this.terminalID = terminalID;
|
|
568
|
|
569 if (terminalID.equals("scoansi")) {
|
|
570 FunctionKey[1] = "\u001b[M"; FunctionKey[2] = "\u001b[N";
|
|
571 FunctionKey[3] = "\u001b[O"; FunctionKey[4] = "\u001b[P";
|
|
572 FunctionKey[5] = "\u001b[Q"; FunctionKey[6] = "\u001b[R";
|
|
573 FunctionKey[7] = "\u001b[S"; FunctionKey[8] = "\u001b[T";
|
|
574 FunctionKey[9] = "\u001b[U"; FunctionKey[10] = "\u001b[V";
|
|
575 FunctionKey[11] = "\u001b[W"; FunctionKey[12] = "\u001b[X";
|
|
576 FunctionKey[13] = "\u001b[Y"; FunctionKey[14] = "?";
|
|
577 FunctionKey[15] = "\u001b[a"; FunctionKey[16] = "\u001b[b";
|
|
578 FunctionKey[17] = "\u001b[c"; FunctionKey[18] = "\u001b[d";
|
|
579 FunctionKey[19] = "\u001b[e"; FunctionKey[20] = "\u001b[f";
|
|
580 PrevScn[0] = PrevScn[1] = PrevScn[2] = PrevScn[3] = "\u001b[I";
|
|
581 NextScn[0] = NextScn[1] = NextScn[2] = NextScn[3] = "\u001b[G";
|
|
582 // more theoretically.
|
|
583 }
|
|
584 }
|
|
585
|
|
586 public void setAnswerBack(String ab) {
|
|
587 this.answerBack = unEscape(ab);
|
|
588 }
|
|
589
|
|
590 /**
|
|
591 * Get the terminal id used to identify this terminal.
|
|
592 */
|
|
593 public String getTerminalID() {
|
|
594 return terminalID;
|
|
595 }
|
|
596
|
|
597 /**
|
|
598 * A small conveniance method thar converts the string to a byte array
|
|
599 * for sending.
|
|
600 * @param s the string to be sent
|
|
601 */
|
|
602 private boolean write(String s, boolean doecho) {
|
|
603 if (debug > 2) {
|
|
604 debugStr.append("write(|")
|
|
605 .append(s)
|
|
606 .append("|,")
|
|
607 .append(doecho);
|
|
608 debug(debugStr.toString());
|
|
609 debugStr.setLength(0);
|
|
610 }
|
|
611
|
|
612 if (s == null) // aka the empty string.
|
|
613 return true;
|
|
614
|
|
615 /* NOTE: getBytes() honours some locale, it *CONVERTS* the string.
|
|
616 * However, we output only 7bit stuff towards the target, and *some*
|
|
617 * 8 bit control codes. We must not mess up the latter, so we do hand
|
|
618 * by hand copy.
|
|
619 */
|
|
620 byte arr[] = new byte[s.length()];
|
|
621
|
|
622 for (int i = 0; i < s.length(); i++) {
|
|
623 arr[i] = (byte) s.charAt(i);
|
|
624 }
|
|
625
|
|
626 write(arr);
|
|
627
|
|
628 if (doecho)
|
|
629 putString(s);
|
|
630
|
|
631 return true;
|
|
632 }
|
|
633
|
|
634 private boolean write(int s, boolean doecho) {
|
|
635 if (debug > 2) {
|
|
636 debugStr.append("write(|")
|
|
637 .append(s)
|
|
638 .append("|,")
|
|
639 .append(doecho);
|
|
640 debug(debugStr.toString());
|
|
641 debugStr.setLength(0);
|
|
642 }
|
|
643
|
|
644 write(s);
|
|
645
|
|
646 // TODO check if character is wide
|
|
647 if (doecho)
|
|
648 putChar((char)s, false, false);
|
|
649
|
|
650 return true;
|
|
651 }
|
|
652
|
|
653 private boolean write(String s) {
|
|
654 return write(s, localecho);
|
|
655 }
|
|
656
|
|
657 // ===================================================================
|
|
658 // the actual terminal emulation code comes here:
|
|
659 // ===================================================================
|
|
660
|
|
661 private String terminalID = "vt320";
|
|
662 private String answerBack = "Use Terminal.answerback to set ...\n";
|
|
663
|
|
664 // X - COLUMNS, Y - ROWS
|
|
665 int R, C;
|
|
666 int attributes = 0;
|
|
667
|
|
668 int Sc, Sr, Sa, Stm, Sbm;
|
|
669 char Sgr, Sgl;
|
|
670 char Sgx[];
|
|
671
|
|
672 int insertmode = 0;
|
|
673 int statusmode = 0;
|
|
674 boolean vt52mode = false;
|
|
675 boolean keypadmode = false; /* false - numeric, true - application */
|
|
676 boolean output8bit = false;
|
|
677 int normalcursor = 0;
|
|
678 boolean moveoutsidemargins = true;
|
|
679 boolean wraparound = true;
|
|
680 boolean sendcrlf = true;
|
|
681 boolean capslock = false;
|
|
682 boolean numlock = false;
|
|
683 int mouserpt = 0;
|
|
684 byte mousebut = 0;
|
|
685
|
|
686 boolean useibmcharset = false;
|
|
687
|
|
688 int lastwaslf = 0;
|
|
689 boolean usedcharsets = false;
|
|
690
|
|
691 private final static char ESC = 27;
|
|
692 private final static char IND = 132;
|
|
693 private final static char NEL = 133;
|
|
694 private final static char RI = 141;
|
|
695 private final static char SS2 = 142;
|
|
696 private final static char SS3 = 143;
|
|
697 private final static char DCS = 144;
|
|
698 private final static char HTS = 136;
|
|
699 private final static char CSI = 155;
|
|
700 private final static char OSC = 157;
|
|
701 private final static int TSTATE_DATA = 0;
|
|
702 private final static int TSTATE_ESC = 1; /* ESC */
|
|
703 private final static int TSTATE_CSI = 2; /* ESC [ */
|
|
704 private final static int TSTATE_DCS = 3; /* ESC P */
|
|
705 private final static int TSTATE_DCEQ = 4; /* ESC [? */
|
|
706 private final static int TSTATE_ESCSQUARE = 5; /* ESC # */
|
|
707 private final static int TSTATE_OSC = 6; /* ESC ] */
|
|
708 private final static int TSTATE_SETG0 = 7; /* ESC (? */
|
|
709 private final static int TSTATE_SETG1 = 8; /* ESC )? */
|
|
710 private final static int TSTATE_SETG2 = 9; /* ESC *? */
|
|
711 private final static int TSTATE_SETG3 = 10; /* ESC +? */
|
|
712 private final static int TSTATE_CSI_DOLLAR = 11; /* ESC [ Pn $ */
|
|
713 private final static int TSTATE_CSI_EX = 12; /* ESC [ ! */
|
|
714 private final static int TSTATE_ESCSPACE = 13; /* ESC <space> */
|
|
715 private final static int TSTATE_VT52X = 14;
|
|
716 private final static int TSTATE_VT52Y = 15;
|
|
717 private final static int TSTATE_CSI_TICKS = 16;
|
|
718 private final static int TSTATE_CSI_EQUAL = 17; /* ESC [ = */
|
|
719 private final static int TSTATE_TITLE = 18; /* xterm title */
|
|
720
|
|
721 /* Keys we support */
|
175
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
722 public final static int KEY_PAUSE = 1;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
723 public final static int KEY_F1 = 2;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
724 public final static int KEY_F2 = 3;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
725 public final static int KEY_F3 = 4;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
726 public final static int KEY_F4 = 5;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
727 public final static int KEY_F5 = 6;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
728 public final static int KEY_F6 = 7;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
729 public final static int KEY_F7 = 8;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
730 public final static int KEY_F8 = 9;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
731 public final static int KEY_F9 = 10;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
732 public final static int KEY_F10 = 11;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
733 public final static int KEY_F11 = 12;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
734 public final static int KEY_F12 = 13;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
735 public final static int KEY_F13 = 14; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
736 public final static int KEY_F14 = 15; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
737 public final static int KEY_F15 = 16; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
738 public final static int KEY_F16 = 17; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
739 public final static int KEY_F17 = 18; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
740 public final static int KEY_F18 = 19; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
741 public final static int KEY_F19 = 20; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
742 public final static int KEY_F20 = 21; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
743 public final static int KEY_F21 = 22; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
744 public final static int KEY_F22 = 23; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
745 public final static int KEY_F23 = 24; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
746 public final static int KEY_F24 = 25; // only used by tn5250
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
747 public final static int KEY_UP = 26;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
748 public final static int KEY_DOWN = 27;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
749 public final static int KEY_LEFT = 28;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
750 public final static int KEY_RIGHT = 29;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
751 public final static int KEY_PAGE_DOWN = 30;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
752 public final static int KEY_PAGE_UP = 31;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
753 public final static int KEY_INSERT = 32;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
754 public final static int KEY_DELETE = 33;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
755 public final static int KEY_BACK_SPACE = 34;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
756 public final static int KEY_HOME = 35;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
757 public final static int KEY_END = 36;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
758 public final static int KEY_NUM_LOCK = 37;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
759 public final static int KEY_CAPS_LOCK = 38;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
760 public final static int KEY_SHIFT = 39;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
761 public final static int KEY_CONTROL = 40;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
762 public final static int KEY_ALT = 41;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
763 public final static int KEY_ENTER = 42;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
764 public final static int KEY_NUMPAD0 = 43;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
765 public final static int KEY_NUMPAD1 = 44;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
766 public final static int KEY_NUMPAD2 = 45;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
767 public final static int KEY_NUMPAD3 = 46;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
768 public final static int KEY_NUMPAD4 = 47;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
769 public final static int KEY_NUMPAD5 = 48;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
770 public final static int KEY_NUMPAD6 = 49;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
771 public final static int KEY_NUMPAD7 = 50;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
772 public final static int KEY_NUMPAD8 = 51;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
773 public final static int KEY_NUMPAD9 = 52;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
774 public final static int KEY_DECIMAL = 53;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
775 public final static int KEY_ADD = 54;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
776 public final static int KEY_ESCAPE = 55;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
777 public final static int KEY_TAB = 56;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
778 public final static int KEY_SYSREQ = 57; // only used by tn5250
|
0
|
779
|
|
780 public final static int DELETE_IS_DEL = 0;
|
|
781 public final static int DELETE_IS_BACKSPACE = 1;
|
|
782
|
|
783 /* The graphics charsets
|
|
784 * B - default ASCII
|
|
785 * A - ISO Latin 1
|
|
786 * 0 - DEC SPECIAL
|
|
787 * < - User defined
|
|
788 * ....
|
|
789 */
|
|
790 char gx[];
|
|
791 char gl; // GL (left charset)
|
|
792 char gr; // GR (right charset)
|
|
793 int onegl; // single shift override for GL.
|
|
794
|
|
795 // Map from scoansi linedrawing to DEC _and_ unicode (for the stuff which
|
|
796 // is not in linedrawing). Got from experimenting with scoadmin.
|
|
797 private final static String scoansi_acs = "Tm7k3x4u?kZl@mYjEnB\u2566DqCtAvM\u2550:\u2551N\u2557I\u2554;\u2557H\u255a0a<\u255d";
|
|
798 // array to store DEC Special -> Unicode mapping
|
|
799 // Unicode DEC Unicode name (DEC name)
|
|
800 private static char DECSPECIAL[] = {
|
|
801 '\u0040', //5f blank
|
|
802 '\u2666', //60 black diamond
|
|
803 '\u2592', //61 grey square
|
|
804 '\u2409', //62 Horizontal tab (ht) pict. for control
|
|
805 '\u240c', //63 Form Feed (ff) pict. for control
|
|
806 '\u240d', //64 Carriage Return (cr) pict. for control
|
|
807 '\u240a', //65 Line Feed (lf) pict. for control
|
|
808 '\u00ba', //66 Masculine ordinal indicator
|
|
809 '\u00b1', //67 Plus or minus sign
|
|
810 '\u2424', //68 New Line (nl) pict. for control
|
|
811 '\u240b', //69 Vertical Tab (vt) pict. for control
|
|
812 '\u2518', //6a Forms light up and left
|
|
813 '\u2510', //6b Forms light down and left
|
|
814 '\u250c', //6c Forms light down and right
|
|
815 '\u2514', //6d Forms light up and right
|
|
816 '\u253c', //6e Forms light vertical and horizontal
|
|
817 '\u2594', //6f Upper 1/8 block (Scan 1)
|
|
818 '\u2580', //70 Upper 1/2 block (Scan 3)
|
|
819 '\u2500', //71 Forms light horizontal or ?em dash? (Scan 5)
|
|
820 '\u25ac', //72 \u25ac black rect. or \u2582 lower 1/4 (Scan 7)
|
|
821 '\u005f', //73 \u005f underscore or \u2581 lower 1/8 (Scan 9)
|
|
822 '\u251c', //74 Forms light vertical and right
|
|
823 '\u2524', //75 Forms light vertical and left
|
|
824 '\u2534', //76 Forms light up and horizontal
|
|
825 '\u252c', //77 Forms light down and horizontal
|
|
826 '\u2502', //78 vertical bar
|
|
827 '\u2264', //79 less than or equal
|
|
828 '\u2265', //7a greater than or equal
|
|
829 '\u00b6', //7b paragraph
|
|
830 '\u2260', //7c not equal
|
|
831 '\u00a3', //7d Pound Sign (british)
|
|
832 '\u00b7' //7e Middle Dot
|
|
833 };
|
|
834
|
|
835 /** Strings to send on function key pressing */
|
|
836 private String Numpad[];
|
|
837 private String FunctionKey[];
|
|
838 private String FunctionKeyShift[];
|
|
839 private String FunctionKeyCtrl[];
|
|
840 private String FunctionKeyAlt[];
|
|
841 private String TabKey[];
|
|
842 private String KeyUp[], KeyDown[], KeyLeft[], KeyRight[];
|
|
843 private String KPMinus, KPComma, KPPeriod, KPEnter;
|
|
844 private String PF1, PF2, PF3, PF4;
|
|
845 private String Help, Do, Find, Select;
|
|
846
|
|
847 private String KeyHome[], KeyEnd[], Insert[], Remove[], PrevScn[], NextScn[];
|
|
848 private String Escape[], BackSpace[], NUMDot[], NUMPlus[];
|
|
849
|
|
850 private String osc, dcs; /* to memorize OSC & DCS control sequence */
|
|
851
|
|
852 /** vt320 state variable (internal) */
|
|
853 private int term_state = TSTATE_DATA;
|
|
854 /** in vms mode, set by Terminal.VMS property */
|
|
855 private boolean vms = false;
|
|
856 /** Tabulators */
|
|
857 private byte[] Tabs;
|
|
858 /** The list of integers as used by CSI */
|
|
859 private int[] DCEvars = new int[30];
|
|
860 private int DCEvar;
|
|
861
|
|
862 /**
|
|
863 * Replace escape code characters (backslash + identifier) with their
|
|
864 * respective codes.
|
|
865 * @param tmp the string to be parsed
|
|
866 * @return a unescaped string
|
|
867 */
|
|
868 static String unEscape(String tmp) {
|
|
869 int idx = 0, oldidx = 0;
|
|
870 String cmd;
|
|
871 // f.println("unescape("+tmp+")");
|
|
872 cmd = "";
|
|
873
|
|
874 while ((idx = tmp.indexOf('\\', oldidx)) >= 0 &&
|
|
875 ++idx <= tmp.length()) {
|
|
876 cmd += tmp.substring(oldidx, idx - 1);
|
|
877
|
|
878 if (idx == tmp.length()) return cmd;
|
|
879
|
|
880 switch (tmp.charAt(idx)) {
|
|
881 case 'b':
|
|
882 cmd += "\b";
|
|
883 break;
|
|
884
|
|
885 case 'e':
|
|
886 cmd += "\u001b";
|
|
887 break;
|
|
888
|
|
889 case 'n':
|
|
890 cmd += "\n";
|
|
891 break;
|
|
892
|
|
893 case 'r':
|
|
894 cmd += "\r";
|
|
895 break;
|
|
896
|
|
897 case 't':
|
|
898 cmd += "\t";
|
|
899 break;
|
|
900
|
|
901 case 'v':
|
|
902 cmd += "\u000b";
|
|
903 break;
|
|
904
|
|
905 case 'a':
|
|
906 cmd += "\u0012";
|
|
907 break;
|
|
908
|
|
909 default :
|
|
910 if ((tmp.charAt(idx) >= '0') && (tmp.charAt(idx) <= '9')) {
|
|
911 int i;
|
|
912
|
|
913 for (i = idx; i < tmp.length(); i++)
|
|
914 if ((tmp.charAt(i) < '0') || (tmp.charAt(i) > '9'))
|
|
915 break;
|
|
916
|
|
917 cmd += (char) Integer.parseInt(tmp.substring(idx, i));
|
|
918 idx = i - 1;
|
|
919 }
|
|
920 else
|
|
921 cmd += tmp.substring(idx, ++idx);
|
|
922
|
|
923 break;
|
|
924 }
|
|
925
|
|
926 oldidx = ++idx;
|
|
927 }
|
|
928
|
|
929 if (oldidx <= tmp.length()) cmd += tmp.substring(oldidx);
|
|
930
|
|
931 return cmd;
|
|
932 }
|
|
933
|
|
934 /**
|
|
935 * A small conveniance method thar converts a 7bit string to the 8bit
|
|
936 * version depending on VT52/Output8Bit mode.
|
|
937 *
|
|
938 * @param s the string to be sent
|
|
939 */
|
|
940 private boolean writeSpecial(String s) {
|
|
941 if (s == null)
|
|
942 return true;
|
|
943
|
|
944 if (((s.length() >= 3) && (s.charAt(0) == 27) && (s.charAt(1) == 'O'))) {
|
|
945 if (vt52mode) {
|
|
946 if ((s.charAt(2) >= 'P') && (s.charAt(2) <= 'S')) {
|
|
947 s = "\u001b" + s.substring(2); /* ESC x */
|
|
948 }
|
|
949 else {
|
|
950 s = "\u001b?" + s.substring(2); /* ESC ? x */
|
|
951 }
|
|
952 }
|
|
953 else {
|
|
954 if (output8bit) {
|
|
955 s = "\u008f" + s.substring(2); /* SS3 x */
|
|
956 } /* else keep string as it is */
|
|
957 }
|
|
958 }
|
|
959
|
|
960 if (((s.length() >= 3) && (s.charAt(0) == 27) && (s.charAt(1) == '['))) {
|
|
961 if (output8bit) {
|
|
962 s = "\u009b" + s.substring(2); /* CSI ... */
|
|
963 } /* else keep */
|
|
964 }
|
|
965
|
|
966 return write(s, false);
|
|
967 }
|
|
968
|
|
969 /**
|
104
|
970 * main keytyping event handler for all the special function and modifier keys
|
|
971 * the normal keys are processed by write(byte b);
|
0
|
972 */
|
|
973 public void keyPressed(int keyCode, char keyChar, int modifiers) {
|
|
974 boolean control = (modifiers & VDUInput.KEY_CONTROL) != 0;
|
|
975 boolean shift = (modifiers & VDUInput.KEY_SHIFT) != 0;
|
|
976 boolean alt = (modifiers & VDUInput.KEY_ALT) != 0;
|
|
977
|
|
978 if (debug > 1) {
|
|
979 debugStr.append("keyPressed(")
|
|
980 .append(keyCode)
|
|
981 .append(", ")
|
|
982 .append((int)keyChar)
|
|
983 .append(", ")
|
|
984 .append(modifiers)
|
|
985 .append(')');
|
|
986 debug(debugStr.toString());
|
|
987 debugStr.setLength(0);
|
|
988 }
|
|
989
|
|
990 int xind;
|
|
991 String fmap[];
|
|
992 xind = 0;
|
|
993 fmap = FunctionKey;
|
|
994
|
|
995 if (shift) {
|
|
996 fmap = FunctionKeyShift;
|
|
997 xind = 1;
|
|
998 }
|
|
999
|
|
1000 if (control) {
|
|
1001 fmap = FunctionKeyCtrl;
|
|
1002 xind = 2;
|
|
1003 }
|
|
1004
|
|
1005 if (alt) {
|
|
1006 fmap = FunctionKeyAlt;
|
|
1007 xind = 3;
|
|
1008 }
|
|
1009
|
|
1010 switch (keyCode) {
|
|
1011 case KEY_PAUSE:
|
|
1012 if (shift || control)
|
|
1013 sendTelnetCommand((byte) 243); // BREAK
|
|
1014
|
|
1015 break;
|
|
1016
|
|
1017 case KEY_F1:
|
|
1018 writeSpecial(fmap[1]);
|
|
1019 break;
|
|
1020
|
|
1021 case KEY_F2:
|
|
1022 writeSpecial(fmap[2]);
|
|
1023 break;
|
|
1024
|
|
1025 case KEY_F3:
|
|
1026 writeSpecial(fmap[3]);
|
|
1027 break;
|
|
1028
|
|
1029 case KEY_F4:
|
|
1030 writeSpecial(fmap[4]);
|
|
1031 break;
|
|
1032
|
|
1033 case KEY_F5:
|
|
1034 writeSpecial(fmap[5]);
|
|
1035 break;
|
|
1036
|
|
1037 case KEY_F6:
|
|
1038 writeSpecial(fmap[6]);
|
|
1039 break;
|
|
1040
|
|
1041 case KEY_F7:
|
|
1042 writeSpecial(fmap[7]);
|
|
1043 break;
|
|
1044
|
|
1045 case KEY_F8:
|
|
1046 writeSpecial(fmap[8]);
|
|
1047 break;
|
|
1048
|
|
1049 case KEY_F9:
|
|
1050 writeSpecial(fmap[9]);
|
|
1051 break;
|
|
1052
|
|
1053 case KEY_F10:
|
|
1054 writeSpecial(fmap[10]);
|
|
1055 break;
|
|
1056
|
|
1057 case KEY_F11:
|
|
1058 writeSpecial(fmap[11]);
|
|
1059 break;
|
|
1060
|
|
1061 case KEY_F12:
|
|
1062 writeSpecial(fmap[12]);
|
|
1063 break;
|
|
1064
|
175
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1065 case KEY_F13:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1066 case KEY_F14:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1067 case KEY_F15:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1068 case KEY_F16:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1069 case KEY_F17:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1070 case KEY_F18:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1071 case KEY_F19:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1072 case KEY_F20:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1073 case KEY_F21:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1074 case KEY_F22:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1075 case KEY_F23:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1076 case KEY_F24:
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1077 break;
|
2a7199ad90be
send cursor movement caused by user keystrokes to the monitor
Carl Byington <carl@five-ten-sg.com>
diff
changeset
|
1078
|
0
|
1079 case KEY_UP:
|
|
1080 writeSpecial(KeyUp[xind]);
|
|
1081 break;
|
|
1082
|
|
1083 case KEY_DOWN:
|
|
1084 writeSpecial(KeyDown[xind]);
|
|
1085 break;
|
|
1086
|
|
1087 case KEY_LEFT:
|
|
1088 writeSpecial(KeyLeft[xind]);
|
|
1089 break;
|
|
1090
|
|
1091 case KEY_RIGHT:
|
|
1092 writeSpecial(KeyRight[xind]);
|
|
1093 break;
|
|
1094
|
|
1095 case KEY_PAGE_DOWN:
|
|
1096 writeSpecial(NextScn[xind]);
|
|
1097 break;
|
|
1098
|
|
1099 case KEY_PAGE_UP:
|
|
1100 writeSpecial(PrevScn[xind]);
|
|
1101 break;
|
|
1102
|
|
1103 case KEY_INSERT:
|
|
1104 writeSpecial(Insert[xind]);
|
|
1105 break;
|
|
1106
|
|
1107 case KEY_DELETE:
|
|
1108 writeSpecial(Remove[xind]);
|
|
1109 break;
|
|
1110
|
|
1111 case KEY_BACK_SPACE:
|
|
1112 writeSpecial(BackSpace[xind]);
|
|
1113
|
|
1114 if (localecho) {
|
|
1115 if (BackSpace[xind] == "\b") {
|
|
1116 putString("\b \b"); // make the last char 'deleted'
|
|
1117 }
|
|
1118 else {
|
|
1119 putString(BackSpace[xind]); // echo it
|
|
1120 }
|
|
1121 }
|
|
1122
|
|
1123 break;
|
|
1124
|
|
1125 case KEY_HOME:
|
|
1126 writeSpecial(KeyHome[xind]);
|
|
1127 break;
|
|
1128
|
|
1129 case KEY_END:
|
|
1130 writeSpecial(KeyEnd[xind]);
|
|
1131 break;
|
|
1132
|
|
1133 case KEY_NUM_LOCK:
|
|
1134 if (vms && control) {
|
|
1135 writeSpecial(PF1);
|
|
1136 }
|
|
1137
|
|
1138 if (!control)
|
|
1139 numlock = !numlock;
|
|
1140
|
|
1141 break;
|
|
1142
|
|
1143 case KEY_CAPS_LOCK:
|
|
1144 capslock = !capslock;
|
53
|
1145 break;
|
0
|
1146
|
|
1147 case KEY_SHIFT:
|
|
1148 case KEY_CONTROL:
|
|
1149 case KEY_ALT:
|
53
|
1150 break;
|
|
1151
|
|
1152 case KEY_ESCAPE:
|
104
|
1153 writeSpecial(Escape[xind]);
|
53
|
1154 break;
|
|
1155
|
56
|
1156 case KEY_ENTER:
|
|
1157 write(0x0d);
|
|
1158 break;
|
|
1159
|
53
|
1160 case KEY_TAB:
|
104
|
1161 writeSpecial(TabKey[xind]);
|
53
|
1162 break;
|
0
|
1163
|
|
1164 default:
|
|
1165 break;
|
|
1166 }
|
|
1167 }
|
|
1168
|
|
1169 private void handle_dcs(String dcs) {
|
|
1170 debugStr.append("DCS: ")
|
|
1171 .append(dcs);
|
|
1172 debug(debugStr.toString());
|
|
1173 debugStr.setLength(0);
|
|
1174 }
|
|
1175
|
|
1176 private void handle_osc(String osc) {
|
|
1177 if (osc.length() > 2 && osc.substring(0, 2).equals("4;")) {
|
|
1178 // Define color palette
|
|
1179 String[] colorData = osc.split(";");
|
|
1180
|
|
1181 try {
|
|
1182 int colorIndex = Integer.parseInt(colorData[1]);
|
|
1183
|
|
1184 if ("rgb:".equals(colorData[2].substring(0, 4))) {
|
|
1185 String[] rgb = colorData[2].substring(4).split("/");
|
|
1186 int red = Integer.parseInt(rgb[0].substring(0, 2), 16) & 0xFF;
|
|
1187 int green = Integer.parseInt(rgb[1].substring(0, 2), 16) & 0xFF;
|
|
1188 int blue = Integer.parseInt(rgb[2].substring(0, 2), 16) & 0xFF;
|
|
1189 display.setColor(colorIndex, red, green, blue);
|
|
1190 }
|
|
1191 }
|
|
1192 catch (Exception e) {
|
|
1193 debugStr.append("OSC: invalid color sequence encountered: ")
|
|
1194 .append(osc);
|
|
1195 debug(debugStr.toString());
|
|
1196 debugStr.setLength(0);
|
|
1197 }
|
|
1198 }
|
|
1199 else
|
|
1200 debug("OSC: " + osc);
|
|
1201 }
|
|
1202
|
|
1203 private final static char unimap[] = {
|
|
1204 //#
|
|
1205 //# Name: cp437_DOSLatinUS to Unicode table
|
|
1206 //# Unicode version: 1.1
|
|
1207 //# Table version: 1.1
|
|
1208 //# Table format: Format A
|
|
1209 //# Date: 03/31/95
|
|
1210 //# Authors: Michel Suignard <michelsu@microsoft.com>
|
|
1211 //# Lori Hoerth <lorih@microsoft.com>
|
|
1212 //# General notes: none
|
|
1213 //#
|
|
1214 //# Format: Three tab-separated columns
|
|
1215 //# Column #1 is the cp1255_WinHebrew code (in hex)
|
|
1216 //# Column #2 is the Unicode (in hex as 0xXXXX)
|
|
1217 //# Column #3 is the Unicode name (follows a comment sign, '#')
|
|
1218 //#
|
|
1219 //# The entries are in cp437_DOSLatinUS order
|
|
1220 //#
|
|
1221
|
|
1222 0x0000, // #NULL
|
|
1223 0x0001, // #START OF HEADING
|
|
1224 0x0002, // #START OF TEXT
|
|
1225 0x0003, // #END OF TEXT
|
|
1226 0x0004, // #END OF TRANSMISSION
|
|
1227 0x0005, // #ENQUIRY
|
|
1228 0x0006, // #ACKNOWLEDGE
|
|
1229 0x0007, // #BELL
|
|
1230 0x0008, // #BACKSPACE
|
|
1231 0x0009, // #HORIZONTAL TABULATION
|
|
1232 0x000a, // #LINE FEED
|
|
1233 0x000b, // #VERTICAL TABULATION
|
|
1234 0x000c, // #FORM FEED
|
|
1235 0x000d, // #CARRIAGE RETURN
|
|
1236 0x000e, // #SHIFT OUT
|
|
1237 0x000f, // #SHIFT IN
|
|
1238 0x0010, // #DATA LINK ESCAPE
|
|
1239 0x0011, // #DEVICE CONTROL ONE
|
|
1240 0x0012, // #DEVICE CONTROL TWO
|
|
1241 0x0013, // #DEVICE CONTROL THREE
|
|
1242 0x0014, // #DEVICE CONTROL FOUR
|
|
1243 0x0015, // #NEGATIVE ACKNOWLEDGE
|
|
1244 0x0016, // #SYNCHRONOUS IDLE
|
|
1245 0x0017, // #END OF TRANSMISSION BLOCK
|
|
1246 0x0018, // #CANCEL
|
|
1247 0x0019, // #END OF MEDIUM
|
|
1248 0x001a, // #SUBSTITUTE
|
|
1249 0x001b, // #ESCAPE
|
|
1250 0x001c, // #FILE SEPARATOR
|
|
1251 0x001d, // #GROUP SEPARATOR
|
|
1252 0x001e, // #RECORD SEPARATOR
|
|
1253 0x001f, // #UNIT SEPARATOR
|
|
1254 0x0020, // #SPACE
|
|
1255 0x0021, // #EXCLAMATION MARK
|
|
1256 0x0022, // #QUOTATION MARK
|
|
1257 0x0023, // #NUMBER SIGN
|
|
1258 0x0024, // #DOLLAR SIGN
|
|
1259 0x0025, // #PERCENT SIGN
|
|
1260 0x0026, // #AMPERSAND
|
|
1261 0x0027, // #APOSTROPHE
|
|
1262 0x0028, // #LEFT PARENTHESIS
|
|
1263 0x0029, // #RIGHT PARENTHESIS
|
|
1264 0x002a, // #ASTERISK
|
|
1265 0x002b, // #PLUS SIGN
|
|
1266 0x002c, // #COMMA
|
|
1267 0x002d, // #HYPHEN-MINUS
|
|
1268 0x002e, // #FULL STOP
|
|
1269 0x002f, // #SOLIDUS
|
|
1270 0x0030, // #DIGIT ZERO
|
|
1271 0x0031, // #DIGIT ONE
|
|
1272 0x0032, // #DIGIT TWO
|
|
1273 0x0033, // #DIGIT THREE
|
|
1274 0x0034, // #DIGIT FOUR
|
|
1275 0x0035, // #DIGIT FIVE
|
|
1276 0x0036, // #DIGIT SIX
|
|
1277 0x0037, // #DIGIT SEVEN
|
|
1278 0x0038, // #DIGIT EIGHT
|
|
1279 0x0039, // #DIGIT NINE
|
|
1280 0x003a, // #COLON
|
|
1281 0x003b, // #SEMICOLON
|
|
1282 0x003c, // #LESS-THAN SIGN
|
|
1283 0x003d, // #EQUALS SIGN
|
|
1284 0x003e, // #GREATER-THAN SIGN
|
|
1285 0x003f, // #QUESTION MARK
|
|
1286 0x0040, // #COMMERCIAL AT
|
|
1287 0x0041, // #LATIN CAPITAL LETTER A
|
|
1288 0x0042, // #LATIN CAPITAL LETTER B
|
|
1289 0x0043, // #LATIN CAPITAL LETTER C
|
|
1290 0x0044, // #LATIN CAPITAL LETTER D
|
|
1291 0x0045, // #LATIN CAPITAL LETTER E
|
|
1292 0x0046, // #LATIN CAPITAL LETTER F
|
|
1293 0x0047, // #LATIN CAPITAL LETTER G
|
|
1294 0x0048, // #LATIN CAPITAL LETTER H
|
|
1295 0x0049, // #LATIN CAPITAL LETTER I
|
|
1296 0x004a, // #LATIN CAPITAL LETTER J
|
|
1297 0x004b, // #LATIN CAPITAL LETTER K
|
|
1298 0x004c, // #LATIN CAPITAL LETTER L
|
|
1299 0x004d, // #LATIN CAPITAL LETTER M
|
|
1300 0x004e, // #LATIN CAPITAL LETTER N
|
|
1301 0x004f, // #LATIN CAPITAL LETTER O
|
|
1302 0x0050, // #LATIN CAPITAL LETTER P
|
|
1303 0x0051, // #LATIN CAPITAL LETTER Q
|
|
1304 0x0052, // #LATIN CAPITAL LETTER R
|
|
1305 0x0053, // #LATIN CAPITAL LETTER S
|
|
1306 0x0054, // #LATIN CAPITAL LETTER T
|
|
1307 0x0055, // #LATIN CAPITAL LETTER U
|
|
1308 0x0056, // #LATIN CAPITAL LETTER V
|
|
1309 0x0057, // #LATIN CAPITAL LETTER W
|
|
1310 0x0058, // #LATIN CAPITAL LETTER X
|
|
1311 0x0059, // #LATIN CAPITAL LETTER Y
|
|
1312 0x005a, // #LATIN CAPITAL LETTER Z
|
|
1313 0x005b, // #LEFT SQUARE BRACKET
|
|
1314 0x005c, // #REVERSE SOLIDUS
|
|
1315 0x005d, // #RIGHT SQUARE BRACKET
|
|
1316 0x005e, // #CIRCUMFLEX ACCENT
|
|
1317 0x005f, // #LOW LINE
|
|
1318 0x0060, // #GRAVE ACCENT
|
|
1319 0x0061, // #LATIN SMALL LETTER A
|
|
1320 0x0062, // #LATIN SMALL LETTER B
|
|
1321 0x0063, // #LATIN SMALL LETTER C
|
|
1322 0x0064, // #LATIN SMALL LETTER D
|
|
1323 0x0065, // #LATIN SMALL LETTER E
|
|
1324 0x0066, // #LATIN SMALL LETTER F
|
|
1325 0x0067, // #LATIN SMALL LETTER G
|
|
1326 0x0068, // #LATIN SMALL LETTER H
|
|
1327 0x0069, // #LATIN SMALL LETTER I
|
|
1328 0x006a, // #LATIN SMALL LETTER J
|
|
1329 0x006b, // #LATIN SMALL LETTER K
|
|
1330 0x006c, // #LATIN SMALL LETTER L
|
|
1331 0x006d, // #LATIN SMALL LETTER M
|
|
1332 0x006e, // #LATIN SMALL LETTER N
|
|
1333 0x006f, // #LATIN SMALL LETTER O
|
|
1334 0x0070, // #LATIN SMALL LETTER P
|
|
1335 0x0071, // #LATIN SMALL LETTER Q
|
|
1336 0x0072, // #LATIN SMALL LETTER R
|
|
1337 0x0073, // #LATIN SMALL LETTER S
|
|
1338 0x0074, // #LATIN SMALL LETTER T
|
|
1339 0x0075, // #LATIN SMALL LETTER U
|
|
1340 0x0076, // #LATIN SMALL LETTER V
|
|
1341 0x0077, // #LATIN SMALL LETTER W
|
|
1342 0x0078, // #LATIN SMALL LETTER X
|
|
1343 0x0079, // #LATIN SMALL LETTER Y
|
|
1344 0x007a, // #LATIN SMALL LETTER Z
|
|
1345 0x007b, // #LEFT CURLY BRACKET
|
|
1346 0x007c, // #VERTICAL LINE
|
|
1347 0x007d, // #RIGHT CURLY BRACKET
|
|
1348 0x007e, // #TILDE
|
|
1349 0x007f, // #DELETE
|
|
1350 0x00c7, // #LATIN CAPITAL LETTER C WITH CEDILLA
|
|
1351 0x00fc, // #LATIN SMALL LETTER U WITH DIAERESIS
|
|
1352 0x00e9, // #LATIN SMALL LETTER E WITH ACUTE
|
|
1353 0x00e2, // #LATIN SMALL LETTER A WITH CIRCUMFLEX
|
|
1354 0x00e4, // #LATIN SMALL LETTER A WITH DIAERESIS
|
|
1355 0x00e0, // #LATIN SMALL LETTER A WITH GRAVE
|
|
1356 0x00e5, // #LATIN SMALL LETTER A WITH RING ABOVE
|
|
1357 0x00e7, // #LATIN SMALL LETTER C WITH CEDILLA
|
|
1358 0x00ea, // #LATIN SMALL LETTER E WITH CIRCUMFLEX
|
|
1359 0x00eb, // #LATIN SMALL LETTER E WITH DIAERESIS
|
|
1360 0x00e8, // #LATIN SMALL LETTER E WITH GRAVE
|
|
1361 0x00ef, // #LATIN SMALL LETTER I WITH DIAERESIS
|
|
1362 0x00ee, // #LATIN SMALL LETTER I WITH CIRCUMFLEX
|
|
1363 0x00ec, // #LATIN SMALL LETTER I WITH GRAVE
|
|
1364 0x00c4, // #LATIN CAPITAL LETTER A WITH DIAERESIS
|
|
1365 0x00c5, // #LATIN CAPITAL LETTER A WITH RING ABOVE
|
|
1366 0x00c9, // #LATIN CAPITAL LETTER E WITH ACUTE
|
|
1367 0x00e6, // #LATIN SMALL LIGATURE AE
|
|
1368 0x00c6, // #LATIN CAPITAL LIGATURE AE
|
|
1369 0x00f4, // #LATIN SMALL LETTER O WITH CIRCUMFLEX
|
|
1370 0x00f6, // #LATIN SMALL LETTER O WITH DIAERESIS
|
|
1371 0x00f2, // #LATIN SMALL LETTER O WITH GRAVE
|
|
1372 0x00fb, // #LATIN SMALL LETTER U WITH CIRCUMFLEX
|
|
1373 0x00f9, // #LATIN SMALL LETTER U WITH GRAVE
|
|
1374 0x00ff, // #LATIN SMALL LETTER Y WITH DIAERESIS
|
|
1375 0x00d6, // #LATIN CAPITAL LETTER O WITH DIAERESIS
|
|
1376 0x00dc, // #LATIN CAPITAL LETTER U WITH DIAERESIS
|
|
1377 0x00a2, // #CENT SIGN
|
|
1378 0x00a3, // #POUND SIGN
|
|
1379 0x00a5, // #YEN SIGN
|
|
1380 0x20a7, // #PESETA SIGN
|
|
1381 0x0192, // #LATIN SMALL LETTER F WITH HOOK
|
|
1382 0x00e1, // #LATIN SMALL LETTER A WITH ACUTE
|
|
1383 0x00ed, // #LATIN SMALL LETTER I WITH ACUTE
|
|
1384 0x00f3, // #LATIN SMALL LETTER O WITH ACUTE
|
|
1385 0x00fa, // #LATIN SMALL LETTER U WITH ACUTE
|
|
1386 0x00f1, // #LATIN SMALL LETTER N WITH TILDE
|
|
1387 0x00d1, // #LATIN CAPITAL LETTER N WITH TILDE
|
|
1388 0x00aa, // #FEMININE ORDINAL INDICATOR
|
|
1389 0x00ba, // #MASCULINE ORDINAL INDICATOR
|
|
1390 0x00bf, // #INVERTED QUESTION MARK
|
|
1391 0x2310, // #REVERSED NOT SIGN
|
|
1392 0x00ac, // #NOT SIGN
|
|
1393 0x00bd, // #VULGAR FRACTION ONE HALF
|
|
1394 0x00bc, // #VULGAR FRACTION ONE QUARTER
|
|
1395 0x00a1, // #INVERTED EXCLAMATION MARK
|
|
1396 0x00ab, // #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
1397 0x00bb, // #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
1398 0x2591, // #LIGHT SHADE
|
|
1399 0x2592, // #MEDIUM SHADE
|
|
1400 0x2593, // #DARK SHADE
|
|
1401 0x2502, // #BOX DRAWINGS LIGHT VERTICAL
|
|
1402 0x2524, // #BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
|
1403 0x2561, // #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
|
|
1404 0x2562, // #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
|
|
1405 0x2556, // #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
|
|
1406 0x2555, // #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
|
|
1407 0x2563, // #BOX DRAWINGS DOUBLE VERTICAL AND LEFT
|
|
1408 0x2551, // #BOX DRAWINGS DOUBLE VERTICAL
|
|
1409 0x2557, // #BOX DRAWINGS DOUBLE DOWN AND LEFT
|
|
1410 0x255d, // #BOX DRAWINGS DOUBLE UP AND LEFT
|
|
1411 0x255c, // #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
|
|
1412 0x255b, // #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
|
|
1413 0x2510, // #BOX DRAWINGS LIGHT DOWN AND LEFT
|
|
1414 0x2514, // #BOX DRAWINGS LIGHT UP AND RIGHT
|
|
1415 0x2534, // #BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
|
1416 0x252c, // #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
|
1417 0x251c, // #BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
|
1418 0x2500, // #BOX DRAWINGS LIGHT HORIZONTAL
|
|
1419 0x253c, // #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
|
|
1420 0x255e, // #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
|
|
1421 0x255f, // #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
|
|
1422 0x255a, // #BOX DRAWINGS DOUBLE UP AND RIGHT
|
|
1423 0x2554, // #BOX DRAWINGS DOUBLE DOWN AND RIGHT
|
|
1424 0x2569, // #BOX DRAWINGS DOUBLE UP AND HORIZONTAL
|
|
1425 0x2566, // #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
|
|
1426 0x2560, // #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
|
|
1427 0x2550, // #BOX DRAWINGS DOUBLE HORIZONTAL
|
|
1428 0x256c, // #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
|
|
1429 0x2567, // #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
|
|
1430 0x2568, // #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
|
|
1431 0x2564, // #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
|
|
1432 0x2565, // #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
|
|
1433 0x2559, // #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
|
|
1434 0x2558, // #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
|
|
1435 0x2552, // #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
|
|
1436 0x2553, // #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
|
|
1437 0x256b, // #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
|
|
1438 0x256a, // #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
|
|
1439 0x2518, // #BOX DRAWINGS LIGHT UP AND LEFT
|
|
1440 0x250c, // #BOX DRAWINGS LIGHT DOWN AND RIGHT
|
|
1441 0x2588, // #FULL BLOCK
|
|
1442 0x2584, // #LOWER HALF BLOCK
|
|
1443 0x258c, // #LEFT HALF BLOCK
|
|
1444 0x2590, // #RIGHT HALF BLOCK
|
|
1445 0x2580, // #UPPER HALF BLOCK
|
|
1446 0x03b1, // #GREEK SMALL LETTER ALPHA
|
|
1447 0x00df, // #LATIN SMALL LETTER SHARP S
|
|
1448 0x0393, // #GREEK CAPITAL LETTER GAMMA
|
|
1449 0x03c0, // #GREEK SMALL LETTER PI
|
|
1450 0x03a3, // #GREEK CAPITAL LETTER SIGMA
|
|
1451 0x03c3, // #GREEK SMALL LETTER SIGMA
|
|
1452 0x00b5, // #MICRO SIGN
|
|
1453 0x03c4, // #GREEK SMALL LETTER TAU
|
|
1454 0x03a6, // #GREEK CAPITAL LETTER PHI
|
|
1455 0x0398, // #GREEK CAPITAL LETTER THETA
|
|
1456 0x03a9, // #GREEK CAPITAL LETTER OMEGA
|
|
1457 0x03b4, // #GREEK SMALL LETTER DELTA
|
|
1458 0x221e, // #INFINITY
|
|
1459 0x03c6, // #GREEK SMALL LETTER PHI
|
|
1460 0x03b5, // #GREEK SMALL LETTER EPSILON
|
|
1461 0x2229, // #INTERSECTION
|
|
1462 0x2261, // #IDENTICAL TO
|
|
1463 0x00b1, // #PLUS-MINUS SIGN
|
|
1464 0x2265, // #GREATER-THAN OR EQUAL TO
|
|
1465 0x2264, // #LESS-THAN OR EQUAL TO
|
|
1466 0x2320, // #TOP HALF INTEGRAL
|
|
1467 0x2321, // #BOTTOM HALF INTEGRAL
|
|
1468 0x00f7, // #DIVISION SIGN
|
|
1469 0x2248, // #ALMOST EQUAL TO
|
|
1470 0x00b0, // #DEGREE SIGN
|
|
1471 0x2219, // #BULLET OPERATOR
|
|
1472 0x00b7, // #MIDDLE DOT
|
|
1473 0x221a, // #SQUARE ROOT
|
|
1474 0x207f, // #SUPERSCRIPT LATIN SMALL LETTER N
|
|
1475 0x00b2, // #SUPERSCRIPT TWO
|
|
1476 0x25a0, // #BLACK SQUARE
|
|
1477 0x00a0, // #NO-BREAK SPACE
|
|
1478 };
|
|
1479
|
|
1480 public char map_cp850_unicode(char x) {
|
|
1481 if (x >= 0x100)
|
|
1482 return x;
|
|
1483
|
|
1484 return unimap[x];
|
|
1485 }
|
|
1486
|
|
1487 private void _SetCursor(int row, int col) {
|
|
1488 int maxr = height - 1;
|
|
1489 int tm = getTopMargin();
|
|
1490 R = (row < 0) ? 0 : row;
|
|
1491 C = (col < 0) ? 0 : (col >= width) ? width - 1 : col;
|
|
1492
|
|
1493 if (!moveoutsidemargins) {
|
|
1494 R += tm;
|
|
1495 maxr = getBottomMargin();
|
|
1496 }
|
|
1497
|
|
1498 if (R > maxr) R = maxr;
|
|
1499 }
|
|
1500
|
|
1501 private void putChar(char c, boolean isWide, boolean doshowcursor) {
|
|
1502 int rows = this.height; //statusline
|
|
1503 int columns = this.width;
|
|
1504
|
|
1505 // byte msg[];
|
|
1506 // if (debug > 4) {
|
|
1507 // debugStr.append("putChar(")
|
|
1508 // .append(c)
|
|
1509 // .append(" [")
|
|
1510 // .append((int) c)
|
|
1511 // .append("]) at R=")
|
|
1512 // .append(R)
|
|
1513 // .append(" , C=")
|
|
1514 // .append(C)
|
|
1515 // .append(", columns=")
|
|
1516 // .append(columns)
|
|
1517 // .append(", rows=")
|
|
1518 // .append(rows);
|
|
1519 // debug(debugStr.toString());
|
|
1520 // debugStr.setLength(0);
|
|
1521 // }
|
|
1522 // markLine(R, 1);
|
|
1523 // if (c > 255) {
|
|
1524 // if (debug > 0)
|
|
1525 // debug("char > 255:" + (int) c);
|
|
1526 // //return;
|
|
1527 // }
|
|
1528 switch (term_state) {
|
|
1529 case TSTATE_DATA:
|
|
1530
|
|
1531 /* FIXME: we shouldn't use chars with bit 8 set if ibmcharset.
|
|
1532 * probably... but some BBS do anyway...
|
|
1533 */
|
|
1534 if (!useibmcharset) {
|
|
1535 boolean doneflag = true;
|
|
1536
|
|
1537 switch (c) {
|
|
1538 case OSC:
|
|
1539 osc = "";
|
|
1540 term_state = TSTATE_OSC;
|
|
1541 break;
|
|
1542
|
|
1543 case RI:
|
|
1544 if (R > getTopMargin())
|
|
1545 R--;
|
|
1546 else
|
|
1547 insertLine(R, 1, SCROLL_DOWN);
|
|
1548
|
|
1549 if (debug > 1)
|
|
1550 debug("RI");
|
|
1551
|
|
1552 break;
|
|
1553
|
|
1554 case IND:
|
|
1555 if (debug > 2) {
|
|
1556 debugStr.append("IND at ")
|
|
1557 .append(R)
|
|
1558 .append(", tm is ")
|
|
1559 .append(getTopMargin())
|
|
1560 .append(", bm is ")
|
|
1561 .append(getBottomMargin());
|
|
1562 debug(debugStr.toString());
|
|
1563 debugStr.setLength(0);
|
|
1564 }
|
|
1565
|
|
1566 if (R == getBottomMargin() || R == rows - 1)
|
|
1567 insertLine(R, 1, SCROLL_UP);
|
|
1568 else
|
|
1569 R++;
|
|
1570
|
|
1571 if (debug > 1)
|
|
1572 debug("IND (at " + R + " )");
|
|
1573
|
|
1574 break;
|
|
1575
|
|
1576 case NEL:
|
|
1577 if (R == getBottomMargin() || R == rows - 1)
|
|
1578 insertLine(R, 1, SCROLL_UP);
|
|
1579 else
|
|
1580 R++;
|
|
1581
|
|
1582 C = 0;
|
|
1583
|
|
1584 if (debug > 1)
|
|
1585 debug("NEL (at " + R + " )");
|
|
1586
|
|
1587 break;
|
|
1588
|
|
1589 case HTS:
|
|
1590 Tabs[C] = 1;
|
|
1591
|
|
1592 if (debug > 1)
|
|
1593 debug("HTS");
|
|
1594
|
|
1595 break;
|
|
1596
|
|
1597 case DCS:
|
|
1598 dcs = "";
|
|
1599 term_state = TSTATE_DCS;
|
|
1600 break;
|
|
1601
|
|
1602 default:
|
|
1603 doneflag = false;
|
|
1604 break;
|
|
1605 }
|
|
1606
|
|
1607 if (doneflag) break;
|
|
1608 }
|
|
1609
|
|
1610 switch (c) {
|
|
1611 case SS3:
|
|
1612 onegl = 3;
|
|
1613 break;
|
|
1614
|
|
1615 case SS2:
|
|
1616 onegl = 2;
|
|
1617 break;
|
|
1618
|
|
1619 case CSI: // should be in the 8bit section, but some BBS use this
|
|
1620 DCEvar = 0;
|
|
1621 DCEvars[0] = 0;
|
|
1622 DCEvars[1] = 0;
|
|
1623 DCEvars[2] = 0;
|
|
1624 DCEvars[3] = 0;
|
|
1625 term_state = TSTATE_CSI;
|
|
1626 break;
|
|
1627
|
|
1628 case ESC:
|
|
1629 term_state = TSTATE_ESC;
|
|
1630 lastwaslf = 0;
|
|
1631 break;
|
|
1632
|
|
1633 case 5: /* ENQ */
|
|
1634 write(answerBack, false);
|
|
1635 break;
|
|
1636
|
|
1637 case 12:
|
|
1638 /* FormFeed, Home for the BBS world */
|
|
1639 deleteArea(0, 0, columns, rows, attributes);
|
|
1640 C = R = 0;
|
|
1641 break;
|
|
1642
|
|
1643 case '\b': /* 8 */
|
|
1644 C--;
|
|
1645
|
|
1646 if (C < 0)
|
|
1647 C = 0;
|
|
1648
|
|
1649 lastwaslf = 0;
|
|
1650 break;
|
|
1651
|
|
1652 case '\t':
|
|
1653 do {
|
|
1654 // Don't overwrite or insert! TABS are not destructive, but movement!
|
|
1655 C++;
|
|
1656 }
|
|
1657 while (C < columns && (Tabs[C] == 0));
|
|
1658
|
|
1659 lastwaslf = 0;
|
|
1660 break;
|
|
1661
|
|
1662 case '\r': // 13 CR
|
|
1663 C = 0;
|
|
1664 break;
|
|
1665
|
|
1666 case '\n': // 10 LF
|
|
1667 if (debug > 3)
|
|
1668 debug("R= " + R + ", bm " + getBottomMargin() + ", tm=" + getTopMargin() + ", rows=" + rows);
|
|
1669
|
|
1670 if (!vms) {
|
|
1671 if (lastwaslf != 0 && lastwaslf != c) // Ray: I do not understand this logic.
|
|
1672 break;
|
|
1673
|
|
1674 lastwaslf = c;
|
|
1675 /*C = 0;*/
|
|
1676 }
|
|
1677
|
|
1678 if (R == getBottomMargin() || R >= rows - 1)
|
|
1679 insertLine(R, 1, SCROLL_UP);
|
|
1680 else
|
|
1681 R++;
|
|
1682
|
|
1683 break;
|
|
1684
|
|
1685 case 7:
|
|
1686 beep();
|
|
1687 break;
|
|
1688
|
|
1689 case '\016': /* SMACS , as */
|
|
1690 /* ^N, Shift out - Put G1 into GL */
|
|
1691 gl = 1;
|
|
1692 usedcharsets = true;
|
|
1693 break;
|
|
1694
|
|
1695 case '\017': /* RMACS , ae */
|
|
1696 /* ^O, Shift in - Put G0 into GL */
|
|
1697 gl = 0;
|
|
1698 usedcharsets = true;
|
|
1699 break;
|
|
1700
|
|
1701 default: {
|
|
1702 int thisgl = gl;
|
|
1703
|
|
1704 if (onegl >= 0) {
|
|
1705 thisgl = onegl;
|
|
1706 onegl = -1;
|
|
1707 }
|
|
1708
|
|
1709 lastwaslf = 0;
|
|
1710
|
|
1711 if (c < 32) {
|
|
1712 if (c != 0)
|
|
1713 if (debug > 0)
|
|
1714 debug("TSTATE_DATA char: " + ((int) c));
|
|
1715
|
|
1716 /*break; some BBS really want those characters, like hearst etc. */
|
|
1717 if (c == 0) /* print 0 ... you bet */
|
|
1718 break;
|
|
1719 }
|
|
1720
|
|
1721 if (C >= columns) {
|
|
1722 if (wraparound) {
|
|
1723 int bot = rows;
|
|
1724
|
|
1725 // If we're in the scroll region, check against the bottom margin
|
|
1726 if (R <= getBottomMargin() && R >= getTopMargin())
|
|
1727 bot = getBottomMargin() + 1;
|
|
1728
|
|
1729 if (R < bot - 1)
|
|
1730 R++;
|
|
1731 else {
|
|
1732 if (debug > 3) debug("scrolling due to wrap at " + R);
|
|
1733
|
|
1734 insertLine(R, 1, SCROLL_UP);
|
|
1735 }
|
|
1736
|
|
1737 C = 0;
|
|
1738 }
|
|
1739 else {
|
|
1740 // cursor stays on last character.
|
|
1741 C = columns - 1;
|
|
1742 }
|
|
1743 }
|
|
1744
|
|
1745 boolean mapped = false;
|
|
1746
|
|
1747 // Mapping if DEC Special is chosen charset
|
|
1748 if (usedcharsets) {
|
|
1749 if (c >= '\u0020' && c <= '\u007f') {
|
|
1750 switch (gx[thisgl]) {
|
|
1751 case '0':
|
|
1752
|
|
1753 // Remap SCOANSI line drawing to VT100 line drawing chars
|
|
1754 // for our SCO using customers.
|
|
1755 if (terminalID.equals("scoansi") || terminalID.equals("ansi")) {
|
|
1756 for (int i = 0; i < scoansi_acs.length(); i += 2) {
|
|
1757 if (c == scoansi_acs.charAt(i)) {
|
|
1758 c = scoansi_acs.charAt(i + 1);
|
|
1759 break;
|
|
1760 }
|
|
1761 }
|
|
1762 }
|
|
1763
|
|
1764 if (c >= '\u005f' && c <= '\u007e') {
|
|
1765 c = DECSPECIAL[(short) c - 0x5f];
|
|
1766 mapped = true;
|
|
1767 }
|
|
1768
|
|
1769 break;
|
|
1770
|
|
1771 case '<': // 'user preferred' is currently 'ISO Latin-1 suppl
|
|
1772 c = (char)((c & 0x7f) | 0x80);
|
|
1773 mapped = true;
|
|
1774 break;
|
|
1775
|
|
1776 case 'A':
|
|
1777 case 'B': // Latin-1 , ASCII -> fall through
|
|
1778 mapped = true;
|
|
1779 break;
|
|
1780
|
|
1781 default:
|
|
1782 debug("Unsupported GL mapping: " + gx[thisgl]);
|
|
1783 break;
|
|
1784 }
|
|
1785 }
|
|
1786
|
|
1787 if (!mapped && (c >= '\u0080' && c <= '\u00ff')) {
|
|
1788 switch (gx[gr]) {
|
|
1789 case '0':
|
|
1790 if (c >= '\u00df' && c <= '\u00fe') {
|
|
1791 c = DECSPECIAL[c - '\u00df'];
|
|
1792 mapped = true;
|
|
1793 }
|
|
1794
|
|
1795 break;
|
|
1796
|
|
1797 case '<':
|
|
1798 case 'A':
|
|
1799 case 'B':
|
|
1800 mapped = true;
|
|
1801 break;
|
|
1802
|
|
1803 default:
|
|
1804 debug("Unsupported GR mapping: " + gx[gr]);
|
|
1805 break;
|
|
1806 }
|
|
1807 }
|
|
1808 }
|
|
1809
|
|
1810 if (!mapped && useibmcharset)
|
|
1811 c = map_cp850_unicode(c);
|
|
1812
|
|
1813 /*if(true || (statusmode == 0)) { */
|
|
1814 if (isWide) {
|
|
1815 if (C >= columns - 1) {
|
|
1816 if (wraparound) {
|
|
1817 int bot = rows;
|
|
1818
|
|
1819 // If we're in the scroll region, check against the bottom margin
|
|
1820 if (R <= getBottomMargin() && R >= getTopMargin())
|
|
1821 bot = getBottomMargin() + 1;
|
|
1822
|
|
1823 if (R < bot - 1)
|
|
1824 R++;
|
|
1825 else {
|
|
1826 if (debug > 3) debug("scrolling due to wrap at " + R);
|
|
1827
|
|
1828 insertLine(R, 1, SCROLL_UP);
|
|
1829 }
|
|
1830
|
|
1831 C = 0;
|
|
1832 }
|
|
1833 else {
|
|
1834 // cursor stays on last wide character.
|
|
1835 C = columns - 2;
|
|
1836 }
|
|
1837 }
|
|
1838 }
|
|
1839
|
|
1840 if (insertmode == 1) {
|
|
1841 if (isWide) {
|
|
1842 insertChar(C++, R, c, attributes | FULLWIDTH);
|
|
1843 insertChar(C, R, ' ', attributes | FULLWIDTH);
|
|
1844 }
|
|
1845 else
|
|
1846 insertChar(C, R, c, attributes);
|
|
1847 }
|
|
1848 else {
|
|
1849 if (isWide) {
|
|
1850 putChar(C++, R, c, attributes | FULLWIDTH);
|
|
1851 putChar(C, R, ' ', attributes | FULLWIDTH);
|
|
1852 }
|
|
1853 else
|
|
1854 putChar(C, R, c, attributes);
|
|
1855 }
|
|
1856
|
|
1857 /*
|
|
1858 } else {
|
|
1859 if (insertmode==1) {
|
|
1860 insertChar(C, rows, c, attributes);
|
|
1861 } else {
|
|
1862 putChar(C, rows, c, attributes);
|
|
1863 }
|
|
1864 }
|
|
1865 */
|
|
1866 C++;
|
|
1867 break;
|
|
1868 }
|
|
1869 } /* switch(c) */
|
|
1870
|
|
1871 break;
|
|
1872
|
|
1873 case TSTATE_OSC:
|
|
1874 if ((c < 0x20) && (c != ESC)) {// NP - No printing character
|
|
1875 handle_osc(osc);
|
|
1876 term_state = TSTATE_DATA;
|
|
1877 break;
|
|
1878 }
|
|
1879
|
|
1880 //but check for vt102 ESC \
|
|
1881 if (c == '\\' && osc.charAt(osc.length() - 1) == ESC) {
|
|
1882 handle_osc(osc);
|
|
1883 term_state = TSTATE_DATA;
|
|
1884 break;
|
|
1885 }
|
|
1886
|
|
1887 osc = osc + c;
|
|
1888 break;
|
|
1889
|
|
1890 case TSTATE_ESCSPACE:
|
|
1891 term_state = TSTATE_DATA;
|
|
1892
|
|
1893 switch (c) {
|
|
1894 case 'F': /* S7C1T, Disable output of 8-bit controls, use 7-bit */
|
|
1895 output8bit = false;
|
|
1896 break;
|
|
1897
|
|
1898 case 'G': /* S8C1T, Enable output of 8-bit control codes*/
|
|
1899 output8bit = true;
|
|
1900 break;
|
|
1901
|
|
1902 default:
|
|
1903 debug("ESC <space> " + c + " unhandled.");
|
|
1904 }
|
|
1905
|
|
1906 break;
|
|
1907
|
|
1908 case TSTATE_ESC:
|
|
1909 term_state = TSTATE_DATA;
|
|
1910
|
|
1911 switch (c) {
|
|
1912 case ' ':
|
|
1913 term_state = TSTATE_ESCSPACE;
|
|
1914 break;
|
|
1915
|
|
1916 case '#':
|
|
1917 term_state = TSTATE_ESCSQUARE;
|
|
1918 break;
|
|
1919
|
|
1920 case 'c':
|
|
1921 /* Hard terminal reset */
|
|
1922 reset();
|
|
1923 break;
|
|
1924
|
|
1925 case '[':
|
|
1926 DCEvar = 0;
|
|
1927 DCEvars[0] = 0;
|
|
1928 DCEvars[1] = 0;
|
|
1929 DCEvars[2] = 0;
|
|
1930 DCEvars[3] = 0;
|
|
1931 term_state = TSTATE_CSI;
|
|
1932 break;
|
|
1933
|
|
1934 case ']':
|
|
1935 osc = "";
|
|
1936 term_state = TSTATE_OSC;
|
|
1937 break;
|
|
1938
|
|
1939 case 'P':
|
|
1940 dcs = "";
|
|
1941 term_state = TSTATE_DCS;
|
|
1942 break;
|
|
1943
|
|
1944 case 'A': /* CUU */
|
|
1945 R--;
|
|
1946
|
|
1947 if (R < 0) R = 0;
|
|
1948
|
|
1949 break;
|
|
1950
|
|
1951 case 'B': /* CUD */
|
|
1952 R++;
|
|
1953
|
|
1954 if (R >= rows) R = rows - 1;
|
|
1955
|
|
1956 break;
|
|
1957
|
|
1958 case 'C':
|
|
1959 C++;
|
|
1960
|
|
1961 if (C >= columns) C = columns - 1;
|
|
1962
|
|
1963 break;
|
|
1964
|
|
1965 case 'I': // RI
|
|
1966 insertLine(R, 1, SCROLL_DOWN);
|
|
1967 break;
|
|
1968
|
|
1969 case 'E': /* NEL */
|
|
1970 if (R == getBottomMargin() || R == rows - 1)
|
|
1971 insertLine(R, 1, SCROLL_UP);
|
|
1972 else
|
|
1973 R++;
|
|
1974
|
|
1975 C = 0;
|
|
1976
|
|
1977 if (debug > 1)
|
|
1978 debug("ESC E (at " + R + ")");
|
|
1979
|
|
1980 break;
|
|
1981
|
|
1982 case 'D': /* IND */
|
|
1983 if (R == getBottomMargin() || R == rows - 1)
|
|
1984 insertLine(R, 1, SCROLL_UP);
|
|
1985 else
|
|
1986 R++;
|
|
1987
|
|
1988 if (debug > 1)
|
|
1989 debug("ESC D (at " + R + " )");
|
|
1990
|
|
1991 break;
|
|
1992
|
|
1993 case 'J': /* erase to end of screen */
|
|
1994 if (R < rows - 1)
|
|
1995 deleteArea(0, R + 1, columns, rows - R - 1, attributes);
|
|
1996
|
|
1997 if (C < columns - 1)
|
|
1998 deleteArea(C, R, columns - C, 1, attributes);
|
|
1999
|
|
2000 break;
|
|
2001
|
|
2002 case 'K':
|
|
2003 if (C < columns - 1)
|
|
2004 deleteArea(C, R, columns - C, 1, attributes);
|
|
2005
|
|
2006 break;
|
|
2007
|
|
2008 case 'M': // RI
|
|
2009 debug("ESC M : R is " + R + ", tm is " + getTopMargin() + ", bm is " + getBottomMargin());
|
|
2010
|
|
2011 if (R > getTopMargin()) { // just go up 1 line.
|
|
2012 R--;
|
|
2013 }
|
|
2014 else { // scroll down
|
|
2015 insertLine(R, 1, SCROLL_DOWN);
|
|
2016 }
|
|
2017
|
|
2018 /* else do nothing ; */
|
|
2019 if (debug > 2)
|
|
2020 debug("ESC M ");
|
|
2021
|
|
2022 break;
|
|
2023
|
|
2024 case 'H':
|
|
2025 if (debug > 1)
|
|
2026 debug("ESC H at " + C);
|
|
2027
|
|
2028 /* right border probably ...*/
|
|
2029 if (C >= columns)
|
|
2030 C = columns - 1;
|
|
2031
|
|
2032 Tabs[C] = 1;
|
|
2033 break;
|
|
2034
|
|
2035 case 'N': // SS2
|
|
2036 onegl = 2;
|
|
2037 break;
|
|
2038
|
|
2039 case 'O': // SS3
|
|
2040 onegl = 3;
|
|
2041 break;
|
|
2042
|
|
2043 case '=':
|
|
2044
|
|
2045 /*application keypad*/
|
|
2046 if (debug > 0)
|
|
2047 debug("ESC =");
|
|
2048
|
|
2049 keypadmode = true;
|
|
2050 break;
|
|
2051
|
|
2052 case '<': /* vt52 mode off */
|
|
2053 vt52mode = false;
|
|
2054 break;
|
|
2055
|
|
2056 case '>': /*normal keypad*/
|
|
2057 if (debug > 0)
|
|
2058 debug("ESC >");
|
|
2059
|
|
2060 keypadmode = false;
|
|
2061 break;
|
|
2062
|
|
2063 case '7': /* DECSC: save cursor, attributes */
|
|
2064 Sc = C;
|
|
2065 Sr = R;
|
|
2066 Sgl = gl;
|
|
2067 Sgr = gr;
|
|
2068 Sa = attributes;
|
|
2069 Sgx = new char[4];
|
|
2070
|
|
2071 for (int i = 0; i < 4; i++) Sgx[i] = gx[i];
|
|
2072
|
|
2073 if (debug > 1)
|
|
2074 debug("ESC 7");
|
|
2075
|
|
2076 break;
|
|
2077
|
|
2078 case '8': /* DECRC: restore cursor, attributes */
|
|
2079 C = Sc;
|
|
2080 R = Sr;
|
|
2081 gl = Sgl;
|
|
2082 gr = Sgr;
|
|
2083
|
|
2084 if (Sgx != null)
|
|
2085 for (int i = 0; i < 4; i++) gx[i] = Sgx[i];
|
|
2086
|
|
2087 attributes = Sa;
|
|
2088
|
|
2089 if (debug > 1)
|
|
2090 debug("ESC 8");
|
|
2091
|
|
2092 break;
|
|
2093
|
|
2094 case '(': /* Designate G0 Character set (ISO 2022) */
|
|
2095 term_state = TSTATE_SETG0;
|
|
2096 usedcharsets = true;
|
|
2097 break;
|
|
2098
|
|
2099 case ')': /* Designate G1 character set (ISO 2022) */
|
|
2100 term_state = TSTATE_SETG1;
|
|
2101 usedcharsets = true;
|
|
2102 break;
|
|
2103
|
|
2104 case '*': /* Designate G2 Character set (ISO 2022) */
|
|
2105 term_state = TSTATE_SETG2;
|
|
2106 usedcharsets = true;
|
|
2107 break;
|
|
2108
|
|
2109 case '+': /* Designate G3 Character set (ISO 2022) */
|
|
2110 term_state = TSTATE_SETG3;
|
|
2111 usedcharsets = true;
|
|
2112 break;
|
|
2113
|
|
2114 case '~': /* Locking Shift 1, right */
|
|
2115 gr = 1;
|
|
2116 usedcharsets = true;
|
|
2117 break;
|
|
2118
|
|
2119 case 'n': /* Locking Shift 2 */
|
|
2120 gl = 2;
|
|
2121 usedcharsets = true;
|
|
2122 break;
|
|
2123
|
|
2124 case '}': /* Locking Shift 2, right */
|
|
2125 gr = 2;
|
|
2126 usedcharsets = true;
|
|
2127 break;
|
|
2128
|
|
2129 case 'o': /* Locking Shift 3 */
|
|
2130 gl = 3;
|
|
2131 usedcharsets = true;
|
|
2132 break;
|
|
2133
|
|
2134 case '|': /* Locking Shift 3, right */
|
|
2135 gr = 3;
|
|
2136 usedcharsets = true;
|
|
2137 break;
|
|
2138
|
|
2139 case 'Y': /* vt52 cursor address mode , next chars are x,y */
|
|
2140 term_state = TSTATE_VT52Y;
|
|
2141 break;
|
|
2142
|
|
2143 case '_':
|
|
2144 term_state = TSTATE_TITLE;
|
|
2145 break;
|
|
2146
|
|
2147 case '\\':
|
|
2148 // TODO save title
|
|
2149 term_state = TSTATE_DATA;
|
|
2150 break;
|
|
2151
|
|
2152 default:
|
|
2153 debug("ESC unknown letter: " + c + " (" + ((int) c) + ")");
|
|
2154 break;
|
|
2155 }
|
|
2156
|
|
2157 break;
|
|
2158
|
|
2159 case TSTATE_VT52X:
|
|
2160 C = c - 37;
|
|
2161
|
|
2162 if (C < 0)
|
|
2163 C = 0;
|
|
2164 else if (C >= width)
|
|
2165 C = width - 1;
|
|
2166
|
|
2167 term_state = TSTATE_VT52Y;
|
|
2168 break;
|
|
2169
|
|
2170 case TSTATE_VT52Y:
|
|
2171 R = c - 37;
|
|
2172
|
|
2173 if (R < 0)
|
|
2174 R = 0;
|
|
2175 else if (R >= height)
|
|
2176 R = height - 1;
|
|
2177
|
|
2178 term_state = TSTATE_DATA;
|
|
2179 break;
|
|
2180
|
|
2181 case TSTATE_SETG0:
|
|
2182 if (c != '0' && c != 'A' && c != 'B' && c != '<')
|
|
2183 debug("ESC ( " + c + ": G0 char set? (" + ((int) c) + ")");
|
|
2184 else {
|
|
2185 if (debug > 2) debug("ESC ( : G0 char set (" + c + " " + ((int) c) + ")");
|
|
2186
|
|
2187 gx[0] = c;
|
|
2188 }
|
|
2189
|
|
2190 term_state = TSTATE_DATA;
|
|
2191 break;
|
|
2192
|
|
2193 case TSTATE_SETG1:
|
|
2194 if (c != '0' && c != 'A' && c != 'B' && c != '<') {
|
|
2195 debug("ESC ) " + c + " (" + ((int) c) + ") :G1 char set?");
|
|
2196 }
|
|
2197 else {
|
|
2198 if (debug > 2) debug("ESC ) :G1 char set (" + c + " " + ((int) c) + ")");
|
|
2199
|
|
2200 gx[1] = c;
|
|
2201 }
|
|
2202
|
|
2203 term_state = TSTATE_DATA;
|
|
2204 break;
|
|
2205
|
|
2206 case TSTATE_SETG2:
|
|
2207 if (c != '0' && c != 'A' && c != 'B' && c != '<')
|
|
2208 debug("ESC*:G2 char set? (" + ((int) c) + ")");
|
|
2209 else {
|
|
2210 if (debug > 2) debug("ESC*:G2 char set (" + c + " " + ((int) c) + ")");
|
|
2211
|
|
2212 gx[2] = c;
|
|
2213 }
|
|
2214
|
|
2215 term_state = TSTATE_DATA;
|
|
2216 break;
|
|
2217
|
|
2218 case TSTATE_SETG3:
|
|
2219 if (c != '0' && c != 'A' && c != 'B' && c != '<')
|
|
2220 debug("ESC+:G3 char set? (" + ((int) c) + ")");
|
|
2221 else {
|
|
2222 if (debug > 2) debug("ESC+:G3 char set (" + c + " " + ((int) c) + ")");
|
|
2223
|
|
2224 gx[3] = c;
|
|
2225 }
|
|
2226
|
|
2227 term_state = TSTATE_DATA;
|
|
2228 break;
|
|
2229
|
|
2230 case TSTATE_ESCSQUARE:
|
|
2231 switch (c) {
|
|
2232 case '8':
|
|
2233 for (int i = 0; i < columns; i++)
|
|
2234 for (int j = 0; j < rows; j++)
|
|
2235 putChar(i, j, 'E', 0);
|
|
2236
|
|
2237 break;
|
|
2238
|
|
2239 default:
|
|
2240 debug("ESC # " + c + " not supported.");
|
|
2241 break;
|
|
2242 }
|
|
2243
|
|
2244 term_state = TSTATE_DATA;
|
|
2245 break;
|
|
2246
|
|
2247 case TSTATE_DCS:
|
|
2248 if (c == '\\' && dcs.charAt(dcs.length() - 1) == ESC) {
|
|
2249 handle_dcs(dcs);
|
|
2250 term_state = TSTATE_DATA;
|
|
2251 break;
|
|
2252 }
|
|
2253
|
|
2254 dcs = dcs + c;
|
|
2255 break;
|
|
2256
|
|
2257 case TSTATE_DCEQ:
|
|
2258 term_state = TSTATE_DATA;
|
|
2259
|
|
2260 switch (c) {
|
|
2261 case '0':
|
|
2262 case '1':
|
|
2263 case '2':
|
|
2264 case '3':
|
|
2265 case '4':
|
|
2266 case '5':
|
|
2267 case '6':
|
|
2268 case '7':
|
|
2269 case '8':
|
|
2270 case '9':
|
|
2271 DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48;
|
|
2272 term_state = TSTATE_DCEQ;
|
|
2273 break;
|
|
2274
|
|
2275 case ';':
|
|
2276 DCEvar++;
|
|
2277 DCEvars[DCEvar] = 0;
|
|
2278 term_state = TSTATE_DCEQ;
|
|
2279 break;
|
|
2280
|
|
2281 case 's': // XTERM_SAVE missing!
|
|
2282 if (true || debug > 1)
|
|
2283 debug("ESC [ ? " + DCEvars[0] + " s unimplemented!");
|
|
2284
|
|
2285 break;
|
|
2286
|
|
2287 case 'r': // XTERM_RESTORE
|
|
2288 if (true || debug > 1)
|
|
2289 debug("ESC [ ? " + DCEvars[0] + " r");
|
|
2290
|
|
2291 /* DEC Mode reset */
|
|
2292 for (int i = 0; i <= DCEvar; i++) {
|
|
2293 switch (DCEvars[i]) {
|
|
2294 case 3: /* 80 columns*/
|
|
2295 setScreenSize(80, height, true);
|
|
2296 break;
|
|
2297
|
|
2298 case 4: /* scrolling mode, smooth */
|
|
2299 break;
|
|
2300
|
|
2301 case 5: /* light background */
|
|
2302 break;
|
|
2303
|
|
2304 case 6: /* DECOM (Origin Mode) move inside margins. */
|
|
2305 moveoutsidemargins = true;
|
|
2306 break;
|
|
2307
|
|
2308 case 7: /* DECAWM: Autowrap Mode */
|
|
2309 wraparound = false;
|
|
2310 break;
|
|
2311
|
|
2312 case 12:/* local echo off */
|
|
2313 break;
|
|
2314
|
|
2315 case 9: /* X10 mouse */
|
|
2316 case 1000: /* xterm style mouse report on */
|
|
2317 case 1001:
|
|
2318 case 1002:
|
|
2319 case 1003:
|
|
2320 mouserpt = DCEvars[i];
|
|
2321 break;
|
|
2322
|
|
2323 default:
|
|
2324 debug("ESC [ ? " + DCEvars[0] + " r, unimplemented!");
|
|
2325 }
|
|
2326 }
|
|
2327
|
|
2328 break;
|
|
2329
|
|
2330 case 'h': // DECSET
|
|
2331 if (debug > 0)
|
|
2332 debug("ESC [ ? " + DCEvars[0] + " h");
|
|
2333
|
|
2334 /* DEC Mode set */
|
|
2335 for (int i = 0; i <= DCEvar; i++) {
|
|
2336 switch (DCEvars[i]) {
|
|
2337 case 1: /* Application cursor keys */
|
|
2338 KeyUp[0] = "\u001bOA";
|
|
2339 KeyDown[0] = "\u001bOB";
|
|
2340 KeyRight[0] = "\u001bOC";
|
|
2341 KeyLeft[0] = "\u001bOD";
|
|
2342 break;
|
|
2343
|
|
2344 case 2: /* DECANM */
|
|
2345 vt52mode = false;
|
|
2346 break;
|
|
2347
|
|
2348 case 3: /* 132 columns*/
|
|
2349 setScreenSize(132, height, true);
|
|
2350 break;
|
|
2351
|
|
2352 case 6: /* DECOM: move inside margins. */
|
|
2353 moveoutsidemargins = false;
|
|
2354 break;
|
|
2355
|
|
2356 case 7: /* DECAWM: Autowrap Mode */
|
|
2357 wraparound = true;
|
|
2358 break;
|
|
2359
|
|
2360 case 25: /* turn cursor on */
|
|
2361 showCursor(true);
|
|
2362 break;
|
|
2363
|
|
2364 case 9: /* X10 mouse */
|
|
2365 case 1000: /* xterm style mouse report on */
|
|
2366 case 1001:
|
|
2367 case 1002:
|
|
2368 case 1003:
|
|
2369 mouserpt = DCEvars[i];
|
|
2370 break;
|
|
2371
|
|
2372 /* unimplemented stuff, fall through */
|
|
2373 /* 4 - scrolling mode, smooth */
|
|
2374 /* 5 - light background */
|
|
2375 /* 12 - local echo off */
|
|
2376 /* 18 - DECPFF - Printer Form Feed Mode -> On */
|
|
2377 /* 19 - DECPEX - Printer Extent Mode -> Screen */
|
|
2378 default:
|
|
2379 debug("ESC [ ? " + DCEvars[0] + " h, unsupported.");
|
|
2380 break;
|
|
2381 }
|
|
2382 }
|
|
2383
|
|
2384 break;
|
|
2385
|
|
2386 case 'i': // DEC Printer Control, autoprint, echo screenchars to printer
|
|
2387
|
|
2388 // This is different to CSI i!
|
|
2389 // Also: "Autoprint prints a final display line only when the
|
|
2390 // cursor is moved off the line by an autowrap or LF, FF, or
|
|
2391 // VT (otherwise do not print the line)."
|
|
2392 switch (DCEvars[0]) {
|
|
2393 case 1:
|
|
2394 if (debug > 1)
|
|
2395 debug("CSI ? 1 i : Print line containing cursor");
|
|
2396
|
|
2397 break;
|
|
2398
|
|
2399 case 4:
|
|
2400 if (debug > 1)
|
|
2401 debug("CSI ? 4 i : Start passthrough printing");
|
|
2402
|
|
2403 break;
|
|
2404
|
|
2405 case 5:
|
|
2406 if (debug > 1)
|
|
2407 debug("CSI ? 4 i : Stop passthrough printing");
|
|
2408
|
|
2409 break;
|
|
2410 }
|
|
2411
|
|
2412 break;
|
|
2413
|
|
2414 case 'l': //DECRST
|
|
2415
|
|
2416 /* DEC Mode reset */
|
|
2417 if (debug > 0)
|
|
2418 debug("ESC [ ? " + DCEvars[0] + " l");
|
|
2419
|
|
2420 for (int i = 0; i <= DCEvar; i++) {
|
|
2421 switch (DCEvars[i]) {
|
|
2422 case 1: /* Application cursor keys */
|
|
2423 KeyUp[0] = "\u001b[A";
|
|
2424 KeyDown[0] = "\u001b[B";
|
|
2425 KeyRight[0] = "\u001b[C";
|
|
2426 KeyLeft[0] = "\u001b[D";
|
|
2427 break;
|
|
2428
|
|
2429 case 2: /* DECANM */
|
|
2430 vt52mode = true;
|
|
2431 break;
|
|
2432
|
|
2433 case 3: /* 80 columns*/
|
|
2434 setScreenSize(80, height, true);
|
|
2435 break;
|
|
2436
|
|
2437 case 6: /* DECOM: move outside margins. */
|
|
2438 moveoutsidemargins = true;
|
|
2439 break;
|
|
2440
|
|
2441 case 7: /* DECAWM: Autowrap Mode OFF */
|
|
2442 wraparound = false;
|
|
2443 break;
|
|
2444
|
|
2445 case 25: /* turn cursor off */
|
|
2446 showCursor(false);
|
|
2447 break;
|
|
2448
|
|
2449 /* Unimplemented stuff: */
|
|
2450 /* 4 - scrolling mode, jump */
|
|
2451 /* 5 - dark background */
|
|
2452 /* 7 - DECAWM - no wrap around mode */
|
|
2453 /* 12 - local echo on */
|
|
2454 /* 18 - DECPFF - Printer Form Feed Mode -> Off*/
|
|
2455 /* 19 - DECPEX - Printer Extent Mode -> Scrolling Region */
|
|
2456 case 9: /* X10 mouse */
|
|
2457 case 1000: /* xterm style mouse report OFF */
|
|
2458 case 1001:
|
|
2459 case 1002:
|
|
2460 case 1003:
|
|
2461 mouserpt = 0;
|
|
2462 break;
|
|
2463
|
|
2464 default:
|
|
2465 debug("ESC [ ? " + DCEvars[0] + " l, unsupported.");
|
|
2466 break;
|
|
2467 }
|
|
2468 }
|
|
2469
|
|
2470 break;
|
|
2471
|
|
2472 case 'n':
|
|
2473 if (debug > 0)
|
|
2474 debug("ESC [ ? " + DCEvars[0] + " n");
|
|
2475
|
|
2476 switch (DCEvars[0]) {
|
|
2477 case 15:
|
|
2478 /* printer? no printer. */
|
|
2479 write((ESC) + "[?13n", false);
|
|
2480 debug("ESC[5n");
|
|
2481 break;
|
|
2482
|
|
2483 default:
|
|
2484 debug("ESC [ ? " + DCEvars[0] + " n, unsupported.");
|
|
2485 break;
|
|
2486 }
|
|
2487
|
|
2488 break;
|
|
2489
|
|
2490 default:
|
|
2491 debug("ESC [ ? " + DCEvars[0] + " " + c + ", unsupported.");
|
|
2492 break;
|
|
2493 }
|
|
2494
|
|
2495 break;
|
|
2496
|
|
2497 case TSTATE_CSI_EX:
|
|
2498 term_state = TSTATE_DATA;
|
|
2499
|
|
2500 switch (c) {
|
|
2501 case ESC:
|
|
2502 term_state = TSTATE_ESC;
|
|
2503 break;
|
|
2504
|
|
2505 default:
|
|
2506 debug("Unknown character ESC[! character is " + (int) c);
|
|
2507 break;
|
|
2508 }
|
|
2509
|
|
2510 break;
|
|
2511
|
|
2512 case TSTATE_CSI_TICKS:
|
|
2513 term_state = TSTATE_DATA;
|
|
2514
|
|
2515 switch (c) {
|
|
2516 case 'p':
|
|
2517 debug("Conformance level: " + DCEvars[0] + " (unsupported)," + DCEvars[1]);
|
|
2518
|
|
2519 if (DCEvars[0] == 61) {
|
|
2520 output8bit = false;
|
|
2521 break;
|
|
2522 }
|
|
2523
|
|
2524 if (DCEvars[1] == 1) {
|
|
2525 output8bit = false;
|
|
2526 }
|
|
2527 else {
|
|
2528 output8bit = true; /* 0 or 2 */
|
|
2529 }
|
|
2530
|
|
2531 break;
|
|
2532
|
|
2533 default:
|
|
2534 debug("Unknown ESC [... \"" + c);
|
|
2535 break;
|
|
2536 }
|
|
2537
|
|
2538 break;
|
|
2539
|
|
2540 case TSTATE_CSI_EQUAL:
|
|
2541 term_state = TSTATE_DATA;
|
|
2542
|
|
2543 switch (c) {
|
|
2544 case '0':
|
|
2545 case '1':
|
|
2546 case '2':
|
|
2547 case '3':
|
|
2548 case '4':
|
|
2549 case '5':
|
|
2550 case '6':
|
|
2551 case '7':
|
|
2552 case '8':
|
|
2553 case '9':
|
|
2554 DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48;
|
|
2555 term_state = TSTATE_CSI_EQUAL;
|
|
2556 break;
|
|
2557
|
|
2558 case ';':
|
|
2559 DCEvar++;
|
|
2560 DCEvars[DCEvar] = 0;
|
|
2561 term_state = TSTATE_CSI_EQUAL;
|
|
2562 break;
|
|
2563
|
|
2564 case 'F': { /* SCO ANSI foreground */
|
|
2565 int newcolor;
|
|
2566 debug("ESC [ = " + DCEvars[0] + " F");
|
|
2567 attributes &= ~COLOR_FG;
|
|
2568 newcolor = ((DCEvars[0] & 1) << 2) |
|
|
2569 (DCEvars[0] & 2) |
|
|
2570 ((DCEvars[0] & 4) >> 2) ;
|
|
2571 attributes |= (newcolor + 1) << COLOR_FG_SHIFT;
|
|
2572 break;
|
|
2573 }
|
|
2574
|
|
2575 case 'G': { /* SCO ANSI background */
|
|
2576 int newcolor;
|
|
2577 debug("ESC [ = " + DCEvars[0] + " G");
|
|
2578 attributes &= ~COLOR_BG;
|
|
2579 newcolor = ((DCEvars[0] & 1) << 2) |
|
|
2580 (DCEvars[0] & 2) |
|
|
2581 ((DCEvars[0] & 4) >> 2) ;
|
|
2582 attributes |= (newcolor + 1) << COLOR_BG_SHIFT;
|
|
2583 break;
|
|
2584 }
|
|
2585
|
|
2586 default:
|
|
2587 debugStr.append("Unknown ESC [ = ");
|
|
2588
|
|
2589 for (int i = 0; i <= DCEvar; i++) {
|
|
2590 debugStr.append(DCEvars[i])
|
|
2591 .append(',');
|
|
2592 }
|
|
2593
|
|
2594 debugStr.append(c);
|
|
2595 debug(debugStr.toString());
|
|
2596 debugStr.setLength(0);
|
|
2597 break;
|
|
2598 }
|
|
2599
|
|
2600 break;
|
|
2601
|
|
2602 case TSTATE_CSI_DOLLAR:
|
|
2603 term_state = TSTATE_DATA;
|
|
2604
|
|
2605 switch (c) {
|
|
2606 case '}':
|
|
2607 debug("Active Status Display now " + DCEvars[0]);
|
|
2608 statusmode = DCEvars[0];
|
|
2609 break;
|
|
2610
|
|
2611 /* bad documentation?
|
|
2612 case '-':
|
|
2613 debug("Set Status Display now "+DCEvars[0]);
|
|
2614 break;
|
|
2615 */
|
|
2616 case '~':
|
|
2617 debug("Status Line mode now " + DCEvars[0]);
|
|
2618 break;
|
|
2619
|
|
2620 default:
|
|
2621 debug("UNKNOWN Status Display code " + c + ", with Pn=" + DCEvars[0]);
|
|
2622 break;
|
|
2623 }
|
|
2624
|
|
2625 break;
|
|
2626
|
|
2627 case TSTATE_CSI:
|
|
2628 term_state = TSTATE_DATA;
|
|
2629
|
|
2630 switch (c) {
|
|
2631 case '"':
|
|
2632 term_state = TSTATE_CSI_TICKS;
|
|
2633 break;
|
|
2634
|
|
2635 case '$':
|
|
2636 term_state = TSTATE_CSI_DOLLAR;
|
|
2637 break;
|
|
2638
|
|
2639 case '=':
|
|
2640 term_state = TSTATE_CSI_EQUAL;
|
|
2641 break;
|
|
2642
|
|
2643 case '!':
|
|
2644 term_state = TSTATE_CSI_EX;
|
|
2645 break;
|
|
2646
|
|
2647 case '?':
|
|
2648 DCEvar = 0;
|
|
2649 DCEvars[0] = 0;
|
|
2650 term_state = TSTATE_DCEQ;
|
|
2651 break;
|
|
2652
|
|
2653 case '0':
|
|
2654 case '1':
|
|
2655 case '2':
|
|
2656 case '3':
|
|
2657 case '4':
|
|
2658 case '5':
|
|
2659 case '6':
|
|
2660 case '7':
|
|
2661 case '8':
|
|
2662 case '9':
|
|
2663 DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48;
|
|
2664 term_state = TSTATE_CSI;
|
|
2665 break;
|
|
2666
|
|
2667 case ';':
|
|
2668 DCEvar++;
|
|
2669 DCEvars[DCEvar] = 0;
|
|
2670 term_state = TSTATE_CSI;
|
|
2671 break;
|
|
2672
|
|
2673 case 'c':/* send primary device attributes */
|
|
2674 /* send (ESC[?61c) */
|
|
2675 String subcode = "";
|
|
2676
|
|
2677 if (terminalID.equals("vt320")) subcode = "63;";
|
|
2678
|
|
2679 if (terminalID.equals("vt220")) subcode = "62;";
|
|
2680
|
|
2681 if (terminalID.equals("vt100")) subcode = "61;";
|
|
2682
|
|
2683 write((ESC) + "[?" + subcode + "1;2c", false);
|
|
2684
|
|
2685 if (debug > 1)
|
|
2686 debug("ESC [ " + DCEvars[0] + " c");
|
|
2687
|
|
2688 break;
|
|
2689
|
|
2690 case 'q':
|
|
2691 if (debug > 1)
|
|
2692 debug("ESC [ " + DCEvars[0] + " q");
|
|
2693
|
|
2694 break;
|
|
2695
|
|
2696 case 'g':
|
|
2697
|
|
2698 /* used for tabsets */
|
|
2699 switch (DCEvars[0]) {
|
|
2700 case 3:/* clear them */
|
|
2701 Tabs = new byte[width];
|
|
2702 break;
|
|
2703
|
|
2704 case 0:
|
|
2705 Tabs[C] = 0;
|
|
2706 break;
|
|
2707 }
|
|
2708
|
|
2709 if (debug > 1)
|
|
2710 debug("ESC [ " + DCEvars[0] + " g");
|
|
2711
|
|
2712 break;
|
|
2713
|
|
2714 case 'h':
|
|
2715 switch (DCEvars[0]) {
|
|
2716 case 4:
|
|
2717 insertmode = 1;
|
|
2718 break;
|
|
2719
|
|
2720 case 20:
|
|
2721 debug("Setting CRLF to TRUE");
|
|
2722 sendcrlf = true;
|
|
2723 break;
|
|
2724
|
|
2725 default:
|
|
2726 debug("unsupported: ESC [ " + DCEvars[0] + " h");
|
|
2727 break;
|
|
2728 }
|
|
2729
|
|
2730 if (debug > 1)
|
|
2731 debug("ESC [ " + DCEvars[0] + " h");
|
|
2732
|
|
2733 break;
|
|
2734
|
|
2735 case 'i': // Printer Controller mode.
|
|
2736
|
|
2737 // "Transparent printing sends all output, except the CSI 4 i
|
|
2738 // termination string, to the printer and not the screen,
|
|
2739 // uses an 8-bit channel if no parity so NUL and DEL will be
|
|
2740 // seen by the printer and by the termination recognizer code,
|
|
2741 // and all translation and character set selections are
|
|
2742 // bypassed."
|
|
2743 switch (DCEvars[0]) {
|
|
2744 case 0:
|
|
2745 if (debug > 1)
|
|
2746 debug("CSI 0 i: Print Screen, not implemented.");
|
|
2747
|
|
2748 break;
|
|
2749
|
|
2750 case 4:
|
|
2751 if (debug > 1)
|
|
2752 debug("CSI 4 i: Enable Transparent Printing, not implemented.");
|
|
2753
|
|
2754 break;
|
|
2755
|
|
2756 case 5:
|
|
2757 if (debug > 1)
|
|
2758 debug("CSI 4/5 i: Disable Transparent Printing, not implemented.");
|
|
2759
|
|
2760 break;
|
|
2761
|
|
2762 default:
|
|
2763 debug("ESC [ " + DCEvars[0] + " i, unimplemented!");
|
|
2764 }
|
|
2765
|
|
2766 break;
|
|
2767
|
|
2768 case 'l':
|
|
2769 switch (DCEvars[0]) {
|
|
2770 case 4:
|
|
2771 insertmode = 0;
|
|
2772 break;
|
|
2773
|
|
2774 case 20:
|
|
2775 debug("Setting CRLF to FALSE");
|
|
2776 sendcrlf = false;
|
|
2777 break;
|
|
2778
|
|
2779 default:
|
|
2780 debug("ESC [ " + DCEvars[0] + " l, unimplemented!");
|
|
2781 break;
|
|
2782 }
|
|
2783
|
|
2784 break;
|
|
2785
|
|
2786 case 'A': { // CUU
|
|
2787 int limit;
|
|
2788
|
|
2789 /* FIXME: xterm only cares about 0 and topmargin */
|
|
2790 if (R >= getTopMargin()) {
|
|
2791 limit = getTopMargin();
|
|
2792 }
|
|
2793 else
|
|
2794 limit = 0;
|
|
2795
|
|
2796 if (DCEvars[0] == 0)
|
|
2797 R--;
|
|
2798 else
|
|
2799 R -= DCEvars[0];
|
|
2800
|
|
2801 if (R < limit)
|
|
2802 R = limit;
|
|
2803
|
|
2804 if (debug > 1)
|
|
2805 debug("ESC [ " + DCEvars[0] + " A");
|
|
2806
|
|
2807 break;
|
|
2808 }
|
|
2809
|
|
2810 case 'B': // CUD
|
|
2811 /* cursor down n (1) times */
|
|
2812 {
|
|
2813 int limit;
|
|
2814
|
|
2815 if (R <= getBottomMargin()) {
|
|
2816 limit = getBottomMargin();
|
|
2817 }
|
|
2818 else
|
|
2819 limit = rows - 1;
|
|
2820
|
|
2821 if (DCEvars[0] == 0)
|
|
2822 R++;
|
|
2823 else
|
|
2824 R += DCEvars[0];
|
|
2825
|
|
2826 if (R > limit)
|
|
2827 R = limit;
|
|
2828 else {
|
|
2829 if (debug > 2) debug("Not limited.");
|
|
2830 }
|
|
2831
|
|
2832 if (debug > 2) debug("to: " + R);
|
|
2833
|
|
2834 if (debug > 1)
|
|
2835 debug("ESC [ " + DCEvars[0] + " B (at C=" + C + ")");
|
|
2836
|
|
2837 break;
|
|
2838 }
|
|
2839
|
|
2840 case 'C':
|
|
2841 if (DCEvars[0] == 0)
|
|
2842 DCEvars[0] = 1;
|
|
2843
|
|
2844 while (DCEvars[0]-- > 0) {
|
|
2845 C++;
|
|
2846 }
|
|
2847
|
|
2848 if (C >= columns)
|
|
2849 C = columns - 1;
|
|
2850
|
|
2851 if (debug > 1)
|
|
2852 debug("ESC [ " + DCEvars[0] + " C");
|
|
2853
|
|
2854 break;
|
|
2855
|
|
2856 case 'd': // CVA
|
|
2857 R = DCEvars[0] - 1;
|
|
2858
|
|
2859 if (R < 0)
|
|
2860 R = 0;
|
|
2861 else if (R >= height)
|
|
2862 R = height - 1;
|
|
2863
|
|
2864 if (debug > 1)
|
|
2865 debug("ESC [ " + DCEvars[0] + " d");
|
|
2866
|
|
2867 break;
|
|
2868
|
|
2869 case 'D':
|
|
2870 if (DCEvars[0] == 0)
|
|
2871 DCEvars[0] = 1;
|
|
2872
|
|
2873 while (DCEvars[0]-- > 0) {
|
|
2874 C--;
|
|
2875 }
|
|
2876
|
|
2877 if (C < 0) C = 0;
|
|
2878
|
|
2879 if (debug > 1)
|
|
2880 debug("ESC [ " + DCEvars[0] + " D");
|
|
2881
|
|
2882 break;
|
|
2883
|
|
2884 case 'r': // DECSTBM
|
|
2885 if (DCEvar > 0) { // Ray: Any argument is optional
|
|
2886 R = DCEvars[1] - 1;
|
|
2887
|
|
2888 if (R < 0)
|
|
2889 R = rows - 1;
|
|
2890 else if (R >= rows) {
|
|
2891 R = rows - 1;
|
|
2892 }
|
|
2893 }
|
|
2894 else
|
|
2895 R = rows - 1;
|
|
2896
|
|
2897 int bot = R;
|
|
2898
|
|
2899 if (R >= DCEvars[0]) {
|
|
2900 R = DCEvars[0] - 1;
|
|
2901
|
|
2902 if (R < 0)
|
|
2903 R = 0;
|
|
2904 }
|
|
2905
|
|
2906 setMargins(R, bot);
|
|
2907 _SetCursor(0, 0);
|
|
2908
|
|
2909 if (debug > 1)
|
|
2910 debug("ESC [" + DCEvars[0] + " ; " + DCEvars[1] + " r");
|
|
2911
|
|
2912 break;
|
|
2913
|
|
2914 case 'G': /* CUP / cursor absolute column */
|
|
2915 C = DCEvars[0];
|
|
2916
|
|
2917 if (C < 0)
|
|
2918 C = 0;
|
|
2919 else if (C >= width)
|
|
2920 C = width - 1;
|
|
2921
|
|
2922 if (debug > 1) debug("ESC [ " + DCEvars[0] + " G");
|
|
2923
|
|
2924 break;
|
|
2925
|
|
2926 case 'H': /* CUP / cursor position */
|
|
2927 /* gets 2 arguments */
|
|
2928 _SetCursor(DCEvars[0] - 1, DCEvars[1] - 1);
|
|
2929
|
|
2930 if (debug > 2) {
|
|
2931 debug("ESC [ " + DCEvars[0] + ";" + DCEvars[1] + " H, moveoutsidemargins " + moveoutsidemargins);
|
|
2932 debug(" -> R now " + R + ", C now " + C);
|
|
2933 }
|
|
2934
|
|
2935 break;
|
|
2936
|
|
2937 case 'f': /* move cursor 2 */
|
|
2938 /* gets 2 arguments */
|
|
2939 R = DCEvars[0] - 1;
|
|
2940 C = DCEvars[1] - 1;
|
|
2941
|
|
2942 if (C < 0)
|
|
2943 C = 0;
|
|
2944 else if (C >= width)
|
|
2945 C = width - 1;
|
|
2946
|
|
2947 if (R < 0)
|
|
2948 R = 0;
|
|
2949 else if (R >= height)
|
|
2950 R = height - 1;
|
|
2951
|
|
2952 if (debug > 2)
|
|
2953 debug("ESC [ " + DCEvars[0] + ";" + DCEvars[1] + " f");
|
|
2954
|
|
2955 break;
|
|
2956
|
|
2957 case 'S': /* ind aka 'scroll forward' */
|
|
2958 if (DCEvars[0] == 0)
|
|
2959 insertLine(getBottomMargin(), SCROLL_UP);
|
|
2960 else
|
|
2961 insertLine(getBottomMargin(), DCEvars[0], SCROLL_UP);
|
|
2962
|
|
2963 break;
|
|
2964
|
|
2965 case 'L':
|
|
2966
|
|
2967 /* insert n lines */
|
|
2968 if (DCEvars[0] == 0)
|
|
2969 insertLine(R, SCROLL_DOWN);
|
|
2970 else
|
|
2971 insertLine(R, DCEvars[0], SCROLL_DOWN);
|
|
2972
|
|
2973 if (debug > 1)
|
|
2974 debug("ESC [ " + DCEvars[0] + "" + (c) + " (at R " + R + ")");
|
|
2975
|
|
2976 break;
|
|
2977
|
|
2978 case 'T': /* 'ri' aka scroll backward */
|
|
2979 if (DCEvars[0] == 0)
|
|
2980 insertLine(getTopMargin(), SCROLL_DOWN);
|
|
2981 else
|
|
2982 insertLine(getTopMargin(), DCEvars[0], SCROLL_DOWN);
|
|
2983
|
|
2984 break;
|
|
2985
|
|
2986 case 'M':
|
|
2987 if (debug > 1)
|
|
2988 debug("ESC [ " + DCEvars[0] + "" + (c) + " at R=" + R);
|
|
2989
|
|
2990 if (DCEvars[0] == 0)
|
|
2991 deleteLine(R);
|
|
2992 else
|
|
2993 for (int i = 0; i < DCEvars[0]; i++)
|
|
2994 deleteLine(R);
|
|
2995
|
|
2996 break;
|
|
2997
|
|
2998 case 'K':
|
|
2999 if (debug > 1)
|
|
3000 debug("ESC [ " + DCEvars[0] + " K");
|
|
3001
|
|
3002 /* clear in line */
|
|
3003 switch (DCEvars[0]) {
|
|
3004 case 6: /* 97801 uses ESC[6K for delete to end of line */
|
|
3005 case 0:/*clear to right*/
|
|
3006 if (C < columns - 1)
|
|
3007 deleteArea(C, R, columns - C, 1, attributes);
|
|
3008
|
|
3009 break;
|
|
3010
|
|
3011 case 1:/*clear to the left, including this */
|
|
3012 if (C > 0)
|
|
3013 deleteArea(0, R, C + 1, 1, attributes);
|
|
3014
|
|
3015 break;
|
|
3016
|
|
3017 case 2:/*clear whole line */
|
|
3018 deleteArea(0, R, columns, 1, attributes);
|
|
3019 break;
|
|
3020 }
|
|
3021
|
|
3022 break;
|
|
3023
|
|
3024 case 'J':
|
|
3025
|
|
3026 /* clear below current line */
|
|
3027 switch (DCEvars[0]) {
|
|
3028 case 0:
|
|
3029 if (R < rows - 1)
|
|
3030 deleteArea(0, R + 1, columns, rows - R - 1, attributes);
|
|
3031
|
|
3032 if (C < columns - 1)
|
|
3033 deleteArea(C, R, columns - C, 1, attributes);
|
|
3034
|
|
3035 break;
|
|
3036
|
|
3037 case 1:
|
|
3038 if (R > 0)
|
|
3039 deleteArea(0, 0, columns, R, attributes);
|
|
3040
|
|
3041 if (C > 0)
|
|
3042 deleteArea(0, R, C + 1, 1, attributes); // include up to and including current
|
|
3043
|
|
3044 break;
|
|
3045
|
|
3046 case 2:
|
|
3047 deleteArea(0, 0, columns, rows, attributes);
|
|
3048 break;
|
|
3049 }
|
|
3050
|
|
3051 if (debug > 1)
|
|
3052 debug("ESC [ " + DCEvars[0] + " J");
|
|
3053
|
|
3054 break;
|
|
3055
|
|
3056 case '@':
|
|
3057 if (DCEvars[0] == 0) DCEvars[0] = 1;
|
|
3058
|
|
3059 if (debug > 1)
|
|
3060 debug("ESC [ " + DCEvars[0] + " @");
|
|
3061
|
|
3062 for (int i = 0; i < DCEvars[0]; i++)
|
|
3063 insertChar(C, R, ' ', attributes);
|
|
3064
|
|
3065 break;
|
|
3066
|
|
3067 case 'X': {
|
|
3068 int toerase = DCEvars[0];
|
|
3069
|
|
3070 if (debug > 1)
|
|
3071 debug("ESC [ " + DCEvars[0] + " X, C=" + C + ",R=" + R);
|
|
3072
|
|
3073 if (toerase == 0)
|
|
3074 toerase = 1;
|
|
3075
|
|
3076 if (toerase + C > columns)
|
|
3077 toerase = columns - C;
|
|
3078
|
|
3079 deleteArea(C, R, toerase, 1, attributes);
|
|
3080 // does not change cursor position
|
|
3081 break;
|
|
3082 }
|
|
3083
|
|
3084 case 'P':
|
|
3085 if (debug > 1)
|
|
3086 debug("ESC [ " + DCEvars[0] + " P, C=" + C + ",R=" + R);
|
|
3087
|
|
3088 if (DCEvars[0] == 0) DCEvars[0] = 1;
|
|
3089
|
|
3090 for (int i = 0; i < DCEvars[0]; i++)
|
|
3091 deleteChar(C, R);
|
|
3092
|
|
3093 break;
|
|
3094
|
|
3095 case 'n':
|
|
3096 switch (DCEvars[0]) {
|
|
3097 case 5: /* malfunction? No malfunction. */
|
|
3098 writeSpecial((ESC) + "[0n");
|
|
3099
|
|
3100 if (debug > 1)
|
|
3101 debug("ESC[5n");
|
|
3102
|
|
3103 break;
|
|
3104
|
|
3105 case 6:
|
|
3106 // DO NOT offset R and C by 1! (checked against /usr/X11R6/bin/resize
|
|
3107 // FIXME check again.
|
|
3108 // FIXME: but vttest thinks different???
|
|
3109 writeSpecial((ESC) + "[" + R + ";" + C + "R");
|
|
3110
|
|
3111 if (debug > 1)
|
|
3112 debug("ESC[6n");
|
|
3113
|
|
3114 break;
|
|
3115
|
|
3116 default:
|
|
3117 if (debug > 0)
|
|
3118 debug("ESC [ " + DCEvars[0] + " n??");
|
|
3119
|
|
3120 break;
|
|
3121 }
|
|
3122
|
|
3123 break;
|
|
3124
|
|
3125 case 's': /* DECSC - save cursor */
|
|
3126 Sc = C;
|
|
3127 Sr = R;
|
|
3128 Sa = attributes;
|
|
3129
|
|
3130 if (debug > 3)
|
|
3131 debug("ESC[s");
|
|
3132
|
|
3133 break;
|
|
3134
|
|
3135 case 'u': /* DECRC - restore cursor */
|
|
3136 C = Sc;
|
|
3137 R = Sr;
|
|
3138 attributes = Sa;
|
|
3139
|
|
3140 if (debug > 3)
|
|
3141 debug("ESC[u");
|
|
3142
|
|
3143 break;
|
|
3144
|
|
3145 case 'm': /* attributes as color, bold , blink,*/
|
|
3146 if (debug > 3)
|
|
3147 debug("ESC [ ");
|
|
3148
|
|
3149 if (DCEvar == 0 && DCEvars[0] == 0)
|
|
3150 attributes = 0;
|
|
3151
|
|
3152 for (int i = 0; i <= DCEvar; i++) {
|
|
3153 switch (DCEvars[i]) {
|
|
3154 case 0:
|
|
3155 if (DCEvar > 0) {
|
|
3156 if (terminalID.equals("scoansi")) {
|
|
3157 attributes &= COLOR; /* Keeps color. Strange but true. */
|
|
3158 }
|
|
3159 else {
|
|
3160 attributes = 0;
|
|
3161 }
|
|
3162 }
|
|
3163
|
|
3164 break;
|
|
3165
|
|
3166 case 1:
|
|
3167 attributes |= BOLD;
|
|
3168 attributes &= ~LOW;
|
|
3169 break;
|
|
3170
|
|
3171 case 2:
|
|
3172
|
|
3173 /* SCO color hack mode */
|
|
3174 if (terminalID.equals("scoansi") && ((DCEvar - i) >= 2)) {
|
|
3175 int ncolor;
|
|
3176 attributes &= ~(COLOR | BOLD);
|
|
3177 ncolor = DCEvars[i + 1];
|
|
3178
|
|
3179 if ((ncolor & 8) == 8)
|
|
3180 attributes |= BOLD;
|
|
3181
|
|
3182 ncolor = ((ncolor & 1) << 2) | (ncolor & 2) | ((ncolor & 4) >> 2);
|
|
3183 attributes |= ((ncolor) + 1) << COLOR_FG_SHIFT;
|
|
3184 ncolor = DCEvars[i + 2];
|
|
3185 ncolor = ((ncolor & 1) << 2) | (ncolor & 2) | ((ncolor & 4) >> 2);
|
|
3186 attributes |= ((ncolor) + 1) << COLOR_BG_SHIFT;
|
|
3187 i += 2;
|
|
3188 }
|
|
3189 else {
|
|
3190 attributes |= LOW;
|
|
3191 }
|
|
3192
|
|
3193 break;
|
|
3194
|
|
3195 case 3: /* italics */
|
|
3196 attributes |= INVERT;
|
|
3197 break;
|
|
3198
|
|
3199 case 4:
|
|
3200 attributes |= UNDERLINE;
|
|
3201 break;
|
|
3202
|
|
3203 case 7:
|
|
3204 attributes |= INVERT;
|
|
3205 break;
|
|
3206
|
|
3207 case 8:
|
|
3208 attributes |= INVISIBLE;
|
|
3209 break;
|
|
3210
|
|
3211 case 5: /* blink on */
|
|
3212 break;
|
|
3213
|
|
3214 /* 10 - ANSI X3.64-1979, select primary font, don't display control
|
|
3215 * chars, don't set bit 8 on output */
|
|
3216 case 10:
|
|
3217 gl = 0;
|
|
3218 usedcharsets = true;
|
|
3219 break;
|
|
3220
|
|
3221 /* 11 - ANSI X3.64-1979, select second alt. font, display control
|
|
3222 * chars, set bit 8 on output */
|
|
3223 case 11: /* SMACS , as */
|
|
3224 case 12:
|
|
3225 gl = 1;
|
|
3226 usedcharsets = true;
|
|
3227 break;
|
|
3228
|
|
3229 case 21: /* normal intensity */
|
|
3230 attributes &= ~(LOW | BOLD);
|
|
3231 break;
|
|
3232
|
|
3233 case 23: /* italics off */
|
|
3234 attributes &= ~INVERT;
|
|
3235 break;
|
|
3236
|
|
3237 case 25: /* blinking off */
|
|
3238 break;
|
|
3239
|
|
3240 case 27:
|
|
3241 attributes &= ~INVERT;
|
|
3242 break;
|
|
3243
|
|
3244 case 28:
|
|
3245 attributes &= ~INVISIBLE;
|
|
3246 break;
|
|
3247
|
|
3248 case 24:
|
|
3249 attributes &= ~UNDERLINE;
|
|
3250 break;
|
|
3251
|
|
3252 case 22:
|
|
3253 attributes &= ~BOLD;
|
|
3254 break;
|
|
3255
|
|
3256 case 30:
|
|
3257 case 31:
|
|
3258 case 32:
|
|
3259 case 33:
|
|
3260 case 34:
|
|
3261 case 35:
|
|
3262 case 36:
|
|
3263 case 37:
|
|
3264 attributes &= ~COLOR_FG;
|
|
3265 attributes |= ((DCEvars[i] - 30) + 1) << COLOR_FG_SHIFT;
|
|
3266 break;
|
|
3267
|
|
3268 case 38:
|
|
3269 if (DCEvars[i + 1] == 5) {
|
|
3270 attributes &= ~COLOR_FG;
|
|
3271 attributes |= ((DCEvars[i + 2]) + 1) << COLOR_FG_SHIFT;
|
|
3272 i += 2;
|
|
3273 }
|
|
3274
|
|
3275 break;
|
|
3276
|
|
3277 case 39:
|
|
3278 attributes &= ~COLOR_FG;
|
|
3279 break;
|
|
3280
|
|
3281 case 40:
|
|
3282 case 41:
|
|
3283 case 42:
|
|
3284 case 43:
|
|
3285 case 44:
|
|
3286 case 45:
|
|
3287 case 46:
|
|
3288 case 47:
|
|
3289 attributes &= ~COLOR_BG;
|
|
3290 attributes |= ((DCEvars[i] - 40) + 1) << COLOR_BG_SHIFT;
|
|
3291 break;
|
|
3292
|
|
3293 case 48:
|
|
3294 if (DCEvars[i + 1] == 5) {
|
|
3295 attributes &= ~COLOR_BG;
|
|
3296 attributes |= (DCEvars[i + 2] + 1) << COLOR_BG_SHIFT;
|
|
3297 i += 2;
|
|
3298 }
|
|
3299
|
|
3300 break;
|
|
3301
|
|
3302 case 49:
|
|
3303 attributes &= ~COLOR_BG;
|
|
3304 break;
|
|
3305
|
|
3306 case 90:
|
|
3307 case 91:
|
|
3308 case 92:
|
|
3309 case 93:
|
|
3310 case 94:
|
|
3311 case 95:
|
|
3312 case 96:
|
|
3313 case 97:
|
|
3314 attributes &= ~COLOR_FG;
|
|
3315 attributes |= ((DCEvars[i] - 82) + 1) << COLOR_FG_SHIFT;
|
|
3316 break;
|
|
3317
|
|
3318 case 100:
|
|
3319 case 101:
|
|
3320 case 102:
|
|
3321 case 103:
|
|
3322 case 104:
|
|
3323 case 105:
|
|
3324 case 106:
|
|
3325 case 107:
|
|
3326 attributes &= ~COLOR_BG;
|
|
3327 attributes |= ((DCEvars[i] - 92) + 1) << COLOR_BG_SHIFT;
|
|
3328 break;
|
|
3329
|
|
3330 default:
|
|
3331 debugStr.append("ESC [ ")
|
|
3332 .append(DCEvars[i])
|
|
3333 .append(" m unknown...");
|
|
3334 debug(debugStr.toString());
|
|
3335 debugStr.setLength(0);
|
|
3336 break;
|
|
3337 }
|
|
3338
|
|
3339 if (debug > 3) {
|
|
3340 debugStr.append(DCEvars[i])
|
|
3341 .append(';');
|
|
3342 debug(debugStr.toString());
|
|
3343 debugStr.setLength(0);
|
|
3344 }
|
|
3345 }
|
|
3346
|
|
3347 if (debug > 3) {
|
|
3348 debugStr.append(" (attributes = ")
|
|
3349 .append(attributes)
|
|
3350 .append(")m");
|
|
3351 debug(debugStr.toString());
|
|
3352 debugStr.setLength(0);
|
|
3353 }
|
|
3354
|
|
3355 break;
|
|
3356
|
|
3357 default:
|
|
3358 debugStr.append("ESC [ unknown letter: ")
|
|
3359 .append(c)
|
|
3360 .append(" (")
|
|
3361 .append((int)c)
|
|
3362 .append(')');
|
|
3363 debug(debugStr.toString());
|
|
3364 debugStr.setLength(0);
|
|
3365 break;
|
|
3366 }
|
|
3367
|
|
3368 break;
|
|
3369
|
|
3370 case TSTATE_TITLE:
|
|
3371 switch (c) {
|
|
3372 case ESC:
|
|
3373 term_state = TSTATE_ESC;
|
|
3374 break;
|
|
3375
|
|
3376 default:
|
|
3377 // TODO save title
|
|
3378 break;
|
|
3379 }
|
|
3380
|
|
3381 break;
|
|
3382
|
|
3383 default:
|
|
3384 term_state = TSTATE_DATA;
|
|
3385 break;
|
|
3386 }
|
|
3387
|
|
3388 setCursorPosition(C, R);
|
|
3389 }
|
|
3390
|
|
3391 /* hard reset the terminal */
|
|
3392 public void reset() {
|
|
3393 gx[0] = 'B';
|
|
3394 gx[1] = 'B';
|
|
3395 gx[2] = 'B';
|
|
3396 gx[3] = 'B';
|
|
3397 gl = 0; // default GL to G0
|
|
3398 gr = 2; // default GR to G2
|
|
3399 onegl = -1; // Single shift override
|
|
3400 /* reset tabs */
|
|
3401 int nw = width;
|
|
3402
|
|
3403 if (nw < 132) nw = 132;
|
|
3404
|
|
3405 Tabs = new byte[nw];
|
|
3406
|
|
3407 for (int i = 0; i < nw; i += 8) {
|
|
3408 Tabs[i] = 1;
|
|
3409 }
|
|
3410
|
|
3411 deleteArea(0, 0, width, height, attributes);
|
|
3412 setMargins(0, height);
|
|
3413 C = R = 0;
|
|
3414 _SetCursor(0, 0);
|
|
3415
|
|
3416 if (display != null)
|
|
3417 display.resetColors();
|
|
3418
|
|
3419 showCursor(true);
|
|
3420 /*FIXME:*/
|
|
3421 term_state = TSTATE_DATA;
|
|
3422 }
|
|
3423 }
|