001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: /**
027: * SSHTools - Java SSH API The contents of this package has been derived from
028: * the TelnetD library available from http://sourceforge.net/projects/telnetd
029: * The original license of the source code is as follows: TelnetD library
030: * (embeddable telnet daemon) Copyright (C) 2000 Dieter Wimberger This library
031: * is free software; you can either redistribute it and/or modify it under the
032: * terms of the GNU Lesser General Public License version 2.1,1999 as
033: * published by the Free Software Foundation (see copy received along with the
034: * library), or under the terms of the BSD-style license received along with
035: * this library.
036: */package com.sshtools.daemon.terminal;
037:
038: /**
039: *
040: *
041: * @author $author$
042: * @version $Revision: 1.11 $
043: */
044: public abstract class BasicTerminal implements Terminal {
045: //Associations
046:
047: /** */
048: protected Colorizer myColorizer;
049:
050: /**
051: * Creates a new BasicTerminal object.
052: */
053: public BasicTerminal() {
054: myColorizer = Colorizer.getReference();
055: }
056:
057: //constructor
058: public int translateControlCharacter(int c) {
059: switch (c) {
060: case DEL:
061: return TerminalIO.DELETE;
062:
063: case BS:
064: return TerminalIO.BACKSPACE;
065:
066: case HT:
067: return TerminalIO.TABULATOR;
068:
069: case ESC:
070: return TerminalIO.ESCAPE;
071:
072: case SGR:
073: return TerminalIO.COLORINIT;
074:
075: case EOT:
076: return TerminalIO.LOGOUTREQUEST;
077:
078: default:
079: return c;
080: }
081: }
082:
083: //translateControlCharacter
084: public int translateEscapeSequence(int[] buffer) {
085: try {
086: if (buffer[0] == LSB) {
087: switch (buffer[1]) {
088: case A:
089: return TerminalIO.UP;
090:
091: case B:
092: return TerminalIO.DOWN;
093:
094: case C:
095: return TerminalIO.RIGHT;
096:
097: case D:
098: return TerminalIO.LEFT;
099:
100: default:
101: break;
102: }
103: }
104: } catch (ArrayIndexOutOfBoundsException e) {
105: return TerminalIO.BYTEMISSING;
106: }
107:
108: return TerminalIO.UNRECOGNIZED;
109: }
110:
111: //translateEscapeSequence
112: public byte[] getCursorMoveSequence(int direction, int times) {
113: byte[] sequence = null;
114:
115: if (times == 1) {
116: sequence = new byte[3];
117: } else {
118: sequence = new byte[times * 3];
119: }
120:
121: for (int g = 0; g < (times * 3); g++) {
122: sequence[g] = ESC;
123: sequence[g + 1] = LSB;
124:
125: switch (direction) {
126: case TerminalIO.UP:
127: sequence[g + 2] = A;
128:
129: break;
130:
131: case TerminalIO.DOWN:
132: sequence[g + 2] = B;
133:
134: break;
135:
136: case TerminalIO.RIGHT:
137: sequence[g + 2] = C;
138:
139: break;
140:
141: case TerminalIO.LEFT:
142: sequence[g + 2] = D;
143:
144: break;
145:
146: default:
147: break;
148: }
149:
150: g = g + 2;
151: }
152:
153: return sequence;
154: }
155:
156: // getCursorMoveSequence
157: public byte[] getCursorPositioningSequence(int[] pos) {
158: byte[] sequence = null;
159:
160: if (pos == TerminalIO.HOME) {
161: sequence = new byte[3];
162: sequence[0] = ESC;
163: sequence[1] = LSB;
164: sequence[2] = H;
165: } else {
166: //first translate integer coords into digits
167: byte[] rowdigits = translateIntToDigitCodes(pos[0]);
168: byte[] columndigits = translateIntToDigitCodes(pos[1]);
169: int offset = 0;
170:
171: //now build up the sequence:
172: sequence = new byte[4 + rowdigits.length
173: + columndigits.length];
174: sequence[0] = ESC;
175: sequence[1] = LSB;
176:
177: //now copy the digit bytes
178: System.arraycopy(rowdigits, 0, sequence, 2,
179: 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,
336: int bottommargin) {
337: byte[] sequence = new byte[0];
338:
339: if (supportsScrolling()) {
340: //first translate integer coords into digits
341: byte[] topdigits = translateIntToDigitCodes(topmargin);
342: byte[] bottomdigits = translateIntToDigitCodes(bottommargin);
343: int offset = 0;
344:
345: //now build up the sequence:
346: sequence = new byte[4 + topdigits.length
347: + bottomdigits.length];
348: sequence[0] = ESC;
349: sequence[1] = LSB;
350:
351: //now copy the digit bytes
352: System.arraycopy(topdigits, 0, sequence, 2,
353: topdigits.length);
354:
355: //offset is now 2+topdigits.length
356: offset = 2 + topdigits.length;
357: sequence[offset] = SEMICOLON;
358: offset++;
359: System.arraycopy(bottomdigits, 0, sequence, offset,
360: bottomdigits.length);
361: offset = offset + bottomdigits.length;
362: sequence[offset] = r;
363: }
364:
365: return sequence;
366: }
367:
368: //getScrollMarginsSequence
369: public String format(String str) {
370: return myColorizer.colorize(str, supportsSGR());
371: }
372:
373: //format
374: public byte[] getInitSequence() {
375: byte[] sequence = new byte[0];
376:
377: return sequence;
378: }
379:
380: //getInitSequence
381: public int getAtomicSequenceLength() {
382: return 2;
383: }
384:
385: //getAtomicSequenceLength
386: public byte[] translateIntToDigitCodes(int in) {
387: return Integer.toString(in).getBytes();
388: }
389:
390: //translateIntToDigitCodes
391: public abstract boolean supportsSGR();
392:
393: /**
394: *
395: *
396: * @return
397: */
398: public abstract boolean supportsScrolling();
399: }
400:
401: //class BasicTerminal
|