// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package rdpclient.adapter; import java.awt.event.InputEvent; import streamer.BaseElement; import streamer.ByteBuffer; import streamer.Link; import common.MouseOrder; /** * @see http://msdn.microsoft.com/en-us/library/cc240594.aspx */ public class AwtRdpMouseAdapter extends BaseElement { public final static int FASTPATH_INPUT_EVENT_MOUSE = 0x01; /** * Event is a mouse wheel rotation. The only valid flags in a wheel rotation * event are PTRFLAGS_WHEEL_NEGATIVE and the WheelRotationMask; all other * pointer flags are ignored. */ public final static int PTRFLAGS_WHEEL = 0x0200; /** * Wheel rotation value (contained in the WheelRotationMask bit field) is * negative and MUST be sign-extended before injection at the server. */ public final static int PTRFLAGS_WHEEL_NEGATIVE = 0x0100; /** * Bit field describing the number of rotation units the mouse wheel was * rotated. The value is negative if the PTRFLAGS_WHEEL_NEGATIVE flag is set. */ public final static int WHEEL_ROTATION_MASK = 0x01FF; /** * Indicates that the mouse position MUST be updated to the location specified * by the xPos and yPos fields. */ public final static int PTRFLAGS_MOVE = 0x0800; /** * Indicates that a click event has occurred at the position specified by the * xPos and yPos fields. The button flags indicate which button has been * clicked and at least one of these flags MUST be set. */ public final static int PTRFLAGS_DOWN = 0x8000; /** * Mouse button 1 (left button) was clicked or released. If the PTRFLAGS_DOWN * flag is set, then the button was clicked, otherwise it was released. */ public final static int PTRFLAGS_BUTTON1 = 0x1000; /** * Mouse button 2 (right button) was clicked or released. If the PTRFLAGS_DOWN * flag is set, then the button was clicked, otherwise it was released. */ public final static int PTRFLAGS_BUTTON2 = 0x2000; /** * Mouse button 3 (middle button or wheel) was clicked or released. If the * PTRFLAGS_DOWN flag is set, then the button was clicked, otherwise it was * released. */ public final static int PTRFLAGS_BUTTON3 = 0x4000; public AwtRdpMouseAdapter(String id) { super(id); } @Override public void handleData(ByteBuffer buf, Link link) { if (verbose) System.out.println("[" + this + "] INFO: Data received: " + buf + "."); // Get mouse event MouseOrder order = (MouseOrder)buf.getOrder(); ByteBuffer outBuf = new ByteBuffer(7, true); // eventHeader (1 byte): An 8-bit, unsigned integer. EventCode bitfield (top // 3 bits) MUST be set to FASTPATH_INPUT_EVENT_MOUSE (1). The // eventFlags bitfield (low 5 bits) MUST be zeroed out. outBuf.writeByte(FASTPATH_INPUT_EVENT_MOUSE << 5); // pointerFlags (2 bytes): A 16-bit, unsigned integer. outBuf.writeShortLE(getPointerFlags(order)); // xPos (2 bytes): A 16-bit, unsigned integer. The x-coordinate of the // pointer. outBuf.writeShortLE(order.event.getX()); // yPos (2 bytes): A 16-bit, unsigned integer. The y-coordinate of the // pointer. outBuf.writeShortLE(order.event.getY()); // Push buffer to one pad only, so it can be modified without copying of // data pushDataToPad(STDOUT, outBuf); } // Remember mouse buttons protected boolean button1, button2, button3; protected int getPointerFlags(MouseOrder order) { int flags = 0; int modifiers = order.event.getModifiersEx(); if (order.pressed) { // Mouse pressed flags |= PTRFLAGS_DOWN; // Check, which one of buttons is released boolean b1 = ((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && !button1; boolean b2 = ((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && !button2; boolean b3 = ((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && !button3; if (b1) { flags |= PTRFLAGS_BUTTON1; button1 = true; } if (b2) { flags |= PTRFLAGS_BUTTON3; button2 = true; } if (b3) { flags |= PTRFLAGS_BUTTON2; button3 = true; } } else if (order.released) { // Mouse released // Check, which one of buttons is released boolean b1 = !((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && button1; boolean b2 = !((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && button2; boolean b3 = !((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && button3; if (b1) { flags |= PTRFLAGS_BUTTON1; button1 = false; } if (b2) { flags |= PTRFLAGS_BUTTON3; button2 = false; } if (b3) { flags |= PTRFLAGS_BUTTON2; button3 = false; } } else { // Mouse moved flags |= PTRFLAGS_MOVE; } return flags; } }