package com.iiordanov.bVNC; import com.freerdp.freerdpcore.application.SessionState; import com.freerdp.freerdpcore.domain.ManualBookmark; import com.freerdp.freerdpcore.services.LibFreeRDP; import com.iiordanov.bVNC.input.RemoteKeyboard; import com.iiordanov.bVNC.input.RdpKeyboardMapper; import com.iiordanov.bVNC.input.RemoteRdpPointer; public class RdpCommunicator implements RfbConnectable, RdpKeyboardMapper.KeyProcessingListener { static final String TAG = "RdpCommunicator"; final static int VK_CONTROL = 0x11; final static int VK_LCONTROL = 0xA2; final static int VK_RCONTROL = 0xA3; final static int VK_LMENU = 0xA4; final static int VK_RMENU = 0xA5; final static int VK_LSHIFT = 0xA0; final static int VK_RSHIFT = 0xA1; final static int VK_LWIN = 0x5B; final static int VK_RWIN = 0x5C; final static int VK_EXT_KEY = 0x00000100; SessionState session; int metaState = 0; boolean isInNormalProtocol = false; RdpCommunicator (SessionState session) { this.session = session; } @Override public void setIsInNormalProtocol (boolean state) { isInNormalProtocol = state; } @Override public int framebufferWidth() { return session.getBookmark().getActiveScreenSettings().getWidth(); } @Override public int framebufferHeight() { return session.getBookmark().getActiveScreenSettings().getHeight(); } @Override public String desktopName() { return ((ManualBookmark)session.getBookmark()).getHostname(); } @Override public void requestUpdate(boolean incremental) { // NOT USED for RDP. } @Override public void writeClientCutText(String text) { LibFreeRDP.sendClipboardData(session.getInstance(), text); } @Override public boolean isInNormalProtocol() { return isInNormalProtocol; } @Override public String getEncoding() { return "RDP"; } @Override public void writePointerEvent(int x, int y, int metaState, int pointerMask) { this.metaState = metaState; if ((pointerMask & RemoteRdpPointer.PTRFLAGS_DOWN) != 0) { sendModifierKeys(true); } try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendCursorEvent(session.getInstance(), x, y, pointerMask); if ((pointerMask & RemoteRdpPointer.PTRFLAGS_DOWN) == 0) { sendModifierKeys(false); } } @Override public void writeKeyEvent(int key, int metaState, boolean down) { // Not used for actually sending keyboard events, but rather to record the current metastate. // The key event is sent to the KeyboardMapper from RemoteRdpKeyboard, and // when processed through the keyboard mapper, it ends up in one of the KeyProcessingListener // methods defined here. this.metaState = metaState; } @Override public void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian, boolean trueColour, int redMax, int greenMax, int blueMax, int redShift, int greenShift, int blueShift, boolean fGreyScale) { // NOT USED for RDP. } @Override public void writeFramebufferUpdateRequest(int x, int y, int w, int h, boolean b) { // NOT USED for RDP. } public class DisconnectThread extends Thread { long instance; public DisconnectThread (long i) { this.instance = i; } public void run () { LibFreeRDP.disconnect(instance); //LibFreeRDP.freeInstance(instance); } } @Override public void close() { setIsInNormalProtocol(false); long instance = session.getInstance(); DisconnectThread d = new DisconnectThread(instance); d.start(); } private void sendModifierKeys (boolean down) { if ((metaState & RemoteKeyboard.CTRL_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending LCTRL " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_LCONTROL, down); } if ((metaState & RemoteKeyboard.RCTRL_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending RCTRL " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_RCONTROL, down); } if ((metaState & RemoteKeyboard.ALT_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending LALT " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_LMENU, down); } if ((metaState & RemoteKeyboard.RALT_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending RALT " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_RMENU, down); } if ((metaState & RemoteKeyboard.SUPER_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending LSUPER " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_LWIN | VK_EXT_KEY, down); } if ((metaState & RemoteKeyboard.RSUPER_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending RSUPER " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_RWIN | VK_EXT_KEY, down); } if ((metaState & RemoteKeyboard.SHIFT_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending LSHIFT " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_LSHIFT, down); } if ((metaState & RemoteKeyboard.RSHIFT_MASK) != 0) { //android.util.Log.e("RdpCommunicator", "Sending RSHIFT " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), VK_RSHIFT, down); } } // **************************************************************************** // KeyboardMapper.KeyProcessingListener implementation @Override public void processVirtualKey(int virtualKeyCode, boolean down) { if (down) { sendModifierKeys(true); } //android.util.Log.e("RdpCommunicator", "Sending VK key: " + virtualKeyCode + ". Is it down: " + down); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendKeyEvent(session.getInstance(), virtualKeyCode, down); if (!down) { sendModifierKeys(false); } } @Override public void processUnicodeKey(int unicodeKey) { android.util.Log.e(TAG, "Unicode character: " + unicodeKey); sendModifierKeys(true); try { Thread.sleep(5); } catch (InterruptedException e) {} LibFreeRDP.sendUnicodeKeyEvent(session.getInstance(), unicodeKey); sendModifierKeys(false); } @Override public void switchKeyboard(int keyboardType) { // This is functionality specific to aFreeRDP. } @Override public void modifiersChanged() { // This is functionality specific to aFreeRDP. } @Override public void requestResolution(int x, int y) { // TODO Auto-generated method stub } }