📄 terminalwin.java
字号:
/****************************************************************************** * * Copyright (c) 1999-2004 AppGate Network Security AB. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. * * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE. If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************/package com.mindbright.terminal;import java.util.NoSuchElementException;import java.awt.*;import java.awt.event.*;import java.util.Vector;import java.util.Properties;import java.util.Enumeration;public final class TerminalWin extends Canvas implements Terminal, KeyListener, AdjustmentListener, MouseListener, MouseMotionListener, ComponentListener, FocusListener{ boolean metaKeyKludge = false; boolean ctrlKeyKludge = false; int lastKeyKludge = 0; boolean lastKeyWasPressed = false; boolean pendingShow = true; final static boolean DEBUG = false; final static boolean DEBUGKEYEVENT = false; final static public int GRAVITY_SOUTHWEST = 0; final static public int GRAVITY_NORTHWEST = 1; final static public int MIN_ROWS = 2; final static public int MIN_COLS = 8; final static public int MAX_COLS = 512; final static public int MAX_ROWS = 512; Vector inListeners; Vector outListeners; TerminalPrinter printer; boolean printerActive; TerminalClipboardHandler clipboard; TerminalInterpreter interpreter; Scrollbar scrollbar; boolean haveScrollbar; PopupMenu popupmenu; Panel myPanel; Frame ownerFrame; Object writeLock; TerminalCharsetTranslator translator; final static char[] mc4 = new char[] { (char)27, '[', '4', 'i' }; int mc4MatchIdx; private boolean logoDraw; private Image logoImg; private int logoX; private int logoY; private int logoW; private int logoH; public int popupButton = InputEvent.BUTTON3_MASK; public int pasteButton = InputEvent.BUTTON2_MASK; TerminalMenuHandler menuHandler; String title; Properties props; boolean propsChanged; String savedGeomPos; boolean insideConstructor; char bsCharacter; char delCharacter; boolean haveFocus; volatile boolean repaintPending; boolean cursorHollow; boolean cursorDrawn; boolean complexScroll; boolean fullRefresh; int dirtyTop; int dirtyBottom; int dirtyLeft; int dirtyRight; int resizeGravity; int rows; int cols; int vpixels; int hpixels; int borderWidth = 2; int borderHeight = 2; int windowTop; int windowBottom; int windowLeft; int windowRight; int charWidth; int charHeight; int charMaxAscent; int charMaxDescent; int charLeading; int baselineIndex; int curRow; int curCol; int lastCursorRow; int lastCursorCol; int selectRowAnchor; int selectColAnchor; int selectRowLast; int selectColLast; boolean hasSelection; boolean selectReverse; String selectDelims; int selectClickRow = -1; boolean selectClickState; long lastLeftClick = 0; int curAttr; int curRowSave; int curColSave; int curAttrSave; Color origBgColor; Color origFgColor; Color cursorColor; public final static Color termColors[] = { Color.black, Color.red.darker(), Color.green.darker(), Color.yellow.darker(), Color.blue.darker(), Color.magenta.darker(), Color.cyan.darker(), Color.white, Color.darkGray, Color.red, Color.green, Color.yellow, Color.blue, Color.magenta, Color.cyan, Color.white }; public final static String[] termColorNames = { "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "i_black", "i_red", "i_green", "i_yellow", "i_blue","i_magenta", "i_cyan", "i_white" }; char[][] screen; int[][] attributes; boolean[] autowraps; int saveLines; int visTop; int saveVisTop; int lineSpaceDelta; // (NOTE: The real terminal attributes are in Terminal.java) // public final static int ATTR_CHARNOTDRAWN = 0x0000; public final static int ATTR_LINEDRAW = 0x0100; public final static int ATTR_SELECTED = 0x1000; public final static int ATTR_CHARDRAWN = 0x8000; public final static int MASK_ATTR = 0x0000ffff; public final static int MASK_FGCOL = 0x00ff0000; public final static int MASK_BGCOL = 0xff000000; public final static int SHIFT_FGCOL = 16; public final static int SHIFT_BGCOL = 24; public final static char[] spacerow = new char[MAX_COLS]; public final static int[] zerorow = new int[MAX_COLS]; public final static char[] byte2char = new char[256]; static { int i; for(i = 0; i < MAX_COLS; i++) { spacerow[i] = ' '; zerorow[i] = 0; } byte[] b = new byte[1]; char[] c; for(i = 0; i < 256; i++) { b[0] = (byte)i; c = (new String(b)).toCharArray(); if(c.length > 0) { byte2char[i] = c[0]; } else { byte2char[i] = (char)i; } } } boolean[] tabStops = new boolean[MAX_COLS]; boolean[] termOptions; Image memImage; Graphics memGraphics; Dimension memImageSize; public Font plainFont; public Font boldFont; public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter, Properties initProps) throws IllegalArgumentException { this(ownerFrame, interpreter, initProps, false); } public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter, Properties initProps, boolean setAsDefault) throws IllegalArgumentException { super(); scrollbar = null; haveScrollbar = false; title = null; termOptions = new boolean[Terminal.OPT_LAST_OPT]; cursorDrawn = false; cursorHollow = false; curAttr = ATTR_CHARDRAWN; curRow = 0; curCol = 0; visTop = 0; saveVisTop = 0; writeLock = new Object(); if(setAsDefault) { TerminalDefProps.setAsDefault(initProps); } repaintPending = false; savedGeomPos = ""; this.ownerFrame = ownerFrame; this.interpreter = interpreter; interpreter.setTerminal(this); insideConstructor = true; setProperties(initProps, true); insideConstructor = false; propsChanged = false; resetTabs(); // !!! We don't receive the proper component-events on the Canvas IMHO? // ownerFrame.addComponentListener(this); // !!! Ok, in spite of all our efforts here, we seem to need this // for certain situations, I give up once again... // // ownerFrame.addKeyListener(this); addKeyListener(this); addComponentListener(this); addFocusListener(this); addMouseMotionListener(this); addMouseListener(this); try { /* * This is put in separate file to be able to use without reflect * package since otherwise we can't link this class in some cases. */ new FocusKludge(this); } catch (Throwable t) { /* only needed/available in jdk1.4 */ } } public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter) throws IllegalArgumentException, NoSuchElementException { this(ownerFrame, interpreter, TerminalDefProps.defaultProperties); } public void setMenus(TerminalMenuHandler menus) { menuHandler = menus; } public TerminalMenuHandler getMenus() { return menuHandler; } public void updateMenus() { if(menuHandler != null) { menuHandler.update(); for(int i = 0; i < OPT_LAST_MENU; i++) { menuHandler.setStateOpt(i, termOptions[i]); } menuHandler.setEnabledOpt(OPT_DECCOLM,termOptions[OPT_DEC132COLS]); } } public void setLogo(Image logoImg, int x, int y, int w, int h) { this.logoImg = logoImg; this.logoX = x; this.logoY = y; this.logoW = w; this.logoH = h; } public Image getLogo() { return logoImg; } public boolean showLogo() { logoDraw = (logoImg != null); try { makeAllDirty(true); } catch (Throwable t) { // Sun JRE 1.4.[01] on 24bpp Linux displays crashes when showing // logo. Ignore. logoDraw = false; } return logoDraw; } public void hideLogo() { logoDraw = false; try { makeAllDirty(true); } catch (Throwable t) { // Sun JRE 1.4.[01] on 24bpp Linux displays crashes when showing // logo. Ignore. } } public void setProperties(Properties newProps, boolean merge) throws IllegalArgumentException { String name, value; Enumeration enum; int i; Properties oldProps = props; props = new Properties(TerminalDefProps.defaultProperties); if(merge && oldProps != null) { enum = oldProps.keys(); while(enum.hasMoreElements()) { name = (String)enum.nextElement(); value = oldProps.getProperty(name); props.put(name, value); } } // Order is important to get this right, set "normal" settings first, // then options // !!! OUCH // String oldVal; for(i = termOptions.length; i < TerminalDefProps.defaultPropDesc.length; i++) { name = TerminalDefProps.defaultPropDesc[i][ TerminalDefProps.PROP_NAME]; value = newProps.getProperty(name); name = TerminalDefProps.backwardCompatProp(name); if(value == null) value = props.getProperty(name); if(!merge && oldProps != null) { oldVal = oldProps.getProperty(name); setProperty(name, value, !value.equals(oldVal)); } else { setProperty(name, value, insideConstructor); } } for(i = 0; i < termOptions.length; i++) { name = TerminalDefProps.defaultPropDesc[i][ TerminalDefProps.PROP_NAME]; value = newProps.getProperty(name); name = TerminalDefProps.backwardCompatProp(name); if(value == null) value = props.getProperty(name); if(!merge && oldProps != null) { oldVal = oldProps.getProperty(name); setProperty(name, value, !value.equals(oldVal)); } else { setProperty(name, value, insideConstructor); } } } public Properties getProperties() { return props; } public boolean getPropsChanged() { return propsChanged; } public void setPropsChanged(boolean value) { propsChanged = value; } public void resetToDefaults() { setProperties(TerminalDefProps.defaultProperties, false); } public String getProperty(String key) { key = TerminalDefProps.backwardCompatProp(key); return props.getProperty(key); } public String getDefaultProperty(String key) { key = TerminalDefProps.backwardCompatProp(key); return TerminalDefProps.defaultProperties.getProperty(key); } public void resetProperty(String key) { key = TerminalDefProps.backwardCompatProp(key); setProperty(key, getDefaultProperty(key)); } public void setProperty(String key, String value) throws IllegalArgumentException, NoSuchElementException { setProperty(key, value, false); } public synchronized void setProperty(String key, String value, boolean forceSet) throws IllegalArgumentException, NoSuchElementException { int i; boolean isEqual = false; String val; key = TerminalDefProps.backwardCompatProp(key); if(((val = getProperty(key)) != null) && val.equals(value)) { isEqual = true; if(!forceSet) return; } for(i = 0; i < termOptions.length; i++) { if(TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME]. equals(key)) break; } if(i < termOptions.length) { if(!(value.equals("true") || value.equals("false"))) { throw new IllegalArgumentException( "value for '" + key + "' must be 'true' or 'false'"); } setOption(i, (new Boolean(value)).booleanValue()); } else { if(key.equals("term-type")) { if(interpreter instanceof TerminalXTerm) ((TerminalXTerm)interpreter).setTerminalType(value); } else if(key.equals("font-name")) { setFont(value, Integer.parseInt(getProperty("font-size"))); } else if(key.equals("font-size")) { try { setFont(getProperty("font-name"), Integer.parseInt(value)); } catch (NumberFormatException e) { throw new IllegalArgumentException(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -