⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* Input.java
 * Component: ProperJavaRDP
 * 
 * Revision: $Revision: 1.7 $
 * Author: $Author: telliott $
 * Date: $Date: 2005/09/27 14:15:39 $
 *
 * Copyright (c) 2005 Propero Limited
 *
 * Purpose: Handles input events and sends relevant input data
 *          to server
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * (See gpl.txt for details of the GNU General Public License.)
 * 
 */

package net.propero.rdp;

import net.propero.rdp.keymapping.KeyCode;
import net.propero.rdp.keymapping.KeyCode_FileBased;
import net.propero.rdp.keymapping.KeyMapException;

import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import java.awt.event.*;
import java.io.InputStream;
import java.util.Vector;

public abstract class Input {

    protected static Logger logger = Logger.getLogger(Input.class);
    
	KeyCode_FileBased newKeyMapper = null;

	protected Vector pressedKeys;

	protected static boolean capsLockOn = false;
	protected static boolean numLockOn = false;
	protected static boolean scrollLockOn = false;

	protected static boolean serverAltDown = false;
    protected static boolean altDown = false;
	protected static boolean ctrlDown = false;

    protected static long last_mousemove = 0;
    
	// Using this flag value (0x0001) seems to do nothing, and after running
	// through other possible values, the RIGHT flag does not appear to be
	// implemented
	protected static final int KBD_FLAG_RIGHT = 0x0001;
	protected static final int KBD_FLAG_EXT = 0x0100;

	// QUIET flag is actually as below (not 0x1000 as in rdesktop)
	protected static final int KBD_FLAG_QUIET = 0x200;
	protected static final int KBD_FLAG_DOWN = 0x4000;
	protected static final int KBD_FLAG_UP = 0x8000;

	protected static final int RDP_KEYPRESS = 0;
	protected static final int RDP_KEYRELEASE = KBD_FLAG_DOWN | KBD_FLAG_UP;
	protected static final int MOUSE_FLAG_MOVE = 0x0800;

	protected static final int MOUSE_FLAG_BUTTON1 = 0x1000;
	protected static final int MOUSE_FLAG_BUTTON2 = 0x2000;
	protected static final int MOUSE_FLAG_BUTTON3 = 0x4000;

	protected static final int MOUSE_FLAG_BUTTON4 = 0x0280; // wheel up -
	                                                        // rdesktop 1.2.0
	protected static final int MOUSE_FLAG_BUTTON5 = 0x0380; // wheel down -
															// rdesktop 1.2.0
	protected static final int MOUSE_FLAG_DOWN = 0x8000;

    protected static final int RDP_INPUT_SYNCHRONIZE = 0;
	protected static final int RDP_INPUT_CODEPOINT = 1;
	protected static final int RDP_INPUT_VIRTKEY = 2;
	protected static final int RDP_INPUT_SCANCODE = 4;
	protected static final int RDP_INPUT_MOUSE = 0x8001;

	protected static int time = 0;

	public KeyEvent lastKeyEvent = null;
	public boolean modifiersValid = false;
	public boolean keyDownWindows = false;

	protected RdesktopCanvas canvas = null;
	protected Rdp rdp = null;
	KeyCode keys = null;

    /**
     * Create a new Input object with a given keymap object
     * @param c Canvas on which to listen for input events
     * @param r Rdp layer on which to send input messages
     * @param k Key map to use in handling keyboard events
     */
	public Input(RdesktopCanvas c, Rdp r, KeyCode_FileBased k) {
		newKeyMapper = k;
		canvas = c;
		rdp = r;
		if (Options.debug_keyboard)
			logger.setLevel(Level.DEBUG);
		addInputListeners();
		pressedKeys = new Vector();
	}

    /**
     * Create a new Input object, using a keymap generated from a specified file
     * @param c Canvas on which to listen for input events
     * @param r Rdp layer on which to send input messages
     * @param keymapFile Path to file containing keymap data
     */
	public Input(RdesktopCanvas c, Rdp r, String keymapFile) {
		try {
			newKeyMapper = new KeyCode_FileBased_Localised(keymapFile);
		} catch (KeyMapException kmEx) {
			System.err.println(kmEx.getMessage());
			if(!Common.underApplet) System.exit(-1);
		}

		canvas = c;
		rdp = r;
		if (Options.debug_keyboard)
			logger.setLevel(Level.DEBUG);
		addInputListeners();
		pressedKeys = new Vector();
	}

    /**
     * Add all relevant input listeners to the canvas
    */
	public void addInputListeners() {
		canvas.addMouseListener(new RdesktopMouseAdapter());
		canvas.addMouseMotionListener(new RdesktopMouseMotionAdapter());
		canvas.addKeyListener(new RdesktopKeyAdapter());
	}

	/**
     * Send a sequence of key actions to the server
     * @param pressSequence String representing a sequence of key actions.
     *                      Actions are represented as a pair of consecutive characters,
     *                      the first character's value (cast to integer) being the scancode
     *                      to send, the second (cast to integer) of the pair representing the action
     *                      (0 == UP, 1 == DOWN, 2 == QUIET UP, 3 == QUIET DOWN). 
	 */
	public void sendKeyPresses(String pressSequence) {
		try {
			String debugString = "Sending keypresses: ";
			for (int i = 0; i < pressSequence.length(); i += 2) {
				int scancode = (int) pressSequence.charAt(i);
				int action = (int) pressSequence.charAt(i + 1);
				int flags = 0;

				if (action == KeyCode_FileBased.UP)
					flags = RDP_KEYRELEASE;
				else if (action == KeyCode_FileBased.DOWN)
					flags = RDP_KEYPRESS;
				else if (action == KeyCode_FileBased.QUIETUP)
					flags = RDP_KEYRELEASE | KBD_FLAG_QUIET;
				else if (action == KeyCode_FileBased.QUIETDOWN)
					flags = RDP_KEYPRESS | KBD_FLAG_QUIET;

				long t = getTime();

				debugString += "(0x"
						+ Integer.toHexString(scancode)
						+ ", "
						+ ((action == KeyCode_FileBased.UP || action == KeyCode_FileBased.QUIETUP) ? "up"
								: "down")
						+ ((flags & KBD_FLAG_QUIET) != 0 ? " quiet" : "")
						+ " at " + t + ")";

				sendScancode(t, flags, scancode);
			}

			if (pressSequence.length() > 0)
				logger.debug(debugString);
		} catch (Exception ex) {
			return;
		}
	}

    /**
     * Retrieve the next "timestamp", by incrementing previous
     * stamp (up to the maximum value of an integer, at which the
     * timestamp is reverted to 1)
     * @return New timestamp value
     */
	public static int getTime() {
		time++;
		if (time == Integer.MAX_VALUE)
			time = 1;
		return time;
	}

    /**
     * Handle loss of focus to the main canvas.
     * Clears all depressed keys (sending release messages
     * to the server.
     */
	public void lostFocus() {
        clearKeys();
		modifiersValid = false;
	}

    /**
     * Handle the main canvas gaining focus.
     * Check locking key states.
     */
    public void gainedFocus() {
		doLockKeys(); // ensure lock key states are correct
	}

    /**
     * Send a keyboard event to the server
     * @param time Time stamp to identify this event
     * @param flags Flags defining the nature of the event (eg: press/release/quiet/extended)
     * @param scancode Scancode value identifying the key in question
     */
	public void sendScancode(long time, int flags, int scancode) {

        if(scancode == 0x38){ // be careful with alt
            if((flags & RDP_KEYRELEASE) != 0){
                //logger.info("Alt release, serverAltDown = " + serverAltDown);
                serverAltDown = false;
            }
            if((flags == RDP_KEYPRESS)){
                //logger.info("Alt press, serverAltDown = " + serverAltDown);
                serverAltDown = true;
            }
        }
        
		if ((scancode & KeyCode.SCANCODE_EXTENDED) != 0) {
			rdp.sendInput((int) time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
					scancode & ~KeyCode.SCANCODE_EXTENDED, 0);
		} else
			rdp.sendInput((int) time, RDP_INPUT_SCANCODE, flags, scancode, 0);
	}

    /**
     * Release any modifier keys that may be depressed.
     */
	public void clearKeys() {
		if (!modifiersValid)
			return;
        
        altDown = false;
        ctrlDown = false;
        
        if(lastKeyEvent == null) return;
        
		if (lastKeyEvent.isShiftDown())
			sendScancode(getTime(), RDP_KEYRELEASE, 0x2a); // shift
		if (lastKeyEvent.isAltDown() || serverAltDown){
            sendScancode(getTime(), RDP_KEYRELEASE, 0x38); // ALT
            sendScancode(getTime(), RDP_KEYPRESS | KBD_FLAG_QUIET, 0x38); // ALT
            sendScancode(getTime(), RDP_KEYRELEASE | KBD_FLAG_QUIET, 0x38); // l.alt
        }
		if (lastKeyEvent.isControlDown()){
            sendScancode(getTime(), RDP_KEYRELEASE, 0x1d); // l.ctrl    
            //sendScancode(getTime(), RDP_KEYPRESS | KBD_FLAG_QUIET, 0x1d); // Ctrl
            //sendScancode(getTime(), RDP_KEYRELEASE | KBD_FLAG_QUIET, 0x1d); // ctrl
        }
		
	}

    /**
     * Send keypress events for any modifier keys that are currently down
     */
	public void setKeys() {
		if (!modifiersValid)
			return;


        if(lastKeyEvent == null) return;
        
		if (lastKeyEvent.isShiftDown())
			sendScancode(getTime(), RDP_KEYPRESS, 0x2a); // shift
		if (lastKeyEvent.isAltDown())
			sendScancode(getTime(), RDP_KEYPRESS, 0x38); // l.alt
		if (lastKeyEvent.isControlDown())
			sendScancode(getTime(), RDP_KEYPRESS, 0x1d); // l.ctrl
	}

	class RdesktopKeyAdapter extends KeyAdapter {

        /**
         * Construct an RdesktopKeyAdapter based on the parent KeyAdapter class
         */
		public RdesktopKeyAdapter() {
			super();
		}

        /**
         * Handle a keyPressed event, sending any relevant keypresses to the server
         */
		public void keyPressed(KeyEvent e) {
			lastKeyEvent = e;
			modifiersValid = true;
			long time = getTime();

			// Some java versions have keys that don't generate keyPresses -
			// here we add the key so we can later check if it happened
			pressedKeys.addElement(new Integer(e.getKeyCode()));

			logger.debug("PRESSED keychar='" + e.getKeyChar() + "' keycode=0x"
					+ Integer.toHexString(e.getKeyCode()) + " char='"
					+ ((char) e.getKeyCode()) + "'");

			if (rdp != null) {
				if (!handleSpecialKeys(time, e, true)) {
					sendKeyPresses(newKeyMapper.getKeyStrokes(e));
				}
				// sendScancode(time, RDP_KEYPRESS, keys.getScancode(e));
			}
		}

        /**
         * Handle a keyTyped event, sending any relevant keypresses to the server
         */
		public void keyTyped(KeyEvent e) {
			lastKeyEvent = e;
			modifiersValid = true;
			long time = getTime();

			// Some java versions have keys that don't generate keyPresses -
			// here we add the key so we can later check if it happened
			pressedKeys.addElement(new Integer(e.getKeyCode()));

			logger.debug("TYPED keychar='" + e.getKeyChar() + "' keycode=0x"
					+ Integer.toHexString(e.getKeyCode()) + " char='"
					+ ((char) e.getKeyCode()) + "'");

			if (rdp != null) {
				if (!handleSpecialKeys(time, e, true))
					sendKeyPresses(newKeyMapper.getKeyStrokes(e));
				// sendScancode(time, RDP_KEYPRESS, keys.getScancode(e));
			}
		}

        /**
         * Handle a keyReleased event, sending any relevent key events to the server
         */
		public void keyReleased(KeyEvent e) {
			// Some java versions have keys that don't generate keyPresses -
			// we added the key to the vector in keyPressed so here we check for
			// it
			Integer keycode = new Integer(e.getKeyCode());
			if (!pressedKeys.contains(keycode)) {
				this.keyPressed(e);
			}

			pressedKeys.removeElement(keycode);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -