5776799 [rkeene@sledge /home/rkeene/archive/floydssh/telnet]$ cat -n MidletTerminal.java
  1 package telnet;

  2 
  3 import javax.microedition.lcdui.*;

  4 import javax.microedition.rms.*;

  5 import java.io.*;

  6 
  7 /* This file is part of "Telnet Floyd".
  8  *
  9  * (c) Radek Polak 2003-2004. All Rights Reserved.
 10  *
 11  * Please visit project homepage at http://phoenix.inf.upol.cz/~polakr
 12  *
 13  * --LICENSE NOTICE--
 14  * This program is free software; you can redistribute it and/or
 15  * modify it under the terms of the GNU General Public License
 16  * as published by the Free Software Foundation; either version 2
 17  * of the License, or (at your option) any later version.
 18  *
 19  * This program is distributed in the hope that it will be useful,
 20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 22  * GNU General Public License for more details.
 23  *
 24  * You should have received a copy of the GNU General Public License
 25  * along with this program; if not, write to the Free Software
 26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 27  * --LICENSE NOTICE--
 28  *
 29  */
 30 
 31 /**
 32  * Class that acts as terminal. It can basicly draw input from emulation (see
 33  * variable "buffer"), execute and store actions defined by user.
 34  */
 35 
 36 public class MidletTerminal
 37     extends Canvas
 38     implements CommandListener {
 39 
 40   /** the VDU buffer */
 41   private vt320 buffer;
 42 
 43   /** first top and left character in buffer, that is displayed */
 44   private int top, left;
 45 
 46   /** display size in characters */
 47   public int rows, cols;
 48 
 49   private Image backingStore = null;
 50 
 51   private DrawFont font;
 52 
 53   public int fgcolor = 0x000000;
 54   public int bgcolor = 0xffffff;
 55 
 56   /** A list of colors used for representation of the display */
 57   private int color[] = {
 58       0x000000,
 59       0xff0000,
 60       0x00ff00,
 61       0xffff00, // yellow

 62       0x0000ff, // blue

 63       0x00ffff, // magenta

 64       0x00ffff, // cyan

 65       0xffffff, // white

 66       0xffffff, // bold color

 67       0xffffff, // inverted color

 68   };
 69 
 70   public final static int COLOR_INVERT = 9;
 71 
 72   public java.util.Hashtable bindings = new java.util.Hashtable();
 73 
 74   public MidletTerminal(vt320 buffer) {
 75 
 76     this.buffer = buffer;
 77 
 78     if (Telnet.useColors) {
 79       fgcolor = 0xffffff;
 80       bgcolor = 0x000000;
 81     }
 82 
 83     font = new DrawFont();
 84     backingStore = Image.createImage(this.getWidth(), this.getHeight());
 85 
 86     cols = this.getWidth() / font.width;
 87     rows = this.getHeight() / font.height;
 88 
 89     buffer.setScreenSize(cols, rows);
 90 
 91     top = 0;
 92     left = 0;
 93 
 94     loadBindings();
 95     displayHelp();
 96   }
 97 
 98   public void commandAction(Command command, Displayable displayable) {
 99     Telnet.setDisplay(new SelectFunctionDlg());
100   }
101 
102   protected void keyPressed(int keycode) {
103 
104     keycode += 64;
105     Object o = bindings.get(new Integer(keycode));
106     if (o == null) {
107       Telnet.setDisplay(new SelectFunctionDlg());
108       return;
109     }
110     Action action = (Action) o;
111 
112     int arg0 = 0;
113     int arg1 = 0;
114     int arg2 = 0;
115     try {
116       arg0 = Integer.parseInt(action.arg0);
117     }
118     catch (Exception e) {}
119     try {
120       arg1 = Integer.parseInt(action.arg1);
121     }
122     catch (Exception e) {}
123     try {
124       arg2 = Integer.parseInt(action.arg2);
125     }
126     catch (Exception e) {}
127 
128     switch (action.funct.hashCode()) {
129       case Action.INPUT_DIALOG_HASH:
130         InputDialog inputDlg = new InputDialog();
131         inputDlg.setString(action.arg0);
132         Telnet.setDisplay(inputDlg);
133         break;
134       case Action.SHOW_HELP_HASH:
135         displayHelp();
136         break;
137       case Action.SCROLL_LEFT_HASH:
138         if (left >= arg0) // arg0 is horizontal step here

139           left -= arg0;
140         else
141           left = 0;
142         redraw();
143         break;
144       case Action.SCROLL_RIGH_HASH:
145         if ( (left + arg0 + cols) <= buffer.width)
146           left += arg0;
147         else
148           left = buffer.width - cols;
149         redraw();
150         break;
151       case Action.SCROLL_UP_HASH:
152         if (top >= arg0) // arg0 is vertical step here

153           top -= arg0;
154         else
155           top = 0;
156         redraw();
157         break;
158       case Action.SCROLL_DOWN_HASH:
159         if ( (top + arg0 + rows) < buffer.height)
160           top += arg0;
161         else
162           top = buffer.height - rows;
163         redraw();
164         break;
165       case Action.TYPE_STRING_HASH:
166         String str = action.arg0;
167         for (int i = 0; i < str.length(); i++)
168           Telnet.emulation.keyTyped(0, str.charAt(i), 0);
169         break;
170       case Action.ENTER_STRING_HASH:
171         str = action.arg0;
172         for (int i = 0; i < str.length(); i++)
173           Telnet.emulation.keyTyped(0, str.charAt(i), 0);
174         Telnet.emulation.keyTyped(0, '\n', 0);
175         break;
176       case Action.KEY_PRESSED_HASH:
177         Telnet.emulation.keyPressed(arg0, (char) arg1, arg2);
178         break;
179       case Action.KEY_TYPED_HASH:
180         if (action.arg2.length() != 0) // key indentified by 3 integer codes

181           Telnet.emulation.keyTyped(arg0, (char) arg1, arg2);
182         else {
183           char keyChar = (char) (action.arg0.charAt(action.arg0.length() - 1) -
184                                  'a' + 1);
185           if (action.arg0.equals("tab"))
186             Telnet.emulation.keyTyped(0, '\t', 0);
187           else
188             Telnet.emulation.keyTyped(0, keyChar, getModifiers(action.arg0)); // key identified by specific string
	(CTRL+x)

189         }
190         break;
191       case Action.SET_SCREEN_SIZE_HASH:
192         Telnet.emulation.setScreenSize(arg0, arg1);
193         break;
194       case Action.CONNECT_HASH:
195         Telnet.host = action.arg0;
196         Telnet.sshIO.login = action.arg1;
197         Telnet.sshIO.password = action.arg2;
198         Telnet.reader.start();
199         break;
200       case Action.TRAFFIC_HASH:
201         Telnet.console.append(Telnet.traffic / 1024 + "kb" );
202         Telnet.setDisplay(Telnet.console);
203         break;
204       case Action.BG_COLOR_HASH:
205         bgcolor = arg2 | (arg1 << 8) | (arg0 << 16);
206         redraw();
207         break;
208       case Action.FG_COLOR_HASH:
209         fgcolor = arg2 | (arg1 << 8) | (arg0 << 16);
210         redraw();
211         break;
212       case Action.VIEW_CONSOLE_HASH:
213         Telnet.setDisplay(Telnet.console);
214         break;
215       case Action.SET_SCOLLBACK_SIZE_HASH:
216         buffer.setBufferSize(arg0);
217         break;
218       case Action.SCOLLBACK_UP_HASH:
219         buffer.setWindowBase(buffer.getWindowBase() - arg0);
220         break;
221       case Action.SCOLLBACK_DOWN_HASH:
222         buffer.setWindowBase(buffer.getWindowBase() + arg0);
223         break;
224       case Action.SHOW_TERMINAL_SIZE_HASH:
225         Telnet.emulation.putString(buffer.width + "x" + buffer.height);
226         redraw();
227         break;
228       case Action.SET_SLEEP_TIME_HASH:
229         Telnet.sleepTime = arg0;
230         break;
231       case Action.KEEP_CONNECTION_TIME_HASH:
232         Telnet.keepAliveCycles = (1000 * arg0) / Telnet.sleepTime;
233         break;
234       case Action.EXIT_APP_HASH:
235         Telnet.quitApp();
236         break;
237     }
238   }
239 
240   /**
241    * Create a color representation that is brighter than the standard
242    * color but not what we would like to use for bold characters.
243    * @param clr the standard color
244    * @return the new brighter color
245    */
246   private int brighten(int color) {
247     int r = (color & 0xff0000) >> 16;
248     int g = (color & 0x00ff00) >> 8;
249     int b = (color & 0x0000ff);
250 
251     r *= 12;
252     r /= 10;
253     if (r > 255) {
254       r = 255;
255     }
256     g *= 12;
257     g /= 10;
258     if (g > 255) {
259       g = 255;
260     }
261     b *= 12;
262     b /= 10;
263     if (b > 255) {
264       b = 255;
265     }
266     return b | (g << 8) | (r << 16);
267   }
268 
269   /**
270    * Create a color representation that is darker than the standard
271    * color but not what we would like to use for bold characters.
272    * @param clr the standard color
273    * @return the new darker color
274    */
275   private int darken(int color) {
276     int r = (color & 0xff0000) >> 16;
277     int g = (color & 0x00ff00) >> 8;
278     int b = (color & 0x0000ff);
279 
280     r *= 8;
281     r /= 10;
282     g *= 8;
283     g /= 10;
284     b *= 8;
285     b /= 10;
286     return b | (g << 8) | (r << 16);
287   }
288 
289   /** Required paint implementation */
290   protected void paint(Graphics g) {
291     g.drawImage(backingStore, 0, 0, 0);
292   }
293 
294   public void redraw() {
295 
296     Graphics g = backingStore.getGraphics();
297 
298     for (int l = top; l < buffer.height && l < (top + rows); l++) {
299       if (!buffer.update[0] && !buffer.update[l + 1]) {
300         continue;
301       }
302       buffer.update[l + 1] = false;
303       for (int c = left; c < buffer.width && c < (left + cols); c++) {
304         int addr = 0;
305         int currAttr = buffer.charAttributes[buffer.windowBase + l][c];
306 
307         int fg = darken(fgcolor);
308         int bg = darken(bgcolor);
309 
310         if ( (currAttr & buffer.COLOR_FG) != 0) {
311           fg = darken(color[ ( (currAttr & buffer.COLOR_FG) >> 4) - 1]);
312         }
313         if ( (currAttr & buffer.COLOR_BG) != 0) {
314           bg = darken(darken(color[ ( (currAttr & buffer.COLOR_BG) >> 8) - 1]));
315 
316           // bold font handling was DELETED

317 
318         }
319         if ( (currAttr & VDUBuffer.LOW) != 0) {
320           fg = darken(fg);
321         }
322         if ( (currAttr & VDUBuffer.INVERT) != 0) {
323           int swapc = bg;
324           bg = fg;
325           fg = swapc;
326         }
327 
328         // determine the maximum of characters we can print in one go

329         while ( (c + addr < buffer.width) &&
330                ( (buffer.charArray[buffer.windowBase + l][c + addr] < ' ') ||
331                 (buffer.charAttributes[buffer.windowBase + l][c + addr] ==
332                  currAttr))) {
333           if (buffer.charArray[buffer.windowBase + l][c + addr] < ' ') {
334             buffer.charArray[buffer.windowBase + l][c + addr] = ' ';
335             buffer.charAttributes[buffer.windowBase + l][c + addr] = 0;
336             continue;
337           }
338           addr++;
339         }
340 
341         // clear the part of the screen we want to change (fill rectangle)

342         if (Telnet.useColors)
343           g.setColor(bg);
344         else
345           g.setColor(bgcolor);
346 
347         g.fillRect( (c - left) * font.width, (l - top) * font.height,
348                    addr * font.width, font.height);
349 
350         if (Telnet.useColors)
351           g.setColor(fg);
352         else
353           g.setColor(fgcolor);
354 
355           // draw the characters

356         font.drawChars(g, buffer.charArray[buffer.windowBase + l], c, addr,
357                        (c - left) * font.width,
358                        (l - top) * font.height);
359 
360         c += addr - 1;
361       }
362     }
363 
364     // draw cursor

365     if (buffer.showcursor && (
366         buffer.screenBase + buffer.cursorY >= buffer.windowBase &&
367         buffer.screenBase + buffer.cursorY < buffer.windowBase + buffer.height)
368         ) {
369       g.setColor(fgcolor);
370       g.fillRect( (buffer.cursorX - left) * font.width,
371                  (buffer.cursorY - top + buffer.screenBase - buffer.windowBase) *
372                  font.height,
373                  font.width, font.height);
374     }
375 
376     repaint();
377   }
378 
379   /**
380    * Set a new terminal (VDU) buffer.
381    * @param buffer new buffer
382    */
383   public void setVDUBuffer(vt320 buffer) {
384     this.buffer = buffer;
385     buffer.setDisplay(this);
386   }
387 
388   public void loadBindings() {
389     bindings = new java.util.Hashtable();
390     RecordStore rec = null;
391     try {
392 //      RecordStore.deleteRecordStore("binds"); // uncomment to delete all binds

393       rec = RecordStore.openRecordStore("binds", false);
394     }
395     catch (Exception e) { // Set up default bindings

396       bindings.put(new Integer(Canvas.KEY_NUM1 + 64),
397                    new Action(Action.CONNECT, "158.194.80.13", "polakr",
398                               "mypass"));
399       bindings.put(new Integer(Canvas.KEY_NUM5 + 64),
400                    new Action(Action.INPUT_DIALOG, "", "", ""));
401       bindings.put(new Integer(Canvas.KEY_STAR + 64),
402                    new Action(Action.KEY_PRESSED, "37", "65535", "8"));
403       bindings.put(new Integer(Canvas.KEY_POUND + 64),
404                    new Action(Action.KEY_PRESSED, "39", "65535", "8"));
405       bindings.put(new Integer(Canvas.KEY_NUM8 + 64),
406                    new Action(Action.KEY_PRESSED, "38", "65535", "8"));
407       bindings.put(new Integer(Canvas.KEY_NUM0 + 64),
408                    new Action(Action.KEY_PRESSED, "40", "65535", "8"));
409       bindings.put(new Integer(Canvas.KEY_NUM9 + 64),
410                    new Action(Action.VIEW_CONSOLE, "", "", ""));
411       return;
412     }
413     try {
414       byte[] data;
415       RecordEnumeration enumerator = rec.enumerateRecords(null, null, false);
416       if (enumerator.hasNextElement()) {
417         data = enumerator.nextRecord();
418         ByteArrayInputStream stream = new ByteArrayInputStream(data);
419         DataInputStream in = new DataInputStream(stream);
420         while (in.available() > 0)
421           bindings.put(new Integer(in.readInt()),
422                        new Action(in.readUTF(), in.readUTF(), in.readUTF(),
423                                   in.readUTF()));
424         in.close();
425       }
426       rec.closeRecordStore();
427     }
428     catch (Exception e) {
429       e.printStackTrace();
430     }
431   }
432 
433   public void saveBindings() {
434     try {
435       try
436       {
437         RecordStore.deleteRecordStore("binds");
438       }
439       catch( Exception e ) {}
440       RecordStore rec = RecordStore.openRecordStore("binds", true);
441       ByteArrayOutputStream stream = new ByteArrayOutputStream();
442       DataOutputStream out = new DataOutputStream(stream);
443       for (int i = 0; i < 128; i++) {
444         Object o = bindings.get(new Integer(i));
445         if (o != null) {
446           Action a = (Action) o;
447           out.writeInt( i );
448           out.writeUTF(a.funct);
449           out.writeUTF(a.arg0);
450           out.writeUTF(a.arg1);
451           out.writeUTF(a.arg2);
452         }
453       }
454       out.close();
455       byte[] data = stream.toByteArray();
456       rec.addRecord(data, 0, data.length);
457       rec.closeRecordStore();
458     }
459     catch (Exception e) {
460       e.printStackTrace();
461     }
462   }
463 
464   public void displayHelp() {
465     String help = "";
466     for (int i = 0; i < 128; i++) {
467       Object o = bindings.get(new Integer(i));
468       if (o != null) {
469         Action action = (Action) o;
470         String line = getKeyName(i - 64) + " - " +
471             action.funct + " " +
472             action.arg0 + " " +
473             action.arg1 + " " +
474             action.arg2;
475         help += line + "\n\r";
476         if (Telnet.socket != null )
477           Telnet.console.append(line);
478       }
479     }
480     if (Telnet.socket != null) {
481       Telnet.setDisplay(Telnet.console);
482     }
483     else {
484       buffer.deleteArea(0, 0, buffer.width, buffer.height);
485       buffer.R = 0;
486       buffer.C = 0;
487       Telnet.emulation.putString(help);
488       redraw();
489     }
490   }
491 
492   /**
493    * Types key specified as string argument
494    * @param code - string kode of key e.g. CTRL+x
495    * @return true if code was parsed and key was typed
496    */
497   public int getModifiers(String code) {
498     int modifiers = 0;
499     if (code.indexOf("ctrl") != -1)
500       modifiers |= vt320.KEY_CONTROL;
501     if (code.indexOf("shift") != -1)
502       modifiers |= vt320.KEY_SHIFT;
503     if (code.indexOf("alt") != -1)
504       modifiers |= vt320.KEY_ALT;
505     return modifiers;
506   }
507 
508 }
5776800 [rkeene@sledge /home/rkeene/archive/floydssh/telnet]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 23:49:58