1 /*
2 * SSHTools - Java SSH2 API
3 *
4 * Copyright (C) 2002-2003 Lee David Painter and Contributors.
5 *
6 * Contributions made by:
7 *
8 * Brett Smith
9 * Richard Pernavas
10 * Erwin Bolwidt
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26 /**
27 * SSHTools - Java SSH API The contents of this package has been derived from
28 * the TelnetD library available from http://sourceforge.net/projects/telnetd
29 * The original license of the source code is as follows: TelnetD library
30 * (embeddable telnet daemon) Copyright (C) 2000 Dieter Wimberger This library
31 * is free software; you can either redistribute it and/or modify it under the
32 * terms of the GNU Lesser General Public License version 2.1,1999 as
33 * published by the Free Software Foundation (see copy received along with the
34 * library), or under the terms of the BSD-style license received along with
35 * this library.
36 */
37 package com.sshtools.daemon.terminal;
38
39
40 /**
41 *
42 *
43 * @author $author$
44 * @version $Revision: 1.11 $
45 */
46 public abstract class BasicTerminal implements Terminal {
47 //Associations
48
49 /** */
50 protected Colorizer myColorizer;
51
52 /**
53 * Creates a new BasicTerminal object.
54 */
55 public BasicTerminal() {
56 myColorizer = Colorizer.getReference();
57 }
58
59 //constructor
60 public int translateControlCharacter(int c) {
61 switch (c) {
62 case DEL:
63 return TerminalIO.DELETE;
64
65 case BS:
66 return TerminalIO.BACKSPACE;
67
68 case HT:
69 return TerminalIO.TABULATOR;
70
71 case ESC:
72 return TerminalIO.ESCAPE;
73
74 case SGR:
75 return TerminalIO.COLORINIT;
76
77 case EOT:
78 return TerminalIO.LOGOUTREQUEST;
79
80 default:
81 return c;
82 }
83 }
84
85 //translateControlCharacter
86 public int translateEscapeSequence(int[] buffer) {
87 try {
88 if (buffer[0] == LSB) {
89 switch (buffer[1]) {
90 case A:
91 return TerminalIO.UP;
92
93 case B:
94 return TerminalIO.DOWN;
95
96 case C:
97 return TerminalIO.RIGHT;
98
99 case D:
100 return TerminalIO.LEFT;
101
102 default:
103 break;
104 }
105 }
106 } catch (ArrayIndexOutOfBoundsException e) {
107 return TerminalIO.BYTEMISSING;
108 }
109
110 return TerminalIO.UNRECOGNIZED;
111 }
112
113 //translateEscapeSequence
114 public byte[] getCursorMoveSequence(int direction, int times) {
115 byte[] sequence = null;
116
117 if (times == 1) {
118 sequence = new byte[3];
119 } else {
120 sequence = new byte[times * 3];
121 }
122
123 for (int g = 0; g < (times * 3); g++) {
124 sequence[g] = ESC;
125 sequence[g + 1] = LSB;
126
127 switch (direction) {
128 case TerminalIO.UP:
129 sequence[g + 2] = A;
130
131 break;
132
133 case TerminalIO.DOWN:
134 sequence[g + 2] = B;
135
136 break;
137
138 case TerminalIO.RIGHT:
139 sequence[g + 2] = C;
140
141 break;
142
143 case TerminalIO.LEFT:
144 sequence[g + 2] = D;
145
146 break;
147
148 default:
149 break;
150 }
151
152 g = g + 2;
153 }
154
155 return sequence;
156 }
157
158 // getCursorMoveSequence
159 public byte[] getCursorPositioningSequence(int[] pos) {
160 byte[] sequence = null;
161
162 if (pos == TerminalIO.HOME) {
163 sequence = new byte[3];
164 sequence[0] = ESC;
165 sequence[1] = LSB;
166 sequence[2] = H;
167 } else {
168 //first translate integer coords into digits
169 byte[] rowdigits = translateIntToDigitCodes(pos[0]);
170 byte[] columndigits = translateIntToDigitCodes(pos[1]);
171 int offset = 0;
172
173 //now build up the sequence:
174 sequence = new byte[4 + rowdigits.length + columndigits.length];
175 sequence[0] = ESC;
176 sequence[1] = LSB;
177
178 //now copy the digit bytes
179 System.arraycopy(rowdigits, 0, sequence, 2, rowdigits.length);
180
181 //offset is now 2+rowdigits.length
182 offset = 2 + rowdigits.length;
183 sequence[offset] = SEMICOLON;
184 offset++;
185 System.arraycopy(columndigits, 0, sequence, offset,
186 columndigits.length);
187 offset = offset + columndigits.length;
188 sequence[offset] = H;
189 }
190
191 return sequence;
192 }
193
194 //getCursorPositioningSequence
195 public byte[] getEraseSequence(int eraseFunc) {
196 byte[] sequence = null;
197
198 switch (eraseFunc) {
199 case TerminalIO.EEOL:
200 sequence = new byte[3];
201 sequence[0] = ESC;
202 sequence[1] = LSB;
203 sequence[2] = LE;
204
205 break;
206
207 case TerminalIO.EBOL:
208 sequence = new byte[4];
209 sequence[0] = ESC;
210 sequence[1] = LSB;
211 sequence[2] = 49; //Ascii Code of 1
212 sequence[3] = LE;
213
214 break;
215
216 case TerminalIO.EEL:
217 sequence = new byte[4];
218 sequence[0] = ESC;
219 sequence[1] = LSB;
220 sequence[2] = 50; //Ascii Code 2
221 sequence[3] = LE;
222
223 break;
224
225 case TerminalIO.EEOS:
226 sequence = new byte[3];
227 sequence[0] = ESC;
228 sequence[1] = LSB;
229 sequence[2] = SE;
230
231 break;
232
233 case TerminalIO.EBOS:
234 sequence = new byte[4];
235 sequence[0] = ESC;
236 sequence[1] = LSB;
237 sequence[2] = 49; //Ascii Code of 1
238 sequence[3] = SE;
239
240 break;
241
242 case TerminalIO.EES:
243 sequence = new byte[4];
244 sequence[0] = ESC;
245 sequence[1] = LSB;
246 sequence[2] = 50; //Ascii Code of 2
247 sequence[3] = SE;
248
249 break;
250
251 default:
252 break;
253 }
254
255 return sequence;
256 }
257
258 //getEraseSequence
259 public byte[] getSpecialSequence(int function) {
260 byte[] sequence = null;
261
262 switch (function) {
263 case TerminalIO.STORECURSOR:
264 sequence = new byte[2];
265 sequence[0] = ESC;
266 sequence[1] = 55; //Ascii Code of 7
267
268 break;
269
270 case TerminalIO.RESTORECURSOR:
271 sequence = new byte[2];
272 sequence[0] = ESC;
273 sequence[1] = 56; //Ascii Code of 8
274
275 break;
276 }
277
278 return sequence;
279 }
280
281 //getSpecialSequence
282 public byte[] getGRSequence(int type, int param) {
283 byte[] sequence = new byte[0];
284 int offset = 0;
285
286 switch (type) {
287 case TerminalIO.FCOLOR:
288 case TerminalIO.BCOLOR:
289
290 byte[] color = translateIntToDigitCodes(param);
291 sequence = new byte[3 + color.length];
292 sequence[0] = ESC;
293 sequence[1] = LSB;
294
295 //now copy the digit bytes
296 System.arraycopy(color, 0, sequence, 2, color.length);
297
298 //offset is now 2+color.length
299 offset = 2 + color.length;
300 sequence[offset] = 109; //ASCII Code of m
301
302 break;
303
304 case TerminalIO.STYLE:
305
306 byte[] style = translateIntToDigitCodes(param);
307 sequence = new byte[3 + style.length];
308 sequence[0] = ESC;
309 sequence[1] = LSB;
310
311 //now copy the digit bytes
312 System.arraycopy(style, 0, sequence, 2, style.length);
313
314 //offset is now 2+style.length
315 offset = 2 + style.length;
316 sequence[offset] = 109; //ASCII Code of m
317
318 break;
319
320 case TerminalIO.RESET:
321 sequence = new byte[5];
322 sequence[0] = ESC;
323 sequence[1] = LSB;
324 sequence[2] = 52; //ASCII Code of 4
325 sequence[3] = 56; //ASCII Code of 8
326 sequence[4] = 109; //ASCII Code of m
327
328 break;
329 }
330
331 return sequence;
332 }
333
334 //getGRsequence
335 public byte[] getScrollMarginsSequence(int topmargin, int bottommargin) {
336 byte[] sequence = new byte[0];
337
338 if (supportsScrolling()) {
339 //first translate integer coords into digits
340 byte[] topdigits = translateIntToDigitCodes(topmargin);
341 byte[] bottomdigits = translateIntToDigitCodes(bottommargin);
342 int offset = 0;
343
344 //now build up the sequence:
345 sequence = new byte[4 + topdigits.length + bottomdigits.length];
346 sequence[0] = ESC;
347 sequence[1] = LSB;
348
349 //now copy the digit bytes
350 System.arraycopy(topdigits, 0, sequence, 2, topdigits.length);
351
352 //offset is now 2+topdigits.length
353 offset = 2 + topdigits.length;
354 sequence[offset] = SEMICOLON;
355 offset++;
356 System.arraycopy(bottomdigits, 0, sequence, offset,
357 bottomdigits.length);
358 offset = offset + bottomdigits.length;
359 sequence[offset] = r;
360 }
361
362 return sequence;
363 }
364
365 //getScrollMarginsSequence
366 public String format(String str) {
367 return myColorizer.colorize(str, supportsSGR());
368 }
369
370 //format
371 public byte[] getInitSequence() {
372 byte[] sequence = new byte[0];
373
374 return sequence;
375 }
376
377 //getInitSequence
378 public int getAtomicSequenceLength() {
379 return 2;
380 }
381
382 //getAtomicSequenceLength
383 public byte[] translateIntToDigitCodes(int in) {
384 return Integer.toString(in).getBytes();
385 }
386
387 //translateIntToDigitCodes
388 public abstract boolean supportsSGR();
389
390 /**
391 *
392 *
393 * @return
394 */
395 public abstract boolean supportsScrolling();
396 }
397
398
399 //class BasicTerminal