📄 vt320.java
字号:
/* This file is part of "The Java Telnet Application". * * (c) Matthias L. Jugel, Marcus Mei\u00dfner 1996-2002. All Rights Reserved. * * Please visit http://javatelnet.org/ for updates and contact. * * --LICENSE NOTICE-- * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * --LICENSE NOTICE-- * */package de.mud.terminal;import java.util.Properties;import java.awt.event.KeyEvent;/** * Implementation of a VT terminal emulation plus ANSI compatible. * <P> * <B>Maintainer:</B> Marcus Mei\u00dfner * * @version $Id: vt320.java,v 2.97 2003/12/09 22:50:49 marcus Exp $ * @author Matthias L. Jugel, Marcus Mei\u00dfner */public abstract class vt320 extends VDUBuffer implements VDUInput { /** The current version id tag.<P> * $Id: vt320.java,v 2.97 2003/12/09 22:50:49 marcus Exp $ */ public final static String ID = "$Id: vt320.java,v 2.97 2003/12/09 22:50:49 marcus Exp $"; /** the debug level */ private final static int debug = 0; /** * Write an answer back to the remote host. This is needed to be able to * send terminal answers requests like status and type information. * @param b the array of bytes to be sent */ public abstract void write(byte[] b); /** * Play the beep sound ... */ public void beep() { /* do nothing by default */ } /** * Put string at current cursor position. Moves cursor * according to the String. Does NOT wrap. * @param s the string */ public void putString(String s) { int len = s.length(); // System.err.println("'"+s+"'"); if (len > 0) { markLine(R, 1); for (int i = 0; i < len; i++) { // System.err.print(s.charAt(i)+"("+(int)s.charAt(i)+")"); putChar(s.charAt(i), false); } setCursorPosition(C, R); redraw(); } } protected void sendTelnetCommand(byte cmd) { } /** * Create a new vt320 terminal and intialize it with useful settings. */ public vt320(int width, int height) { super(width, height); setVMS(false); setIBMCharset(false); setTerminalID("vt320"); setBufferSize(100); //setBorder(2, false); int nw = getColumns(); if (nw < 132) nw = 132; //catch possible later 132/80 resizes Tabs = new byte[nw]; for (int i = 0; i < nw; i += 8) { Tabs[i] = 1; } /* top row of numpad */ PF1 = "\u001bOP"; PF2 = "\u001bOQ"; PF3 = "\u001bOR"; PF4 = "\u001bOS"; /* the 3x2 keyblock on PC keyboards */ Insert = new String[4]; Remove = new String[4]; KeyHome = new String[4]; KeyEnd = new String[4]; NextScn = new String[4]; PrevScn = new String[4]; Escape = new String[4]; BackSpace = new String[4]; TabKey = new String[4]; Insert[0] = Insert[1] = Insert[2] = Insert[3] = "\u001b[2~"; Remove[0] = Remove[1] = Remove[2] = Remove[3] = "\u001b[3~"; PrevScn[0] = PrevScn[1] = PrevScn[2] = PrevScn[3] = "\u001b[5~"; NextScn[0] = NextScn[1] = NextScn[2] = NextScn[3] = "\u001b[6~"; KeyHome[0] = KeyHome[1] = KeyHome[2] = KeyHome[3] = "\u001b[H"; KeyEnd[0] = KeyEnd[1] = KeyEnd[2] = KeyEnd[3] = "\u001b[F"; Escape[0] = Escape[1] = Escape[2] = Escape[3] = "\u001b"; if (vms) { BackSpace[1] = "" + (char) 10; // VMS shift deletes word back BackSpace[2] = "\u0018"; // VMS control deletes line back BackSpace[0] = BackSpace[3] = "\u007f"; // VMS other is delete } else { BackSpace[0] = BackSpace[1] = BackSpace[2] = BackSpace[3] = "\b"; } /* some more VT100 keys */ Find = "\u001b[1~"; Select = "\u001b[4~"; Help = "\u001b[28~"; Do = "\u001b[29~"; FunctionKey = new String[21]; FunctionKey[0] = ""; FunctionKey[1] = PF1; FunctionKey[2] = PF2; FunctionKey[3] = PF3; FunctionKey[4] = PF4; /* following are defined differently for vt220 / vt132 ... */ FunctionKey[5] = "\u001b[15~"; FunctionKey[6] = "\u001b[17~"; FunctionKey[7] = "\u001b[18~"; FunctionKey[8] = "\u001b[19~"; FunctionKey[9] = "\u001b[20~"; FunctionKey[10] = "\u001b[21~"; FunctionKey[11] = "\u001b[23~"; FunctionKey[12] = "\u001b[24~"; FunctionKey[13] = "\u001b[25~"; FunctionKey[14] = "\u001b[26~"; FunctionKey[15] = Help; FunctionKey[16] = Do; FunctionKey[17] = "\u001b[31~"; FunctionKey[18] = "\u001b[32~"; FunctionKey[19] = "\u001b[33~"; FunctionKey[20] = "\u001b[34~"; FunctionKeyShift = new String[21]; FunctionKeyAlt = new String[21]; FunctionKeyCtrl = new String[21]; for (int i = 0; i < 20; i++) { FunctionKeyShift[i] = ""; FunctionKeyAlt[i] = ""; FunctionKeyCtrl[i] = ""; } FunctionKeyShift[15] = Find; FunctionKeyShift[16] = Select; TabKey[0] = "\u0009"; TabKey[1] = "\u001bOP\u0009"; TabKey[2] = TabKey[3] = ""; KeyUp = new String[4]; KeyUp[0] = "\u001b[A"; KeyDown = new String[4]; KeyDown[0] = "\u001b[B"; KeyRight = new String[4]; KeyRight[0] = "\u001b[C"; KeyLeft = new String[4]; KeyLeft[0] = "\u001b[D"; Numpad = new String[10]; Numpad[0] = "\u001bOp"; Numpad[1] = "\u001bOq"; Numpad[2] = "\u001bOr"; Numpad[3] = "\u001bOs"; Numpad[4] = "\u001bOt"; Numpad[5] = "\u001bOu"; Numpad[6] = "\u001bOv"; Numpad[7] = "\u001bOw"; Numpad[8] = "\u001bOx"; Numpad[9] = "\u001bOy"; KPMinus = PF4; KPComma = "\u001bOl"; KPPeriod = "\u001bOn"; KPEnter = "\u001bOM"; NUMPlus = new String[4]; NUMPlus[0] = "+"; NUMDot = new String[4]; NUMDot[0] = "."; } /** * Create a default vt320 terminal with 80 columns and 24 lines. */ public vt320() { this(80, 24); } /** * Terminal is mouse-aware and requires (x,y) coordinates of * on the terminal (character coordinates) and the button clicked. * @param x * @param y * @param modifiers */ public void mousePressed(int x, int y, int modifiers) { if (mouserpt == 0) return; int mods = modifiers; mousebut = 3; if ((mods & 16) == 16) mousebut = 0; if ((mods & 8) == 8) mousebut = 1; if ((mods & 4) == 4) mousebut = 2; int mousecode; if (mouserpt == 9) /* X10 Mouse */ mousecode = 0x20 | mousebut; else /* normal xterm mouse reporting */ mousecode = mousebut | 0x20 | ((mods & 7) << 2); byte b[] = new byte[6]; b[0] = 27; b[1] = (byte) '['; b[2] = (byte) 'M'; b[3] = (byte) mousecode; b[4] = (byte) (0x20 + x + 1); b[5] = (byte) (0x20 + y + 1); write(b); // FIXME: writeSpecial here } /** * Terminal is mouse-aware and requires the coordinates and button * of the release. * @param x * @param y * @param modifiers */ public void mouseReleased(int x, int y, int modifiers) { if (mouserpt == 0) return; /* problem is tht modifiers still have the released button set in them. int mods = modifiers; mousebut = 3; if ((mods & 16)==16) mousebut=0; if ((mods & 8)==8 ) mousebut=1; if ((mods & 4)==4 ) mousebut=2; */ int mousecode; if (mouserpt == 9) mousecode = 0x20 + mousebut; /* same as press? appears so. */ else mousecode = '#'; byte b[] = new byte[6]; b[0] = 27; b[1] = (byte) '['; b[2] = (byte) 'M'; b[3] = (byte) mousecode; b[4] = (byte) (0x20 + x + 1); b[5] = (byte) (0x20 + y + 1); write(b); // FIXME: writeSpecial here mousebut = 0; } /** we should do localecho (passed from other modules). false is default */ private boolean localecho = false; /** * Enable or disable the local echo property of the terminal. * @param echo true if the terminal should echo locally */ public void setLocalEcho(boolean echo) { localecho = echo; } /** * Enable the VMS mode of the terminal to handle some things differently * for VMS hosts. * @param vms true for vms mode, false for normal mode */ public void setVMS(boolean vms) { this.vms = vms; } /** * Enable the usage of the IBM character set used by some BBS's. Special * graphical character are available in this mode. * @param ibm true to use the ibm character set */ public void setIBMCharset(boolean ibm) { useibmcharset = ibm; } /** * Override the standard key codes used by the terminal emulation. * @param codes a properties object containing key code definitions */ public void setKeyCodes(Properties codes) { String res, prefixes[] = {"", "S", "C", "A"}; int i; for (i = 0; i < 10; i++) { res = codes.getProperty("NUMPAD" + i); if (res != null) Numpad[i] = unEscape(res); } for (i = 1; i < 20; i++) { res = codes.getProperty("F" + i); if (res != null) FunctionKey[i] = unEscape(res); res = codes.getProperty("SF" + i); if (res != null) FunctionKeyShift[i] = unEscape(res); res = codes.getProperty("CF" + i); if (res != null) FunctionKeyCtrl[i] = unEscape(res); res = codes.getProperty("AF" + i); if (res != null) FunctionKeyAlt[i] = unEscape(res); } for (i = 0; i < 4; i++) { res = codes.getProperty(prefixes[i] + "PGUP"); if (res != null) PrevScn[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "PGDOWN"); if (res != null) NextScn[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "END"); if (res != null) KeyEnd[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "HOME"); if (res != null) KeyHome[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "INSERT"); if (res != null) Insert[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "REMOVE"); if (res != null) Remove[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "UP"); if (res != null) KeyUp[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "DOWN"); if (res != null) KeyDown[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "LEFT"); if (res != null) KeyLeft[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "RIGHT"); if (res != null) KeyRight[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "ESCAPE"); if (res != null) Escape[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "BACKSPACE"); if (res != null) BackSpace[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "TAB"); if (res != null) TabKey[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "NUMPLUS"); if (res != null) NUMPlus[i] = unEscape(res); res = codes.getProperty(prefixes[i] + "NUMDECIMAL"); if (res != null) NUMDot[i] = unEscape(res); } } /** * Set the terminal id used to identify this terminal. * @param terminalID the id string */ public void setTerminalID(String terminalID) { this.terminalID = terminalID; if (terminalID.equals("scoansi")) { FunctionKey[1] = "\u001b[M"; FunctionKey[2] = "\u001b[N"; FunctionKey[3] = "\u001b[O"; FunctionKey[4] = "\u001b[P"; FunctionKey[5] = "\u001b[Q"; FunctionKey[6] = "\u001b[R"; FunctionKey[7] = "\u001b[S"; FunctionKey[8] = "\u001b[T"; FunctionKey[9] = "\u001b[U"; FunctionKey[10] = "\u001b[V"; FunctionKey[11] = "\u001b[W"; FunctionKey[12] = "\u001b[X"; FunctionKey[13] = "\u001b[Y"; FunctionKey[14] = "?"; FunctionKey[15] = "\u001b[a"; FunctionKey[16] = "\u001b[b"; FunctionKey[17] = "\u001b[c"; FunctionKey[18] = "\u001b[d"; FunctionKey[19] = "\u001b[e"; FunctionKey[20] = "\u001b[f"; // more theoretically. } } public void setAnswerBack(String ab) { this.answerBack = unEscape(ab); } /** * Get the terminal id used to identify this terminal. */ public String getTerminalID() { return terminalID; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -