You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by hu...@apache.org on 2014/01/03 11:17:45 UTC

[12/50] [abbrv] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
deleted file mode 100644
index 25631c2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
+++ /dev/null
@@ -1,245 +0,0 @@
-// 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 vncclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.ScreenDescription;
-
-public class VncInitializer extends OneTimeSwitch {
-
-    // Pad names
-    public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
-    public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
-
-    protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-
-    /**
-     * Properties of remote screen .
-     */
-    protected ScreenDescription screen;
-
-    public VncInitializer(String id, boolean shared, ScreenDescription screen) {
-        super(id);
-
-        setSharedFlag(shared);
-        this.screen = screen;
-
-        declarePads();
-    }
-
-    @Override
-    protected void declarePads() {
-        super.declarePads();
-        outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
-        outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
-    }
-
-    public ScreenDescription getScreen() {
-        return screen;
-    }
-
-    public void setScreen(ScreenDescription screen) {
-        this.screen = screen;
-    }
-
-    public void setSharedFlag(boolean shared) {
-        if (shared)
-            sharedFlag = RfbConstants.SHARED_ACCESS;
-        else
-            sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Server initialization message is at least 24 bytes long + length of
-        // desktop name
-        if (!cap(buf, 24, UNLIMITED, link, false))
-            return;
-
-        // Read server initialization message
-        // Read frame buffer size
-        int framebufferWidth = buf.readUnsignedShort();
-        int framebufferHeight = buf.readUnsignedShort();
-
-        // Read pixel format
-        int bitsPerPixel = buf.readUnsignedByte();
-        int depth = buf.readUnsignedByte();
-
-        int bigEndianFlag = buf.readUnsignedByte();
-        int trueColorFlag = buf.readUnsignedByte();
-
-        int redMax = buf.readUnsignedShort();
-        int greenMax = buf.readUnsignedShort();
-        int blueMax = buf.readUnsignedShort();
-
-        int redShift = buf.readUnsignedByte();
-        int greenShift = buf.readUnsignedByte();
-        int blueShift = buf.readUnsignedByte();
-
-        // Skip padding
-        buf.skipBytes(3);
-
-        // Read desktop name
-        int length = buf.readSignedInt();
-
-        // Consume exactly $length bytes, push back any extra bytes
-        if (!cap(buf, length, length, link, true))
-            return;
-
-        String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-        buf.unref();
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: " +
-                framebufferWidth + "x" + framebufferHeight + ".");
-
-        // Set screen properties
-        screen.setFramebufferSize(framebufferWidth, framebufferHeight);
-        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColorFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax,
-            redShift, greenShift, blueShift);
-        screen.setDesktopName(desktopName);
-
-        // If sever screen has different parameters than ours, then change it
-        if (!screen.isRGB888_32_LE()) {
-            // Send client pixel format
-            sendClientPixelFormat();
-        }
-
-        // Send encodings supported by client
-        sendSupportedEncodings();
-
-        switchOff();
-
-    }
-
-    @Override
-    protected void onStart() {
-        ByteBuffer buf = new ByteBuffer(new byte[] {sharedFlag});
-        pushDataToOTOut(buf);
-    }
-
-    private void sendClientPixelFormat() {
-        pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
-    }
-
-    private void sendSupportedEncodings() {
-        pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
-    }
-
-    @Override
-    public String toString() {
-        return "VncInit(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-        // System.setProperty("streamer.Link.debug", "true");
-        System.setProperty("streamer.Element.debug", "true");
-        // System.setProperty("streamer.Pipeline.debug", "true");
-
-        final String desktopName = "test";
-
-        Element source = new MockSource("source") {
-            {
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(
-                    // Send screen description
-                    new byte[] {
-                        // Framebuffer width (short)
-                        0, (byte)200,
-                        // Framebuffer height (short)
-                        0, 100,
-                        // Bits per pixel
-                        32,
-                        // Depth,
-                        24,
-                        // Endianness flag
-                        RfbConstants.LITTLE_ENDIAN,
-                        // Truecolor flag
-                        RfbConstants.TRUE_COLOR,
-                        // Red max (short)
-                        0, (byte)255,
-                        // Green max (short)
-                        0, (byte)255,
-                        // Blue max (short)
-                        0, (byte)255,
-                        // Red shift
-                        16,
-                        // Green shift
-                        8,
-                        // Blue shift
-                        0,
-                        // Padding
-                        0, 0, 0,
-                        // Desktop name length (int)
-                        0, 0, 0, 4,
-                        // Desktop name ("test", 4 bytes)
-                        't', 'e', 's', 't',
-
-                        // Tail
-                        1, 2, 3
-
-                    },
-                    // Tail packet
-                    new byte[] {4, 5, 6});
-            }
-        };
-
-        ScreenDescription screen = new ScreenDescription();
-        final VncInitializer init = new VncInitializer("init", true, screen);
-        Element initSink = new MockSink("initSink") {
-            {
-                // Expect shared flag
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {RfbConstants.SHARED_ACCESS});
-            }
-        };
-        Element mainSink = new MockSink("mainSink") {
-            {
-                // Expect two tail packets
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}, new byte[] {4, 5, 6});
-            }
-        };
-        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-        Element encodingsSink = new MockSink("encodings", emptyBuf);
-        Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, init, mainSink);
-        pipeline.add(encodingsSink, pixelFormatSink, initSink);
-        pipeline.link("init >otout", "initSink");
-        pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
-        pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-        if (!screen.isRGB888_32_LE())
-            System.err.println("Screen description was read incorrectly: " + screen + ".");
-        if (!desktopName.equals(screen.getDesktopName()))
-            System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
deleted file mode 100644
index 6421fb2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
+++ /dev/null
@@ -1,420 +0,0 @@
-// 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.BitmapOrder;
-import common.BitmapRectangle;
-import common.CopyRectOrder;
-import common.ScreenDescription;
-
-public class VncMessageHandler extends BaseElement {
-    protected ScreenDescription screen = null;
-
-    // Pad names
-    public static final String SERVER_BELL_ADAPTER_PAD = "bell";
-    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
-    public static final String PIXEL_ADAPTER_PAD = "pixels";
-    public static final String FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD = "fbur";
-
-    // Keys for metadata
-    public static final String CLIPBOARD_CONTENT = "content";
-    public static final String TARGET_X = "x";
-    public static final String TARGET_Y = "y";
-    public static final String WIDTH = "width";
-    public static final String HEIGHT = "height";
-    public static final String SOURCE_X = "srcX";
-    public static final String SOURCE_Y = "srcY";
-    public static final String PIXEL_FORMAT = "pixel_format";
-
-    private static final String NUM_OF_PROCESSED_RECTANGLES = "rects";
-    private static final String SAVED_CURSOR_POSITION = "cursor";
-
-    // Pixel format: RGB888 LE 32
-    public static final String RGB888LE32 = "RGB888LE32";
-
-    public VncMessageHandler(String id, ScreenDescription screen) {
-        super(id);
-        this.screen = screen;
-        declarePads();
-    }
-
-    private void declarePads() {
-        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-        outputPads.put(SERVER_CLIPBOARD_ADAPTER_PAD, null);
-        outputPads.put(PIXEL_ADAPTER_PAD, null);
-        outputPads.put(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, null);
-
-        inputPads.put("stdin", null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        try {
-            if (verbose)
-                System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-            if (!cap(buf, 1, UNLIMITED, link, false))
-                return;
-
-            // Read server message type
-            int messageType = buf.readUnsignedByte();
-
-            // Invoke packet handler by packet type.
-            switch (messageType) {
-
-                case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
-                    // Handle frame buffer update
-                    if (!handleFBU(buf, link))
-                        return;
-
-                    // Frame buffer update is received and fully processed, send request for
-                    // another frame buffer update to server.
-                    sendFBUR();
-
-                    break;
-                }
-
-                case RfbConstants.SERVER_BELL: {
-                    if (!handleBell(buf, link))
-                        return;
-                    break;
-                }
-
-                case RfbConstants.SERVER_CUT_TEXT: {
-                    if (!handleClipboard(buf, link))
-                        return;
-                    break;
-                }
-
-                default:
-                    // TODO: allow to extend functionality
-                    throw new RuntimeException("Unknown server packet type: " + messageType + ".");
-            }
-
-            // Cut tail, if any
-            cap(buf, 0, 0, link, true);
-        } finally {
-
-            // Return processed buffer back to pool
-            buf.unref();
-        }
-    }
-
-    private boolean handleClipboard(ByteBuffer buf, Link link) {
-        if (!cap(buf, 3 + 4, UNLIMITED, link, true))
-            return false;
-
-        // Skip padding
-        buf.skipBytes(3);
-
-        // Read text length
-        int length = buf.readSignedInt();
-
-        // We need full string to parse it
-        if (!cap(buf, length, UNLIMITED, link, true))
-            return false;
-
-        String content = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-
-        // Send content in metadata
-        ByteBuffer outBuf = new ByteBuffer(0);
-        outBuf.putMetadata(CLIPBOARD_CONTENT, content);
-
-        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
-
-        return true;
-    }
-
-    private boolean handleBell(ByteBuffer buf, Link link) {
-        // Send empty packet to bell adapter to produce bell
-        pushDataToPad(SERVER_BELL_ADAPTER_PAD, new ByteBuffer(0));
-
-        return true;
-    }
-
-    // FIXME: this method is too complex
-    private boolean handleFBU(ByteBuffer buf, Link link) {
-
-        // We need at least 3 bytes here, 1 - padding, 2 - number of rectangles
-        if (!cap(buf, 3, UNLIMITED, link, true))
-            return false;
-
-        buf.skipBytes(1);// Skip padding
-
-        // Read number of rectangles
-        int numberOfRectangles = buf.readUnsignedShort();
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Frame buffer update. Number of rectangles: " + numberOfRectangles + ".");
-
-        // Each rectangle must have header at least, header length is 12 bytes.
-        if (!cap(buf, 12 * numberOfRectangles, UNLIMITED, link, true))
-            return false;
-
-        // For all rectangles
-
-        // Restore saved point, to avoid flickering and performance problems when
-        // frame buffer update is split between few incoming packets.
-        int numberOfProcessedRectangles = (buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) != null) ? (Integer)buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) : 0;
-        if (buf.getMetadata(SAVED_CURSOR_POSITION) != null)
-            buf.cursor = (Integer)buf.getMetadata(SAVED_CURSOR_POSITION);
-
-        if (verbose && numberOfProcessedRectangles > 0)
-            System.out.println("[" + this + "] INFO: Restarting from saved point. Number of already processed rectangles: " + numberOfRectangles + ", cursor: " +
-                buf.cursor + ".");
-
-        // For all new rectangles
-        for (int i = numberOfProcessedRectangles; i < numberOfRectangles; i++) {
-
-            // We need coordinates of rectangle (2x4 bytes) and encoding type (4
-            // bytes)
-            if (!cap(buf, 12, UNLIMITED, link, true))
-                return false;
-
-            // Read coordinates of rectangle
-            int x = buf.readUnsignedShort();
-            int y = buf.readUnsignedShort();
-            int width = buf.readUnsignedShort();
-            int height = buf.readUnsignedShort();
-
-            // Read rectangle encoding
-            int encodingType = buf.readSignedInt();
-
-            // Process rectangle
-            switch (encodingType) {
-
-                case RfbConstants.ENCODING_RAW: {
-                    if (!handleRawRectangle(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                case RfbConstants.ENCODING_COPY_RECT: {
-                    if (!handleCopyRect(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                case RfbConstants.ENCODING_DESKTOP_SIZE: {
-                    if (!handleScreenSizeChangeRect(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                default:
-                    // TODO: allow to extend functionality
-                    throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
-            }
-
-            // Update information about processed rectangles to avoid handling of same
-            // rectangle multiple times.
-            // TODO: push back partial rectangle only instead
-            buf.putMetadata(NUM_OF_PROCESSED_RECTANGLES, ++numberOfProcessedRectangles);
-            buf.putMetadata(SAVED_CURSOR_POSITION, buf.cursor);
-        }
-
-        return true;
-    }
-
-    private boolean handleScreenSizeChangeRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Remote screen size is changed
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Screen size rect. Width: " + width + ", height: " + height + ".");
-
-        screen.setFramebufferSize(width, height);
-
-        return true;
-    }
-
-    private boolean handleCopyRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Copy rectangle from one part of screen to another.
-        // Areas may overlap. Antialiasing may cause visible artifacts.
-
-        // We need 4 bytes with coordinates of source rectangle
-        if (!cap(buf, 4, UNLIMITED, link, true))
-            return false;
-
-        CopyRectOrder order = new CopyRectOrder();
-
-        order.srcX = buf.readUnsignedShort();
-        order.srcY = buf.readUnsignedShort();
-        order.x = x;
-        order.y = y;
-        order.width = width;
-        order.height = height;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Copy rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", srcX: " + order.srcX +
-                ", srcY: " + order.srcY + ".");
-
-        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-
-        return true;
-    }
-
-    private boolean handleRawRectangle(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Raw rectangle is just array of pixels to draw on screen.
-        int rectDataLength = width * height * screen.getBytesPerPixel();
-
-        // We need at least rectDataLength bytes. Extra bytes may contain other
-        // rectangles.
-        if (!cap(buf, rectDataLength, UNLIMITED, link, true))
-            return false;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: " + rectDataLength +
-                ".");
-
-        BitmapRectangle rectangle = new BitmapRectangle();
-        rectangle.x = x;
-        rectangle.y = y;
-        rectangle.width = width;
-        rectangle.height = height;
-        rectangle.bufferWidth = width;
-        rectangle.bufferHeight = height;
-        rectangle.bitmapDataStream = buf.readBytes(rectDataLength);
-        rectangle.colorDepth = screen.getColorDeph();
-
-        BitmapOrder order = new BitmapOrder();
-        order.rectangles = new BitmapRectangle[] {rectangle};
-
-        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-        return true;
-    }
-
-    @Override
-    public void onStart() {
-        // Send Frame Buffer Update request
-        sendFBUR();
-    }
-
-    private void sendFBUR() {
-        ByteBuffer buf = new ByteBuffer(0);
-        buf.putMetadata("incremental", true);
-        pushDataToPad(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, buf);
-    }
-
-    @Override
-    public String toString() {
-        return "VNCMessageHandler(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String[] args) {
-
-        // System.setProperty("streamer.Link.debug", "true");
-        System.setProperty("streamer.Element.debug", "true");
-        // System.setProperty("streamer.Pipeline.debug", "true");
-
-        Element source = new MockSource("source") {
-            {
-                // Split messages at random boundaries to check "pushback" logic
-                bufs =
-                    ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-                        // Message type: server bell
-                        RfbConstants.SERVER_BELL,
-
-                        // Message type: clipboard text
-                        RfbConstants.SERVER_CUT_TEXT,
-                        // Padding
-                        0, 0, 0,
-                        // Length (test)
-                        0, 0, 0, 4,
-
-                    }, new byte[] {
-                        // Clipboard text
-                        't', 'e', 's', 't',
-
-                        // Message type: frame buffer update
-                        RfbConstants.SERVER_FRAMEBUFFER_UPDATE,
-                        // Padding
-                        0,
-                        // Number of rectangles
-                        0, 3,},
-
-                        new byte[] {
-
-                            // x, y, width, height: 0x0@4x4
-                            0, 0, 0, 0, 0, 4, 0, 4,
-                            // Encoding: desktop size
-                            (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 24) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 8) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 0) & 0xff),},
-
-                        new byte[] {
-
-                            // x, y, width, height: 0x0@4x4
-                            0, 0, 0, 0, 0, 4, 0, 4,
-                            // Encoding: raw rect
-                            (byte)((RfbConstants.ENCODING_RAW >> 24) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_RAW >> 8) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 0) & 0xff),
-                            // Raw pixel data 4x4x1 bpp
-                            1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}, new byte[] {11, 12, 13, 14, 15, 16,
-
-                            // x, y, width, height: 0x0@2x2
-                            0, 0, 0, 0, 0, 2, 0, 2,
-                            // Encoding: copy rect
-                            (byte)((RfbConstants.ENCODING_COPY_RECT >> 24) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_COPY_RECT >> 8) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 0) & 0xff),
-                            // srcX, srcY: 2x2
-                            0, 2, 0, 2,});
-            }
-        };
-
-        ScreenDescription screen = new ScreenDescription() {
-            {
-                this.bytesPerPixel = 1;
-            }
-        };
-
-        final Element handler = new VncMessageHandler("handler", screen);
-
-        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-        Element fburSink = new MockSink("fbur", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}, new byte[] {}));
-        Element bellSink = new MockSink("bell", emptyBuf);
-        Element clipboardSink = new MockSink("clipboard", emptyBuf);
-        Element desktopSizeChangeSink = new MockSink("desktop_size", emptyBuf);
-        Element pixelsSink = new MockSink("pixels", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,}));
-        Element copyRectSink = new MockSink("copy_rect", emptyBuf);
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, handler);
-        pipeline.add(fburSink, bellSink, clipboardSink, desktopSizeChangeSink, pixelsSink, copyRectSink);
-
-        pipeline.link("handler >" + FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, "fbur");
-        pipeline.link("handler >" + SERVER_BELL_ADAPTER_PAD, "bell");
-        pipeline.link("handler >" + SERVER_CLIPBOARD_ADAPTER_PAD, "clipboard");
-        pipeline.link("handler >" + PIXEL_ADAPTER_PAD, "pixels");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
new file mode 100755
index 0000000..6b50e35
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
@@ -0,0 +1,369 @@
+// 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 vncclient.adapter;
+
+import java.awt.event.KeyEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+import common.KeyOrder;
+
+public class AwtVncKeyboardAdapter extends BaseElement {
+
+    protected boolean sh = false;
+    protected boolean caps = false;
+    protected boolean num = false;
+
+    public AwtVncKeyboardAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        KeyOrder order = (KeyOrder)buf.getOrder();
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(8);
+        outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
+
+        outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
+        outBuf.writeShort(0); // padding
+        outBuf.writeInt(map_en_us(order));
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Return key scan code (in lower byte) and extended flags (in second byte).
+     */
+    private int map_en_us(KeyOrder order) {
+
+        switch (order.event.getKeyCode()) {
+        // Functional keys
+        case KeyEvent.VK_ESCAPE:
+            return 0xff1b;
+        case KeyEvent.VK_F1:
+            return 0xffbe;
+        case KeyEvent.VK_F2:
+            return 0xffbf;
+        case KeyEvent.VK_F3:
+            return 0xffc0;
+        case KeyEvent.VK_F4:
+            return 0xffc1;
+        case KeyEvent.VK_F5:
+            return 0xffc2;
+        case KeyEvent.VK_F6:
+            return 0xffc3;
+        case KeyEvent.VK_F7:
+            return 0xffc4;
+        case KeyEvent.VK_F8:
+            return 0xffc5;
+        case KeyEvent.VK_F9:
+            return 0xffc6;
+        case KeyEvent.VK_F10:
+            return 0xffc7;
+        case KeyEvent.VK_F11:
+            return 0xffc8;
+        case KeyEvent.VK_F12:
+            return 0xffc9;
+
+            // Row #1
+        case KeyEvent.VK_BACK_QUOTE:
+            return (sh) ? '~' : '`';
+        case KeyEvent.VK_1:
+            return (sh) ? '!' : '1';
+        case KeyEvent.VK_2:
+            return (sh) ? '@' : '2';
+        case KeyEvent.VK_3:
+            return (sh) ? '#' : '3';
+        case KeyEvent.VK_4:
+            return (sh) ? '$' : '4';
+        case KeyEvent.VK_5:
+            return (sh) ? '%' : '5';
+        case KeyEvent.VK_6:
+            return (sh) ? '^' : '6';
+        case KeyEvent.VK_7:
+            return (sh) ? '&' : '7';
+        case KeyEvent.VK_8:
+            return (sh) ? '*' : '8';
+        case KeyEvent.VK_9:
+            return (sh) ? '(' : '9';
+        case KeyEvent.VK_0:
+            return (sh) ? ')' : '0';
+        case KeyEvent.VK_MINUS:
+            return (sh) ? '_' : '-';
+        case KeyEvent.VK_EQUALS:
+            return (sh) ? '+' : '=';
+        case KeyEvent.VK_BACK_SPACE:
+            return 0xff08;
+
+            // Row #2
+        case KeyEvent.VK_TAB:
+            return 0xff09;
+        case KeyEvent.VK_Q:
+            return (sh ^ caps) ? 'Q' : 'q';
+        case KeyEvent.VK_W:
+            return (sh ^ caps) ? 'W' : 'w';
+        case KeyEvent.VK_E:
+            return (sh ^ caps) ? 'E' : 'e';
+        case KeyEvent.VK_R:
+            return (sh ^ caps) ? 'R' : 'r';
+        case KeyEvent.VK_T:
+            return (sh ^ caps) ? 'T' : 't';
+        case KeyEvent.VK_Y:
+            return (sh ^ caps) ? 'Y' : 'y';
+        case KeyEvent.VK_U:
+            return (sh ^ caps) ? 'U' : 'u';
+        case KeyEvent.VK_I:
+            return (sh ^ caps) ? 'I' : 'i';
+        case KeyEvent.VK_O:
+            return (sh ^ caps) ? 'O' : 'o';
+        case KeyEvent.VK_P:
+            return (sh ^ caps) ? 'P' : 'p';
+        case KeyEvent.VK_OPEN_BRACKET:
+            return (sh) ? '{' : '[';
+        case KeyEvent.VK_CLOSE_BRACKET:
+            return (sh) ? '{' : ']';
+        case KeyEvent.VK_ENTER:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_STANDARD:
+                return 0xff0d;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xff8d;
+            }
+
+            // Row #3
+        case KeyEvent.VK_CAPS_LOCK:
+            if (order.pressed)
+                caps = !caps;
+            return 0xFFE5;
+        case KeyEvent.VK_A:
+            return (sh ^ caps) ? 'A' : 'a';
+        case KeyEvent.VK_S:
+            return (sh ^ caps) ? 'S' : 's';
+        case KeyEvent.VK_D:
+            return (sh ^ caps) ? 'D' : 'd';
+        case KeyEvent.VK_F:
+            return (sh ^ caps) ? 'F' : 'f';
+        case KeyEvent.VK_G:
+            return (sh ^ caps) ? 'G' : 'g';
+        case KeyEvent.VK_H:
+            return (sh ^ caps) ? 'H' : 'h';
+        case KeyEvent.VK_J:
+            return (sh ^ caps) ? 'J' : 'j';
+        case KeyEvent.VK_K:
+            return (sh ^ caps) ? 'K' : 'k';
+        case KeyEvent.VK_L:
+            return (sh ^ caps) ? 'L' : 'l';
+        case KeyEvent.VK_SEMICOLON:
+            return (sh) ? ':' : ';';
+        case KeyEvent.VK_QUOTE:
+            return (sh) ? '"' : '\'';
+
+            // Row #4
+        case KeyEvent.VK_SHIFT:
+            sh = !sh;
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xffe1;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xffe2;
+            }
+        case KeyEvent.VK_BACK_SLASH:
+            return (sh) ? '|' : '\\';
+        case KeyEvent.VK_Z:
+            return (sh ^ caps) ? 'Z' : 'z';
+        case KeyEvent.VK_X:
+            return (sh ^ caps) ? 'X' : 'x';
+        case KeyEvent.VK_C:
+            return (sh ^ caps) ? 'C' : 'c';
+        case KeyEvent.VK_V:
+            return (sh ^ caps) ? 'V' : 'v';
+        case KeyEvent.VK_B:
+            return (sh ^ caps) ? 'B' : 'b';
+        case KeyEvent.VK_N:
+            return (sh ^ caps) ? 'N' : 'n';
+        case KeyEvent.VK_M:
+            return (sh ^ caps) ? 'M' : 'M';
+        case KeyEvent.VK_COMMA:
+            return (sh) ? '<' : ',';
+        case KeyEvent.VK_PERIOD:
+            return (sh) ? '>' : '.';
+        case KeyEvent.VK_SLASH:
+            return (sh) ? '?' : '/';
+
+            //
+            // Bottom row
+        case KeyEvent.VK_CONTROL:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE3;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE4;
+            }
+        case KeyEvent.VK_WINDOWS:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFED; // HyperL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEE; // HyperR
+            }
+        case KeyEvent.VK_META:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE7; // MetaL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE8; // MetaR
+            }
+
+        case KeyEvent.VK_ALT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE9;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEA;
+            }
+        case KeyEvent.VK_ALT_GRAPH:
+            return 0xfe03;
+
+        case KeyEvent.VK_SPACE:
+            return ' ';
+
+        case KeyEvent.VK_CONTEXT_MENU:
+            return 0xff67;
+
+            //
+            // Special keys
+        case KeyEvent.VK_PRINTSCREEN:
+            return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
+        case KeyEvent.VK_SCROLL_LOCK:
+            return 0xFF14;
+        case KeyEvent.VK_PAUSE:
+            return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
+
+            // Text navigation keys
+        case KeyEvent.VK_INSERT:
+            return 0xff63;
+        case KeyEvent.VK_DELETE:
+            return 0xffff;
+        case KeyEvent.VK_HOME:
+            return 0xff50;
+        case KeyEvent.VK_END:
+            return 0xff57;
+        case KeyEvent.VK_PAGE_UP:
+            return 0xff55;
+        case KeyEvent.VK_PAGE_DOWN:
+            return 0xff56;
+
+            // Cursor keys
+        case KeyEvent.VK_LEFT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff51;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF96;
+            }
+        case KeyEvent.VK_UP:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff52;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF97;
+            }
+        case KeyEvent.VK_RIGHT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff53;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF98;
+            }
+        case KeyEvent.VK_DOWN:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff54;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF99;
+            }
+
+            // Keypad
+        case KeyEvent.VK_NUM_LOCK:
+            if (order.pressed)
+                num = !num;
+            return 0xFF6F;
+        case KeyEvent.VK_DIVIDE:
+            return 0xFFAF;
+        case KeyEvent.VK_MULTIPLY:
+            return 0xFFAA;
+        case KeyEvent.VK_SUBTRACT:
+            return 0xFFAD;
+        case KeyEvent.VK_ADD:
+            return 0xFFAB;
+
+        case KeyEvent.VK_KP_LEFT:
+            return 0xFF96;
+        case KeyEvent.VK_KP_UP:
+            return 0xFF97;
+        case KeyEvent.VK_KP_RIGHT:
+            return 0xFF98;
+        case KeyEvent.VK_KP_DOWN:
+            return 0xFF99;
+
+        case KeyEvent.VK_NUMPAD0:
+            return 0xFFB0;
+        case KeyEvent.VK_NUMPAD1:
+            return 0xFFB1;
+        case KeyEvent.VK_NUMPAD2:
+            return 0xFFB2;
+        case KeyEvent.VK_NUMPAD3:
+            return 0xFFB3;
+        case KeyEvent.VK_NUMPAD4:
+            return 0xFFB4;
+        case KeyEvent.VK_NUMPAD5:
+            return 0xFFB5;
+        case KeyEvent.VK_NUMPAD6:
+            return 0xFFB6;
+        case KeyEvent.VK_NUMPAD7:
+            return 0xFFB7;
+        case KeyEvent.VK_NUMPAD8:
+            return 0xFFB8;
+        case KeyEvent.VK_NUMPAD9:
+            return 0xFFB9;
+        case KeyEvent.VK_DECIMAL:
+            return 0xFFAE;
+
+        default:
+            System.err.println("Key is not mapped: " + order + ".");
+            return ' '; // Space
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
new file mode 100755
index 0000000..59216d3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
@@ -0,0 +1,71 @@
+// 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 vncclient.adapter;
+
+import java.awt.event.InputEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+import common.MouseOrder;
+
+public class AwtVncMouseAdapter extends BaseElement {
+
+    public AwtVncMouseAdapter(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(6);
+
+        outBuf.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
+
+        int buttonMask = mapAwtModifiersToVncButtonMask(order.event.getModifiersEx());
+        outBuf.writeByte(buttonMask);
+        outBuf.writeShort(order.event.getX());
+        outBuf.writeShort(order.event.getY());
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Current state of buttons 1 to 8 are represented by bits 0 to 7 of
+     * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
+     * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
+     * right buttons on the mouse. On a wheel mouse, each step of the wheel
+     * upwards is represented by a press and release of button 4, and each step
+     * downwards is represented by a press and release of button 5.
+     *
+     * @param modifiers
+     *          extended modifiers from AWT mouse event
+     * @return VNC mouse button mask
+     */
+    public static int mapAwtModifiersToVncButtonMask(int modifiers) {
+        int mask = (((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0)
+                | (((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
+        return mask;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
new file mode 100755
index 0000000..5dfa831
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
@@ -0,0 +1,63 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class EncodingsMessage extends BaseElement {
+
+    protected final int[] encodings;
+
+    public EncodingsMessage(String id, int[] encodings) {
+        super(id);
+        this.encodings = encodings;
+        declarePads();
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(4 + encodings.length * 4);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
+
+        outBuf.writeByte(0);// padding
+
+        outBuf.writeShort(encodings.length);
+
+        for (int i = 0; i < encodings.length; i++) {
+            outBuf.writeInt(encodings[i]);
+        }
+
+        pushDataToAllOuts(outBuf);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
new file mode 100755
index 0000000..ee94c60
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
@@ -0,0 +1,126 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.ScreenDescription;
+
+public class FrameBufferUpdateRequest extends BaseElement {
+    // TODO: use object with fields instead of raw values in map
+    public static final String INCREMENTAL_UPDATE = "incremental";
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+
+    protected ScreenDescription screen;
+
+    public FrameBufferUpdateRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        Boolean incremental = (Boolean)buf.getMetadata(INCREMENTAL_UPDATE);
+        Integer x = (Integer)buf.getMetadata(TARGET_X);
+        Integer y = (Integer)buf.getMetadata(TARGET_Y);
+        Integer width = (Integer)buf.getMetadata(WIDTH);
+        Integer height = (Integer)buf.getMetadata(HEIGHT);
+        buf.unref();
+
+        // Set default values when parameters are not set
+        if (incremental == null)
+            incremental = false;
+
+        if (x == null)
+            x = 0;
+        if (y == null)
+            y = 0;
+
+        if (width == null)
+            width = screen.getFramebufferWidth();
+        if (height == null)
+            height = screen.getFramebufferHeight();
+
+        ByteBuffer outBuf = new ByteBuffer(10);
+
+        outBuf.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
+        outBuf.writeByte((incremental) ? RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST : RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST);
+        outBuf.writeShort(x);
+        outBuf.writeShort(y);
+        outBuf.writeShort(width);
+        outBuf.writeShort(height);
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("dimensions", width + "x" + height + "@" + x + "x" + y);
+        }
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        ScreenDescription screen = new ScreenDescription();
+        screen.setFramebufferSize(120, 80);
+        Element adapter = new FrameBufferUpdateRequest("renderer", screen);
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Request
+                RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST,
+                // Full update (redraw area)
+                RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST,
+                // X
+                0, 1,
+                // Y
+                0, 2,
+                // Width
+                0, 3,
+                // Height
+                0, 4}));
+
+        ByteBuffer buf = new ByteBuffer(new byte[0]);
+        buf.putMetadata(TARGET_X, 1);
+        buf.putMetadata(TARGET_Y, 2);
+        buf.putMetadata(WIDTH, 3);
+        buf.putMetadata(HEIGHT, 4);
+
+        Element source = new MockSource("source", new ByteBuffer[] {buf});
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(source, adapter, sink);
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
new file mode 100755
index 0000000..2350f14
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
@@ -0,0 +1,89 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import common.ScreenDescription;
+
+public class RGB888LE32PixelFormatRequest extends BaseElement {
+    protected int bitsPerPixel = 32;
+    protected int depth = 24;
+    protected int bigEndianFlag = RfbConstants.LITTLE_ENDIAN;
+    protected int trueColourFlag = RfbConstants.TRUE_COLOR;
+    protected int redMax = 255;
+    protected int greenMax = 255;
+    protected int blueMax = 255;
+    protected int redShift = 0;
+    protected int greenShift = 8;
+    protected int blueShift = 16;
+
+    protected ScreenDescription screen;
+
+    public RGB888LE32PixelFormatRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(20);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        // Send pixel format
+        outBuf.writeByte(bitsPerPixel);
+        outBuf.writeByte(depth);
+        outBuf.writeByte(bigEndianFlag);
+        outBuf.writeByte(trueColourFlag);
+        outBuf.writeShort(redMax);
+        outBuf.writeShort(greenMax);
+        outBuf.writeShort(blueMax);
+        outBuf.writeByte(redShift);
+        outBuf.writeByte(greenShift);
+        outBuf.writeByte(blueShift);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax,
+                blueMax, redShift, greenShift, blueShift);
+
+        pushDataToAllOuts(outBuf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
new file mode 100755
index 0000000..a3895d4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
@@ -0,0 +1,85 @@
+// 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 vncclient.vnc;
+
+import java.nio.charset.Charset;
+
+public interface RfbConstants {
+
+    public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
+    public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
+    public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
+
+    /**
+     * Server message types.
+     */
+    final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
+
+    /**
+     * Client message types.
+     */
+    public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
+            CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
+
+    /**
+     * Server authorization type
+     */
+    public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
+
+    /**
+     * Server authorization reply.
+     */
+    public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
+
+    /**
+     * Encodings.
+     */
+    public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
+
+    /**
+     * Pseudo-encodings.
+     */
+    public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
+
+    /**
+     * Encodings, which we support.
+     */
+    public final static int[] SUPPORTED_ENCODINGS_ARRAY = {ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE};
+
+    /**
+     * Frame buffer update request type: update of whole screen or partial update.
+     */
+    public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
+
+    public static final int KEY_UP = 0, KEY_DOWN = 1;
+
+    public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
+
+    public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
+
+    public static final int PALETTE = 0, TRUE_COLOR = 1;
+
+    /**
+     * Default 8 bit charset to use when communicating with server.
+     */
+    public static final Charset US_ASCII_CHARSET = Charset.availableCharsets().get("US-ASCII");
+
+    /**
+     * Default 16 bit charset to use when communicating with server.
+     */
+    public static final Charset UCS2_CHARSET = Charset.availableCharsets().get("UTF-16LE");
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
new file mode 100755
index 0000000..6fdb3b1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
@@ -0,0 +1,292 @@
+// 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 vncclient.vnc;
+
+import java.security.spec.KeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class Vnc33Authentication extends OneTimeSwitch {
+
+    /**
+     * Password to use when authentication is required.
+     */
+    protected String password = null;
+
+    /**
+     * Authentication stage:
+     * <ul>
+     * <li>0 - challenge received, response must be sent
+     * <li>1 - authentication result received.
+     * </ul>
+     */
+    protected int stage = 0;
+
+    public Vnc33Authentication(String id) {
+        super(id);
+    }
+
+    public Vnc33Authentication(String id, String password) {
+        super(id);
+        this.password = password;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        switch (stage) {
+        case 0: // Read security with optional challenge and response
+            stage0(buf, link);
+
+            break;
+        case 1: // Read authentication response
+            stage1(buf, link);
+            break;
+        }
+
+    }
+
+    /**
+     * Read security type. If connection type is @see
+     * RfbConstants.CONNECTION_FAILED, then throw exception. If connection type is @see
+     * RfbConstants.NO_AUTH, then switch off this element. If connection type is @see
+     * RfbConstants.VNC_AUTH, then read challenge, send encoded password, and read
+     * authentication response.
+     */
+    private void stage0(ByteBuffer buf, Link link) {
+        // At least 4 bytes are necessary
+        if (!cap(buf, 4, UNLIMITED, link, true))
+            return;
+
+        // Read security type
+        int authType = buf.readSignedInt();
+
+        switch (authType) {
+        case RfbConstants.CONNECTION_FAILED: {
+            // Server forbids to connect. Read reason and throw exception
+
+            int length = buf.readSignedInt();
+            String reason = new String(buf.data, buf.offset, length, RfbConstants.US_ASCII_CHARSET);
+
+            throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
+        }
+
+        case RfbConstants.NO_AUTH: {
+            // Client can connect without authorization. Nothing to do.
+            // Switch off this element from circuit
+            switchOff();
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH: {
+            // Read challenge and generate response
+            responseToChallenge(buf, link);
+            break;
+        }
+
+        default:
+            throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
+        }
+
+    }
+
+    private void responseToChallenge(ByteBuffer buf, Link link) {
+        // Challenge is exactly 16 bytes long
+        if (!cap(buf, 16, 16, link, true))
+            return;
+
+        ByteBuffer challenge = buf.slice(buf.cursor, 16, true);
+        buf.unref();
+
+        // Encode challenge with password
+        ByteBuffer response;
+        try {
+            response = encodePassword(challenge, password);
+            challenge.unref();
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
+        }
+
+        if (verbose) {
+            response.putMetadata("sender", this);
+        }
+
+        // Send encoded challenge
+        nextStage();
+        pushDataToOTOut(response);
+
+    }
+
+    private void nextStage() {
+        stage++;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Next stage: " + stage + ".");
+    }
+
+    /**
+     * Encode password using DES encryption with given challenge.
+     *
+     * @param challenge
+     *          a random set of bytes.
+     * @param password
+     *          a password
+     * @return DES hash of password and challenge
+     */
+    public ByteBuffer encodePassword(ByteBuffer challenge, String password) {
+        if (challenge.length != 16)
+            throw new RuntimeException("Challenge must be exactly 16 bytes long.");
+
+        // VNC password consist of up to eight ASCII characters.
+        byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; // Padding
+        byte[] passwordAsciiBytes = password.getBytes(RfbConstants.US_ASCII_CHARSET);
+        System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
+
+        // Flip bytes (reverse bits) in key
+        for (int i = 0; i < key.length; i++) {
+            key[i] = flipByte(key[i]);
+        }
+
+        try {
+            KeySpec desKeySpec = new DESKeySpec(key);
+            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
+            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+            ByteBuffer buf = new ByteBuffer(cipher.doFinal(challenge.data, challenge.offset, challenge.length));
+
+            return buf;
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encode password.", e);
+        }
+    }
+
+    /**
+     * Reverse bits in byte, so least significant bit will be most significant
+     * bit. E.g. 01001100 will become 00110010.
+     *
+     * See also: http://www.vidarholen.net/contents/junk/vnc.html ,
+     * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
+     *
+     * @param b
+     *          a byte
+     * @return byte in reverse order
+     */
+    private static byte flipByte(byte b) {
+        int b1_8 = (b & 0x1) << 7;
+        int b2_7 = (b & 0x2) << 5;
+        int b3_6 = (b & 0x4) << 3;
+        int b4_5 = (b & 0x8) << 1;
+        int b5_4 = (b & 0x10) >>> 1;
+        int b6_3 = (b & 0x20) >>> 3;
+        int b7_2 = (b & 0x40) >>> 5;
+        int b8_1 = (b & 0x80) >>> 7;
+        byte c = (byte)(b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
+        return c;
+    }
+
+    /**
+     * Read authentication result, send nothing.
+     */
+    private void stage1(ByteBuffer buf, Link link) {
+        // Read authentication response
+        if (!cap(buf, 4, 4, link, false))
+            return;
+
+        int authResult = buf.readSignedInt();
+
+        switch (authResult) {
+        case RfbConstants.VNC_AUTH_OK: {
+            // Nothing to do
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Authentication successfull.");
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH_TOO_MANY:
+            throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
+
+        case RfbConstants.VNC_AUTH_FAILED:
+            throw new RuntimeException("Connection to VNC server failed: wrong password.");
+
+        default:
+            throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
+        }
+
+        switchOff();
+
+    }
+
+    @Override
+    public String toString() {
+        return "VNC3.3 Authentication(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        final String password = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Request authentication and send 16 byte challenge
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+                        // Respond to challenge with AUTH_OK
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH_OK});
+            }
+        };
+
+        Element mainSink = new FakeSink("mainSink");
+        final Vnc33Authentication auth = new Vnc33Authentication("auth", password);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect encoded password
+                bufs = new ByteBuffer[] {auth.encodePassword(new ByteBuffer(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), password)};
+            }
+        };
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, auth, mainSink);
+        pipeline.add(initSink);
+        pipeline.link("auth >otout", "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
new file mode 100755
index 0000000..812c6a8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
@@ -0,0 +1,116 @@
+// 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 vncclient.vnc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import streamer.ByteBuffer;
+import streamer.InputStreamSource;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.OutputStreamSink;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+
+/**
+ * VNC server sends hello packet with RFB protocol version, e.g.
+ * "RFB 003.007\n". We need to send response packet with supported protocol
+ * version, e.g. "RFB 003.003\n".
+ */
+public class Vnc33Hello extends OneTimeSwitch {
+
+    public Vnc33Hello(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Initial packet is exactly 12 bytes long
+        if (!cap(buf, 12, 12, link, false))
+            return;
+
+        // Read protocol version
+        String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+
+        // Server should use RFB protocol 3.x
+        if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
+            throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
+
+        // Send response: we support RFB 3.3 only
+        String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
+
+        ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
+        }
+
+        pushDataToOTOut(outBuf);
+
+        // Switch off this element from circuit
+        switchOff();
+
+    }
+
+    @Override
+    public String toString() {
+        return "Vnc3.3 Hello(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
+        ByteArrayOutputStream initOS = new ByteArrayOutputStream();
+        ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
+        InputStreamSource inputStreamSource = new InputStreamSource("source", is);
+        OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
+
+        Vnc33Hello hello = new Vnc33Hello("hello");
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
+        pipeline.add(new OutputStreamSink("initSink", initOS));
+
+        pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+        String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+
+        if (!"RFB 003.003\n".equals(initOut))
+            System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
+
+        if (!"test".equals(mainOut))
+            System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
new file mode 100755
index 0000000..0b96c73
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
@@ -0,0 +1,245 @@
+// 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 vncclient.vnc;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.ScreenDescription;
+
+public class VncInitializer extends OneTimeSwitch {
+
+    // Pad names
+    public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
+    public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
+
+    protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+
+    /**
+     * Properties of remote screen .
+     */
+    protected ScreenDescription screen;
+
+    public VncInitializer(String id, boolean shared, ScreenDescription screen) {
+        super(id);
+
+        setSharedFlag(shared);
+        this.screen = screen;
+
+        declarePads();
+    }
+
+    @Override
+    protected void declarePads() {
+        super.declarePads();
+        outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
+        outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
+    }
+
+    public ScreenDescription getScreen() {
+        return screen;
+    }
+
+    public void setScreen(ScreenDescription screen) {
+        this.screen = screen;
+    }
+
+    public void setSharedFlag(boolean shared) {
+        if (shared)
+            sharedFlag = RfbConstants.SHARED_ACCESS;
+        else
+            sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Server initialization message is at least 24 bytes long + length of
+        // desktop name
+        if (!cap(buf, 24, UNLIMITED, link, false))
+            return;
+
+        // Read server initialization message
+        // Read frame buffer size
+        int framebufferWidth = buf.readUnsignedShort();
+        int framebufferHeight = buf.readUnsignedShort();
+
+        // Read pixel format
+        int bitsPerPixel = buf.readUnsignedByte();
+        int depth = buf.readUnsignedByte();
+
+        int bigEndianFlag = buf.readUnsignedByte();
+        int trueColorFlag = buf.readUnsignedByte();
+
+        int redMax = buf.readUnsignedShort();
+        int greenMax = buf.readUnsignedShort();
+        int blueMax = buf.readUnsignedShort();
+
+        int redShift = buf.readUnsignedByte();
+        int greenShift = buf.readUnsignedByte();
+        int blueShift = buf.readUnsignedByte();
+
+        // Skip padding
+        buf.skipBytes(3);
+
+        // Read desktop name
+        int length = buf.readSignedInt();
+
+        // Consume exactly $length bytes, push back any extra bytes
+        if (!cap(buf, length, length, link, true))
+            return;
+
+        String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: "
+                    + framebufferWidth + "x" + framebufferHeight + ".");
+
+        // Set screen properties
+        screen.setFramebufferSize(framebufferWidth, framebufferHeight);
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColorFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax, redShift,
+                greenShift, blueShift);
+        screen.setDesktopName(desktopName);
+
+        // If sever screen has different parameters than ours, then change it
+        if (!screen.isRGB888_32_LE()) {
+            // Send client pixel format
+            sendClientPixelFormat();
+        }
+
+        // Send encodings supported by client
+        sendSupportedEncodings();
+
+        switchOff();
+
+    }
+
+    @Override
+    protected void onStart() {
+        ByteBuffer buf = new ByteBuffer(new byte[] {sharedFlag});
+        pushDataToOTOut(buf);
+    }
+
+    private void sendClientPixelFormat() {
+        pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    private void sendSupportedEncodings() {
+        pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    @Override
+    public String toString() {
+        return "VncInit(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        final String desktopName = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Send screen description
+                        new byte[] {
+                                // Framebuffer width (short)
+                                0, (byte)200,
+                                // Framebuffer height (short)
+                                0, 100,
+                                // Bits per pixel
+                                32,
+                                // Depth,
+                                24,
+                                // Endianness flag
+                                RfbConstants.LITTLE_ENDIAN,
+                                // Truecolor flag
+                                RfbConstants.TRUE_COLOR,
+                                // Red max (short)
+                                0, (byte)255,
+                                // Green max (short)
+                                0, (byte)255,
+                                // Blue max (short)
+                                0, (byte)255,
+                                // Red shift
+                                16,
+                                // Green shift
+                                8,
+                                // Blue shift
+                                0,
+                                // Padding
+                                0, 0, 0,
+                                // Desktop name length (int)
+                                0, 0, 0, 4,
+                                // Desktop name ("test", 4 bytes)
+                                't', 'e', 's', 't',
+
+                                // Tail
+                                1, 2, 3
+
+                        },
+                        // Tail packet
+                        new byte[] {4, 5, 6});
+            }
+        };
+
+        ScreenDescription screen = new ScreenDescription();
+        final VncInitializer init = new VncInitializer("init", true, screen);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect shared flag
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {RfbConstants.SHARED_ACCESS});
+            }
+        };
+        Element mainSink = new MockSink("mainSink") {
+            {
+                // Expect two tail packets
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}, new byte[] {4, 5, 6});
+            }
+        };
+        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
+        Element encodingsSink = new MockSink("encodings", emptyBuf);
+        Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, init, mainSink);
+        pipeline.add(encodingsSink, pixelFormatSink, initSink);
+        pipeline.link("init >otout", "initSink");
+        pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
+        pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        if (!screen.isRGB888_32_LE())
+            System.err.println("Screen description was read incorrectly: " + screen + ".");
+        if (!desktopName.equals(screen.getDesktopName()))
+            System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
+
+    }
+}