diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
new file mode 100644
index 0000000..4f9d1b2
--- /dev/null
+++ b/.ycm_extra_conf.py
@@ -0,0 +1,35 @@
+# Vim YouCompleteMe completion configuration.
+#
+# See doc/topics/ycm.md for details.
+
+import os
+
+repo_root = os.path.dirname(os.path.abspath(__file__))
+
+# Paths in the compilation flags must be absolute to allow ycm to find them from
+# any working directory.
+def AbsolutePath(path):
+  return os.path.join(repo_root, path)
+
+flags = [
+    '-I', AbsolutePath('src'),
+    '-I', AbsolutePath('../tigervnc/common'),
+    '-I', AbsolutePath('../libvncserver'),
+    '-I', AbsolutePath('../../system/core/include'),
+    '-I', AbsolutePath('../../frameworks/native/include'),
+    '-Wall',
+    '-Werror',
+    '-Wextra',
+    '-pedantic',
+    '-Wno-newline-eof',
+    '-Wwrite-strings',
+    '-std=c++11',
+    '-x', 'c++'
+]
+
+def FlagsForFile(filename, **kwargs):
+    return {
+        'flags': flags,
+        'do_cache': True
+    }
+
diff --git a/Android.mk b/Android.mk
index 5f52278..57db5b0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -4,36 +4,34 @@
 
 LOCAL_SRC_FILES := \
     src/InputDevice.cpp \
-    src/VNCFlinger.cpp \
+    src/AndroidDesktop.cpp \
     src/main.cpp
 
-LOCAL_SRC_FILES += \
-    aidl/org/chemlab/IVNCService.aidl
+#LOCAL_SRC_FILES += \
+#    aidl/org/chemlab/IVNCService.aidl
 
 LOCAL_C_INCLUDES += \
     $(LOCAL_PATH)/src \
-    external/libvncserver \
-    external/zlib
+    external/tigervnc/common \
 
 LOCAL_SHARED_LIBRARIES := \
     libbinder \
     libcrypto \
     libcutils \
-    libjpeg \
     libgui \
-    libpng \
+    libjpeg \
     libssl \
     libui \
     libutils \
     libz
 
 LOCAL_STATIC_LIBRARIES += \
-    libvncserver
+    libtigervnc
 
 LOCAL_CFLAGS := -DVNCFLINGER_VERSION="0.1"
-LOCAL_CFLAGS += -Ofast -Werror -std=c++11
+LOCAL_CFLAGS += -Ofast -Werror -std=c++11 -fexceptions
 
-#LOCAL_CFLAGS += -DLOG_NDEBUG=0
+LOCAL_CFLAGS += -DLOG_NDEBUG=0
 #LOCAL_CXX := /usr/bin/include-what-you-use
 
 LOCAL_INIT_RC := etc/vncflinger.rc
diff --git a/src/AndroidDesktop.cpp b/src/AndroidDesktop.cpp
new file mode 100644
index 0000000..a37500c
--- /dev/null
+++ b/src/AndroidDesktop.cpp
@@ -0,0 +1,340 @@
+#define LOG_TAG "AndroidDesktop"
+#include <utils/Log.h>
+
+#include <fcntl.h>
+#include <sys/eventfd.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include <ui/DisplayInfo.h>
+
+#include <rfb/PixelFormat.h>
+#include <rfb/Rect.h>
+#include <rfb/ScreenSet.h>
+#include <rfb/VNCServerST.h>
+
+#include "AndroidDesktop.h"
+#include "InputDevice.h"
+
+using namespace vncflinger;
+using namespace android;
+
+const rfb::PixelFormat AndroidDesktop::sRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+
+AndroidDesktop::AndroidDesktop() {
+    mListener = new FrameListener(this);
+    mInputDevice = new InputDevice();
+
+    mEventFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+    if (mEventFd < 0) {
+        ALOGE("Failed to create event notifier");
+        return;
+    }
+}
+
+AndroidDesktop::~AndroidDesktop() {
+    mInputDevice->stop();
+    close(mEventFd);
+}
+
+void AndroidDesktop::start(rfb::VNCServer* vs) {
+    Mutex::Autolock _l(mMutex);
+
+    sp<ProcessState> self = ProcessState::self();
+    self->startThreadPool();
+
+    mMainDpy = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
+    if (updateDisplayProjection() == NO_INIT) {
+        ALOGE("Failed to query display!");
+        return;
+    }
+    mProjectionChanged = false;
+
+    status_t err = createVirtualDisplay();
+    if (err != NO_ERROR) {
+        ALOGE("Failed to create virtual display: err=%d", err);
+        return;
+    }
+
+    mInputDevice->start_async(mWidth, mHeight);
+
+    mServer = (rfb::VNCServerST*)vs;
+
+    updateFBSize(mWidth, mHeight);
+
+    mServer->setPixelBuffer(mPixels.get());
+
+    ALOGV("Desktop is running");
+}
+
+void AndroidDesktop::stop() {
+    Mutex::Autolock _L(mMutex);
+
+    ALOGV("Shutting down");
+
+    mServer->setPixelBuffer(0);
+    destroyVirtualDisplay();
+    mWidth = 0;
+    mHeight = 0;
+}
+
+status_t AndroidDesktop::createVirtualDisplay() {
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&mProducer, &consumer);
+    mCpuConsumer = new CpuConsumer(consumer, 1);
+    mCpuConsumer->setName(String8("vds-to-cpu"));
+    mCpuConsumer->setDefaultBufferSize(mWidth, mHeight);
+    mProducer->setMaxDequeuedBufferCount(4);
+    consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBX_8888);
+
+    mCpuConsumer->setFrameAvailableListener(mListener);
+
+    mDpy = SurfaceComposerClient::createDisplay(String8("VNC-VirtualDisplay"), false /*secure*/);
+
+    // aspect ratio
+    float displayAspect = (float) mSourceHeight / (float) mSourceWidth;
+
+    uint32_t outWidth, outHeight;
+    if (mWidth > (uint32_t)(mWidth * displayAspect)) {
+        // limited by narrow width; reduce height
+        outWidth = mWidth;
+        outHeight = (uint32_t)(mWidth * displayAspect);
+    } else {
+        // limited by short height; restrict width
+        outHeight = mHeight;
+        outWidth = (uint32_t)(mHeight / displayAspect);
+    }
+
+    // position the desktop in the viewport while preserving
+    // the source aspect ratio. we do this in case the client
+    // has resized the window and to deal with orientation
+    // changes set up by updateDisplayProjection
+    uint32_t offX, offY;
+    offX = (mWidth - outWidth) / 2;
+    offY = (mHeight - outHeight) / 2;
+    mDisplayRect = Rect(offX, offY, offX + outWidth, offY + outHeight);
+    Rect sourceRect(0, 0, mSourceWidth, mSourceHeight);
+
+    SurfaceComposerClient::openGlobalTransaction();
+    SurfaceComposerClient::setDisplaySurface(mDpy, mProducer);
+    SurfaceComposerClient::setDisplayProjection(mDpy, 0, sourceRect, mDisplayRect);
+    SurfaceComposerClient::setDisplayLayerStack(mDpy, 0);  // default stack
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    mVDSActive = true;
+
+    ALOGV("Virtual display (%lux%lu [viewport=%ux%u] created", mWidth, mHeight,
+            outWidth, outHeight);
+
+    return NO_ERROR;
+}
+
+status_t AndroidDesktop::destroyVirtualDisplay() {
+    if (!mVDSActive) {
+        return NO_INIT;
+    }
+
+    mCpuConsumer.clear();
+    mProducer.clear();
+    SurfaceComposerClient::destroyDisplay(mDpy);
+
+    mVDSActive = false;
+
+    ALOGV("Virtual display destroyed");
+
+    return NO_ERROR;
+}
+
+void AndroidDesktop::processDesktopResize() {
+    if (mProjectionChanged) {
+        destroyVirtualDisplay();
+        createVirtualDisplay();
+        updateFBSize(mWidth, mHeight);
+        mInputDevice->reconfigure(mDisplayRect.getWidth(), mDisplayRect.getHeight());
+        rfb::ScreenSet screens;
+        screens.add_screen(rfb::Screen(0, 0, 0, mWidth, mHeight, 0));
+        mServer->setScreenLayout(screens);
+
+        mProjectionChanged = false;
+    }
+}
+
+void AndroidDesktop::processFrames() {
+    Mutex::Autolock _l(mMutex);
+
+    // do any pending resize
+    processDesktopResize();
+
+    if (!mFrameAvailable) {
+        return;
+    }
+
+    // get a frame from the virtual display
+    CpuConsumer::LockedBuffer imgBuffer;
+    status_t res = mCpuConsumer->lockNextBuffer(&imgBuffer);
+    if (res != OK) {
+        ALOGE("Failed to lock next buffer: %s (%d)", strerror(-res), res);
+        return;
+    }
+
+    mFrameNumber = imgBuffer.frameNumber;
+    ALOGV("processFrame: [%lu] format: %x (%dx%d, stride=%d)", mFrameNumber, imgBuffer.format,
+          imgBuffer.width, imgBuffer.height, imgBuffer.stride);
+
+    // we don't know if there was a stride change until we get
+    // a buffer from the queue. if it changed, we need to resize
+
+    rfb::Rect bufRect(0, 0, imgBuffer.width, imgBuffer.height);
+
+    // performance is extremely bad if the gpu memory is used
+    // directly without copying because it is likely uncached
+    mPixels->imageRect(bufRect, imgBuffer.data, imgBuffer.stride);
+
+    mCpuConsumer->unlockBuffer(imgBuffer);
+
+    // update clients
+    mServer->add_changed(bufRect);
+    mFrameAvailable = false;
+}
+
+// notifies the server loop that we have changes
+void AndroidDesktop::notify() {
+    static uint64_t notify = 1;
+    write(mEventFd, &notify, sizeof(notify));
+}
+
+// called when a client resizes the window
+unsigned int AndroidDesktop::setScreenLayout(int reqWidth, int reqHeight,
+                                             const rfb::ScreenSet& layout) {
+    Mutex::Autolock _l(mMutex);
+
+    char* dbg = new char[1024];
+    layout.print(dbg, 1024);
+
+    ALOGD("setScreenLayout: cur: %lux%lu  new: %dx%d %s", mWidth, mHeight, reqWidth, reqHeight, dbg);
+    delete[] dbg;
+
+    if (reqWidth == (int)mWidth && reqHeight == (int)mHeight) {
+        return rfb::resultInvalid;
+    }
+
+    if (reqWidth > 0 && reqHeight > 0) {
+        mWidth = reqWidth;
+        mHeight = reqHeight;
+
+        if (updateDisplayProjection() == NO_ERROR) {
+            // resize immediately
+            processDesktopResize();
+            notify();
+            return rfb::resultSuccess;
+        }
+    }
+    return rfb::resultInvalid;
+}
+
+// updates the pixelbuffer dimensions
+bool AndroidDesktop::updateFBSize(uint64_t width, uint64_t height) {
+    if (mPixels == nullptr || mPixels->height() != (int)height || mPixels->width() != (int)width) {
+        if (mPixels != nullptr) {
+            ALOGD("updateFBSize: old=[%dx%d] new=[%lux%lu]", mPixels->width(), mPixels->height(),
+                  width, height);
+        }
+        if (mPixels != nullptr && (int)width <= mPixels->width() &&
+            (int)height <= mPixels->height()) {
+            mPixels->setSize(width, height);
+        } else {
+            mPixels = new AndroidPixelBuffer(width, height);
+            mServer->setPixelBuffer(mPixels.get());
+        }
+        return true;
+    }
+    return false;
+}
+
+// cpuconsumer frame listener, called from binder thread
+void AndroidDesktop::FrameListener::onFrameAvailable(const BufferItem& item) {
+    Mutex::Autolock _l(mDesktop->mMutex);
+    mDesktop->updateDisplayProjection();
+    mDesktop->mFrameAvailable = true;
+    mDesktop->notify();
+    ALOGV("onFrameAvailable: [%lu] mTimestamp=%ld", item.mFrameNumber, item.mTimestamp);
+}
+
+rfb::Point AndroidDesktop::getFbSize() {
+    return rfb::Point(mPixels->width(), mPixels->height());
+}
+
+void AndroidDesktop::keyEvent(rdr::U32 key, bool down) {
+    mInputDevice->keyEvent(down, key);
+}
+
+void AndroidDesktop::pointerEvent(const rfb::Point& pos, int buttonMask) {
+    if (pos.x < mDisplayRect.left || pos.x > mDisplayRect.right ||
+            pos.y < mDisplayRect.top || pos.y > mDisplayRect.bottom) {
+        // outside viewport
+        return;
+    }
+    uint32_t x = pos.x * ((float)(mDisplayRect.getWidth()) / (float)mWidth);
+    uint32_t y = pos.y * ((float)(mDisplayRect.getHeight()) / (float)mHeight);
+
+    ALOGD("pointer xlate x1=%d y1=%d x2=%d y2=%d", pos.x, pos.y, x, y);
+
+    mServer->setCursorPos(rfb::Point(x, y));
+    mInputDevice->pointerEvent(buttonMask, x, y);
+}
+
+// figure out the dimensions of the display. deal with orientation
+// changes, client-side window resize, server-side scaling, and
+// maintaining aspect ratio.
+status_t AndroidDesktop::updateDisplayProjection() {
+    DisplayInfo info;
+    status_t err = SurfaceComposerClient::getDisplayInfo(mMainDpy, &info);
+    if (err != NO_ERROR) {
+        ALOGE("Failed to get display characteristics\n");
+        return err;
+    }
+
+    bool deviceRotated =
+        info.orientation != DISPLAY_ORIENTATION_0 && info.orientation != DISPLAY_ORIENTATION_180;
+
+    // if orientation changed, swap width/height
+    uint32_t sourceWidth, sourceHeight;
+    if (!deviceRotated) {
+        sourceWidth = info.w;
+        sourceHeight = info.h;
+    } else {
+        sourceHeight = info.w;
+        sourceWidth = info.h;
+    }
+
+    if (mWidth == 0 && mHeight == 0) {
+        mWidth = sourceWidth;
+        mHeight = sourceHeight;
+    }
+
+    if (deviceRotated != mRotated) {
+        std::swap(mWidth, mHeight);
+        mRotated = deviceRotated;
+    }
+
+    // if nothing changed, we're done
+    if (mSourceWidth == sourceWidth && mSourceHeight == sourceHeight &&
+        (int)mWidth == mPixels->width() && (int)mHeight == mPixels->height()) {
+        return NO_ERROR;
+    }
+
+    // update all the values and flag for an update
+    mSourceWidth = sourceWidth;
+    mSourceHeight = sourceHeight;
+    mProjectionChanged = true;
+
+    ALOGV("Dimensions: %lux%lu [out: %lux%lu] rotated=%d", mSourceWidth, mSourceHeight, mWidth,
+          mHeight, mRotated);
+
+    return NO_ERROR;
+}
diff --git a/src/AndroidDesktop.h b/src/AndroidDesktop.h
new file mode 100644
index 0000000..0d3f8e4
--- /dev/null
+++ b/src/AndroidDesktop.h
@@ -0,0 +1,124 @@
+#ifndef ANDROID_DESKTOP_H_
+#define ANDROID_DESKTOP_H_
+
+#include <memory>
+
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/Thread.h>
+
+#include <gui/CpuConsumer.h>
+
+#include <rfb/PixelBuffer.h>
+#include <rfb/SDesktop.h>
+#include <rfb/VNCServerST.h>
+
+#include "InputDevice.h"
+
+
+using namespace android;
+
+namespace vncflinger {
+
+static const rfb::PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+
+class AndroidDesktop : public rfb::SDesktop, public RefBase {
+  public:
+    AndroidDesktop();
+
+    virtual ~AndroidDesktop();
+
+    virtual void start(rfb::VNCServer* vs);
+    virtual void stop();
+
+    virtual rfb::Point getFbSize();
+    virtual unsigned int setScreenLayout(int fb_width, int fb_height, const rfb::ScreenSet& layout);
+
+    virtual void keyEvent(rdr::U32 key, bool down);
+    virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
+
+    virtual void processFrames();
+
+    virtual int getEventFd() {
+        return mEventFd;
+    }
+
+  private:
+    class FrameListener : public CpuConsumer::FrameAvailableListener {
+      public:
+        FrameListener(AndroidDesktop* desktop) : mDesktop(desktop) {
+        }
+
+        virtual void onFrameAvailable(const BufferItem& item);
+
+      private:
+        FrameListener(FrameListener&) {
+        }
+        AndroidDesktop* mDesktop;
+    };
+
+    class AndroidPixelBuffer : public RefBase, public rfb::ManagedPixelBuffer {
+      public:
+        AndroidPixelBuffer(uint64_t width, uint64_t height)
+            : rfb::ManagedPixelBuffer(sRGBX, width, height) {
+        }
+    };
+
+    virtual status_t createVirtualDisplay();
+    virtual status_t destroyVirtualDisplay();
+
+    virtual void notify();
+
+    virtual status_t updateDisplayProjection();
+    virtual bool updateFBSize(uint64_t width, uint64_t height);
+    virtual void processDesktopResize();
+
+    uint64_t mSourceWidth, mSourceHeight;
+    uint64_t mWidth, mHeight;
+    Rect mDisplayRect;
+
+    bool mRotated;
+
+    Mutex mMutex;
+
+    bool mFrameAvailable;
+    bool mProjectionChanged;
+    bool mRotate;
+    bool mVDSActive;
+
+    uint64_t mFrameNumber;
+    nsecs_t mFrameStartWhen;
+
+    int mEventFd;
+
+    // Android virtual display is always 32-bit
+    static const rfb::PixelFormat sRGBX;
+
+    // Server instance
+    rfb::VNCServerST* mServer;
+
+    // Pixel buffer
+    sp<AndroidPixelBuffer> mPixels;
+
+    // Primary display
+    sp<IBinder> mMainDpy;
+
+    // Virtual display
+    sp<IBinder> mDpy;
+
+    // Producer side of queue, passed into the virtual display.
+    sp<IGraphicBufferProducer> mProducer;
+
+    // This receives frames from the virtual display and makes them available
+    sp<CpuConsumer> mCpuConsumer;
+
+    // Listener for virtual display buffers
+    sp<FrameListener> mListener;
+
+    // Virtual input device
+    sp<InputDevice> mInputDevice;
+};
+};
+
+#endif
diff --git a/src/InputDevice.cpp b/src/InputDevice.cpp
index a4b6d7c..04bad97 100644
--- a/src/InputDevice.cpp
+++ b/src/InputDevice.cpp
@@ -18,6 +18,8 @@
 #define LOG_TAG "VNC-InputDevice"
 #include <utils/Log.h>
 
+#include <future>
+
 #include "InputDevice.h"
 
 #include <fcntl.h>
@@ -28,11 +30,8 @@
 #include <linux/input.h>
 #include <linux/uinput.h>
 
-#include <rfb/keysym.h>
-
 using namespace android;
 
-ANDROID_SINGLETON_STATIC_INSTANCE(InputDevice)
 
 static const struct UInputOptions {
     int cmd;
@@ -51,11 +50,16 @@
     {UI_SET_PROPBIT, INPUT_PROP_DIRECT},
 };
 
+status_t InputDevice::start_async(uint32_t width, uint32_t height) {
+    // don't block the caller since this can take a few seconds
+    std::async(&InputDevice::start, this, width, height);
+
+    return NO_ERROR;
+}
+
 status_t InputDevice::start(uint32_t width, uint32_t height) {
     Mutex::Autolock _l(mLock);
 
-    status_t err = OK;
-
     mLeftClicked = mMiddleClicked = mRightClicked = false;
 
     struct input_id id = {
@@ -111,6 +115,8 @@
         goto err_ioctl;
     }
 
+    mOpened = true;
+
     ALOGD("Virtual input device created successfully (%dx%d)", width, height);
     return NO_ERROR;
 
@@ -124,11 +130,14 @@
 
 status_t InputDevice::reconfigure(uint32_t width, uint32_t height) {
     stop();
-    return start(width, height);
+    return start_async(width, height);
 }
 
 status_t InputDevice::stop() {
     Mutex::Autolock _l(mLock);
+
+    mOpened = false;
+
     if (mFD < 0) {
         return OK;
     }
@@ -187,20 +196,15 @@
     return release(code);
 }
 
-void InputDevice::onKeyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) {
-    InputDevice::getInstance().keyEvent(down, key, cl);
-}
-
-void InputDevice::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) {
+void InputDevice::keyEvent(bool down, uint32_t key) {
     int code;
     int sh = 0;
     int alt = 0;
 
-    if (mFD < 0) return;
-
     Mutex::Autolock _l(mLock);
+    if (!mOpened) return;
 
-    if ((code = keysym2scancode(key, cl, &sh, &alt))) {
+    if ((code = keysym2scancode(key, &sh, &alt))) {
         int ret = 0;
 
         if (key && down) {
@@ -231,17 +235,12 @@
     }
 }
 
-void InputDevice::onPointerEvent(int buttonMask, int x, int y, rfbClientPtr cl) {
-    InputDevice::getInstance().pointerEvent(buttonMask, x, y, cl);
-}
-
-void InputDevice::pointerEvent(int buttonMask, int x, int y, rfbClientPtr /* cl  */) {
-    if (mFD < 0) return;
+void InputDevice::pointerEvent(int buttonMask, int x, int y) {
+    Mutex::Autolock _l(mLock);
+    if (!mOpened) return;
 
     ALOGV("pointerEvent: buttonMask=%x x=%d y=%d", buttonMask, x, y);
 
-    Mutex::Autolock _l(mLock);
-
     if ((buttonMask & 1) && mLeftClicked) {  // left btn clicked and moving
         inject(EV_ABS, ABS_X, x);
         inject(EV_ABS, ABS_Y, y);
@@ -314,7 +313,7 @@
 static const int spec4[] = {26, 43, 27, 215, 14};
 static const int spec4sh[] = {1, 1, 1, 1, 0};
 
-int InputDevice::keysym2scancode(rfbKeySym c, rfbClientPtr cl, int* sh, int* alt) {
+int InputDevice::keysym2scancode(uint32_t c, int* sh, int* alt) {
     int real = 1;
     if ('a' <= c && c <= 'z') return qwerty[c - 'a'];
     if ('A' <= c && c <= 'Z') {
@@ -372,9 +371,6 @@
         //	return 232;// end -> DPAD_CENTER (ball click)
         case 0xff50:
             return KEY_HOME;  // home
-        case 0xFFC8:
-            rfbShutdownServer(cl->screen, TRUE);
-            return 0;  // F11 disconnect
         case 0xffff:
             return 158;  // del -> back
         case 0xff55:
diff --git a/src/InputDevice.h b/src/InputDevice.h
index 1744478..be4367f 100644
--- a/src/InputDevice.h
+++ b/src/InputDevice.h
@@ -20,32 +20,33 @@
 
 #include <utils/Errors.h>
 #include <utils/Mutex.h>
-#include <utils/Singleton.h>
+#include <utils/RefBase.h>
 
 #include <linux/uinput.h>
-#include <rfb/rfb.h>
+
 
 #define UINPUT_DEVICE "/dev/uinput"
 
 namespace android {
 
-class InputDevice : public Singleton<InputDevice> {
-    friend class Singleton;
-
+class InputDevice : public RefBase {
   public:
     virtual status_t start(uint32_t width, uint32_t height);
+    virtual status_t start_async(uint32_t width, uint32_t height);
     virtual status_t stop();
     virtual status_t reconfigure(uint32_t width, uint32_t height);
 
-    static void onKeyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
-    static void onPointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
+    virtual void keyEvent(bool down, uint32_t key);
+    virtual void pointerEvent(int buttonMask, int x, int y);
 
     InputDevice() : mFD(-1) {
     }
     virtual ~InputDevice() {
+        stop();
     }
 
   private:
+
     status_t inject(uint16_t type, uint16_t code, int32_t value);
     status_t injectSyn(uint16_t type, uint16_t code, int32_t value);
     status_t movePointer(int32_t x, int32_t y);
@@ -54,14 +55,12 @@
     status_t release(uint16_t code);
     status_t click(uint16_t code);
 
-    void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
-    void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
-
-    int keysym2scancode(rfbKeySym c, rfbClientPtr cl, int* sh, int* alt);
+    int keysym2scancode(uint32_t c, int* sh, int* alt);
 
     Mutex mLock;
 
     int mFD;
+    bool mOpened;
 
     struct uinput_user_dev mUserDev;
 
diff --git a/src/VNCFlinger.cpp b/src/VNCFlinger.cpp
deleted file mode 100644
index b910453..0000000
--- a/src/VNCFlinger.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-//
-// vncflinger - Copyright (C) 2017 Steve Kondik
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-#define LOG_TAG "VNCFlinger"
-#include <utils/Log.h>
-
-#include <fstream>
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <ui/PixelFormat.h>
-
-#include "InputDevice.h"
-#include "VNCFlinger.h"
-
-using namespace android;
-
-VNCFlinger::VNCFlinger() {
-    mOrientation = -1;
-    mScale = 1.0f;
-    mMainDpy = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
-    updateDisplayProjection();
-
-    createVNCServer();
-
-    String8 v4("127.0.0.1");
-    String8 v6("::1");
-
-    setV4Address(v4);
-    setV6Address(v6);
-}
-
-status_t VNCFlinger::setV4Address(const String8& address) {
-    if (!rfbStringToAddr(const_cast<char *>(address.string()), &(mVNCScreen->listenInterface))) {
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::setV6Address(const String8& address) {
-    mVNCScreen->listen6Interface = const_cast<char *>(address.string());
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::setPort(unsigned int port) {
-    if (port > 65535) {
-        port = 0;
-    }
-    if (port == 0) {
-        mVNCScreen->autoPort = 1;
-    } else {
-        mVNCScreen->autoPort = 0;
-        mVNCScreen->port = port;
-        mVNCScreen->ipv6port = port;
-    }
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::setScale(float scale) {
-    if (scale <= 0.0f || scale > 2.0f) {
-        return BAD_VALUE;
-    }
-    mScale = scale;
-    updateDisplayProjection();
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::clearPassword() {
-    std::remove(VNC_AUTH_FILE);
-    ALOGW("Password authentication disabled");
-    mVNCScreen->authPasswdData = NULL;
-    return OK;
-}
-
-status_t VNCFlinger::setPassword(const String8& passwd) {
-    String8 path(VNC_AUTH_FILE);
-    if (rfbEncryptAndStorePasswd(const_cast<char *>(passwd.string()),
-                                 const_cast<char *>(path.string())) != 0) {
-        ALOGE("Failed to set password");
-        return BAD_VALUE;
-    }
-    ALOGI("Password has been set");
-    mVNCScreen->authPasswdData = (void *)VNC_AUTH_FILE;
-    return OK;
-}
-
-status_t VNCFlinger::start() {
-    sp<ProcessState> self = ProcessState::self();
-    self->startThreadPool();
-
-    status_t err = startVNCServer();
-    if (err != NO_ERROR) {
-        ALOGE("Failed to start VNCFlinger: err=%d", err);
-        return err;
-    }
-
-    rfbRunEventLoop(mVNCScreen, -1, true);
-
-    ALOGD("VNCFlinger ready to fling");
-
-    eventLoop();
-
-    ALOGI("VNCFlinger has left the building");
-
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::stop() {
-    Mutex::Autolock _L(mEventMutex);
-    ALOGV("Shutting down");
-
-    rfbShutdownServer(mVNCScreen, false);
-
-    destroyVirtualDisplayLocked();
-
-    mClientCount = 0;
-    mRunning = false;
-
-    mEventCond.signal();
-    delete[] mVNCScreen->frameBuffer;
-    return NO_ERROR;
-}
-
-void VNCFlinger::eventLoop() {
-    mRunning = true;
-
-    Mutex::Autolock _l(mEventMutex);
-    while (mRunning) {
-        mEventCond.wait(mEventMutex);
-
-        // spurious wakeup? never.
-        if (mClientCount == 0) {
-            continue;
-        }
-
-        // this is a new client, so fire everything up
-        status_t err = createVirtualDisplay();
-        if (err != NO_ERROR) {
-            ALOGE("Failed to create virtual display: err=%d", err);
-        }
-
-        // loop while clients are connected and process frames
-        // on the main thread when signalled
-        while (mClientCount > 0) {
-            mEventCond.wait(mEventMutex);
-            if (mFrameAvailable) {
-                if (!updateDisplayProjection()) {
-                    processFrame();
-                }
-                mFrameAvailable = false;
-            }
-        }
-        Mutex::Autolock _l(mUpdateMutex);
-        memset(mVNCScreen->frameBuffer, 0, mFrameSize);
-        destroyVirtualDisplayLocked();
-    }
-}
-
-status_t VNCFlinger::createVirtualDisplay() {
-    sp<IGraphicBufferConsumer> consumer;
-    BufferQueue::createBufferQueue(&mProducer, &consumer);
-    mCpuConsumer = new CpuConsumer(consumer, NUM_BUFS);
-    mCpuConsumer->setName(String8("vds-to-cpu"));
-    mCpuConsumer->setDefaultBufferSize(mWidth, mHeight);
-    mProducer->setMaxDequeuedBufferCount(1);
-    consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBX_8888);
-
-    mListener = new FrameListener(this);
-    mCpuConsumer->setFrameAvailableListener(mListener);
-
-    mDpy = SurfaceComposerClient::createDisplay(String8("VNC-VirtualDisplay"), false /*secure*/);
-
-    SurfaceComposerClient::openGlobalTransaction();
-    SurfaceComposerClient::setDisplaySurface(mDpy, mProducer);
-    Rect displayRect(0, 0, mSourceWidth, mSourceHeight);
-    Rect outRect(0, 0, mWidth, mHeight);
-    SurfaceComposerClient::setDisplayProjection(mDpy, 0, displayRect, outRect);
-    SurfaceComposerClient::setDisplayLayerStack(mDpy, 0);  // default stack
-    SurfaceComposerClient::closeGlobalTransaction();
-
-    mVDSActive = true;
-
-    ALOGV("Virtual display (%dx%d) created", mWidth, mHeight);
-
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::destroyVirtualDisplayLocked() {
-    if (!mVDSActive) {
-        return NO_INIT;
-    }
-
-    mCpuConsumer.clear();
-    mProducer.clear();
-    SurfaceComposerClient::destroyDisplay(mDpy);
-
-    mVDSActive = false;
-
-    ALOGV("Virtual display destroyed");
-
-    return NO_ERROR;
-}
-
-status_t VNCFlinger::createVNCServer() {
-    status_t err = NO_ERROR;
-
-    rfbLog = VNCFlinger::rfbLogger;
-    rfbErr = VNCFlinger::rfbLogger;
-
-    // 32-bit color
-    mVNCScreen = rfbGetScreen(0, NULL, mWidth, mHeight, 8, 3, 4);
-    if (mVNCScreen == NULL) {
-        ALOGE("Unable to create VNCScreen");
-        return NO_INIT;
-    }
-
-    mFrameNumber = 0;
-    mFrameSize = mWidth * mHeight * 4;
-    mVNCScreen->frameBuffer = (char*)new uint8_t[mFrameSize];
-    memset(mVNCScreen->frameBuffer, 0, mFrameSize);
-
-    mVNCScreen->desktopName = "VNCFlinger";
-    mVNCScreen->alwaysShared = TRUE;
-    mVNCScreen->httpDir = NULL;
-    mVNCScreen->newClientHook = (rfbNewClientHookPtr)VNCFlinger::onNewClient;
-    mVNCScreen->kbdAddEvent = InputDevice::onKeyEvent;
-    mVNCScreen->ptrAddEvent = InputDevice::onPointerEvent;
-    mVNCScreen->displayHook = (rfbDisplayHookPtr)VNCFlinger::onFrameStart;
-    mVNCScreen->displayFinishedHook = (rfbDisplayFinishedHookPtr)VNCFlinger::onFrameDone;
-    mVNCScreen->serverFormat.trueColour = true;
-    mVNCScreen->serverFormat.bitsPerPixel = 32;
-    mVNCScreen->serverFormat.depth = 24;
-    mVNCScreen->handleEventsEagerly = true;
-    mVNCScreen->deferUpdateTime = 0;
-    mVNCScreen->screenData = this;
-
-    std::ifstream authFile(VNC_AUTH_FILE);
-    if ((bool)authFile) {
-        mVNCScreen->authPasswdData = (void *)VNC_AUTH_FILE;
-    }
-
-    return err;
-}
-
-status_t VNCFlinger::startVNCServer() {
-    rfbInitServer(mVNCScreen);
-
-    /* Mark as dirty since we haven't sent any updates at all yet. */
-    rfbMarkRectAsModified(mVNCScreen, 0, 0, mWidth, mHeight);
-
-    return NO_ERROR;
-}
-
-size_t VNCFlinger::addClient() {
-    Mutex::Autolock _l(mEventMutex);
-    if (mClientCount == 0) {
-        mClientCount++;
-        InputDevice::getInstance().start(mWidth, mHeight);
-        mEventCond.signal();
-    }
-
-    ALOGI("Client connected (%zu)", mClientCount);
-
-    return mClientCount;
-}
-
-size_t VNCFlinger::removeClient() {
-    Mutex::Autolock _l(mEventMutex);
-    if (mClientCount > 0) {
-        mClientCount--;
-        if (mClientCount == 0) {
-            InputDevice::getInstance().stop();
-            mEventCond.signal();
-        }
-    }
-
-    ALOGI("Client disconnected (%zu)", mClientCount);
-
-    return mClientCount;
-}
-
-void VNCFlinger::processFrame() {
-    // Take the update mutex. This ensures that we don't dequeue
-    // a new buffer and blow away the one being sent to a client.
-    // The BufferQueue is self-regulating and will drop frames
-    // automatically for us.
-    Mutex::Autolock _l(mUpdateMutex);
-
-    // get a frame from the virtual display
-    CpuConsumer::LockedBuffer imgBuffer;
-    status_t res = mCpuConsumer->lockNextBuffer(&imgBuffer);
-    if (res != OK) {
-        ALOGE("Failed to lock next buffer: %s (%d)", strerror(-res), res);
-        return;
-    }
-
-    mFrameNumber = imgBuffer.frameNumber;
-    ALOGV("processFrame: [%lu] format: %x (%dx%d, stride=%d)", mFrameNumber, imgBuffer.format,
-          imgBuffer.width, imgBuffer.height, imgBuffer.stride);
-
-    // we don't know if there was a stride change until we get
-    // a buffer from the queue. if it changed, we need to resize
-    updateFBSize(imgBuffer);
-
-    // performance is extremely bad if the gpu memory is used
-    // directly without copying because it is likely uncached
-    memcpy(mVNCScreen->frameBuffer, imgBuffer.data, mFrameSize);
-
-    // update clients
-    rfbMarkRectAsModified(mVNCScreen, 0, 0, imgBuffer.width, imgBuffer.height);
-
-    mCpuConsumer->unlockBuffer(imgBuffer);
-}
-
-/*
- * Returns "true" if the device is rotated 90 degrees.
- */
-bool VNCFlinger::isDeviceRotated(int orientation) {
-    return orientation != DISPLAY_ORIENTATION_0 && orientation != DISPLAY_ORIENTATION_180;
-}
-
-/*
- * Sets the display projection, based on the display dimensions, video size,
- * and device orientation.
- */
-bool VNCFlinger::updateDisplayProjection() {
-    DisplayInfo info;
-    status_t err = SurfaceComposerClient::getDisplayInfo(mMainDpy, &info);
-    if (err != NO_ERROR) {
-        ALOGE("Failed to get display characteristics\n");
-        return true;
-    }
-
-    // Set the region of the layer stack we're interested in, which in our
-    // case is "all of it".  If the app is rotated (so that the width of the
-    // app is based on the height of the display), reverse width/height.
-    bool deviceRotated = isDeviceRotated(info.orientation);
-    uint32_t sourceWidth, sourceHeight;
-    if (!deviceRotated) {
-        sourceWidth = info.w;
-        sourceHeight = info.h;
-    } else {
-        ALOGV("using rotated width/height");
-        sourceHeight = info.w;
-        sourceWidth = info.h;
-    }
-
-    uint32_t width = sourceWidth * mScale;
-    uint32_t height = sourceHeight * mScale;
-
-    if (mSourceWidth == sourceWidth && mSourceHeight == sourceHeight &&
-            mWidth == width && mHeight == height &&
-            mOrientation == info.orientation) {
-        return false;
-    }
-
-    // orientation / resolution change
-    mSourceWidth = sourceWidth;
-    mSourceHeight = sourceHeight;
-    mWidth = width;
-    mHeight = height;
-    mOrientation = info.orientation;
-
-    ALOGV("Dimensions: %dx%d [out: %dx%d, scale: %f] orientation=%d",
-            mSourceWidth, mSourceHeight, mWidth, mHeight, mScale, mOrientation);
-
-    if (!mVDSActive) {
-        return true;
-    }
-
-    // it does not appear to be possible to reconfigure the virtual display
-    // on the fly without forcing surfaceflinger to tear it down
-    destroyVirtualDisplayLocked();
-    createVirtualDisplay();
-
-    return false;
-}
-
-bool VNCFlinger::updateFBSize(CpuConsumer::LockedBuffer& buf) {
-    uint32_t stride = (uint32_t)mVNCScreen->paddedWidthInBytes / 4;
-    uint32_t width = (uint32_t)mVNCScreen->width;
-    uint32_t height = (uint32_t)mVNCScreen->height;
-
-    uint64_t newSize = buf.stride * buf.height * 4;
-
-    if (stride != buf.stride || height != buf.height || width != buf.width) {
-        ALOGD("updateFBSize: old=[%dx%d %d] new=[%dx%d %d]", width, height, stride, buf.width,
-              buf.height, buf.stride);
-
-        if (mFrameSize != newSize) {
-            mFrameSize = newSize;
-            delete[] mVNCScreen->frameBuffer;
-            rfbNewFramebuffer(mVNCScreen, (char*)new uint8_t[newSize], buf.width, buf.height, 8, 3,
-                              4);
-        }
-        mVNCScreen->paddedWidthInBytes = buf.stride * 4;
-    }
-    return NO_ERROR;
-}
-
-// ------------------------------------------------------------------------ //
-
-// libvncserver logger
-void VNCFlinger::rfbLogger(const char* format, ...) {
-    va_list args;
-    char buf[256];
-
-    va_start(args, format);
-    vsprintf(buf, format, args);
-    ALOGI("%s", buf);
-    va_end(args);
-}
-
-// libvncserver callbacks
-ClientGoneHookPtr VNCFlinger::onClientGone(rfbClientPtr cl) {
-    ALOGV("onClientGone");
-    VNCFlinger* vf = (VNCFlinger*)cl->screen->screenData;
-    vf->removeClient();
-    return 0;
-}
-
-enum rfbNewClientAction VNCFlinger::onNewClient(rfbClientPtr cl) {
-    ALOGV("onNewClient");
-    cl->clientGoneHook = (ClientGoneHookPtr)VNCFlinger::onClientGone;
-    VNCFlinger* vf = (VNCFlinger*)cl->screen->screenData;
-    vf->addClient();
-    return RFB_CLIENT_ACCEPT;
-}
-
-void VNCFlinger::onFrameStart(rfbClientPtr cl) {
-    VNCFlinger* vf = (VNCFlinger*)cl->screen->screenData;
-    vf->mUpdateMutex.lock();
-
-    vf->mFrameStartWhen = systemTime(CLOCK_MONOTONIC);
-    ALOGV("frame start [%lu]", vf->mFrameNumber);
-}
-
-void VNCFlinger::onFrameDone(rfbClientPtr cl, int /* status */) {
-    VNCFlinger* vf = (VNCFlinger*)cl->screen->screenData;
-
-    float timing = (systemTime(CLOCK_MONOTONIC) - vf->mFrameStartWhen) / 1000000.0;
-    ALOGV("onFrameDone [%lu] (%.3f ms)", vf->mFrameNumber, timing);
-
-    vf->mUpdateMutex.unlock();
-}
-
-// cpuconsumer frame listener
-void VNCFlinger::FrameListener::onFrameAvailable(const BufferItem& item) {
-    Mutex::Autolock _l(mVNC->mEventMutex);
-    mVNC->mFrameAvailable = true;
-    mVNC->mEventCond.signal();
-    ALOGV("onFrameAvailable: [%lu] mTimestamp=%ld", item.mFrameNumber, item.mTimestamp);
-}
diff --git a/src/VNCFlinger.h b/src/VNCFlinger.h
deleted file mode 100644
index 3f9bf62..0000000
--- a/src/VNCFlinger.h
+++ /dev/null
@@ -1,130 +0,0 @@
-//
-// vncflinger - Copyright (C) 2017 Steve Kondik
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-#ifndef VNCFLINGER_H
-#define VNCFLINGER_H
-
-#include <gui/CpuConsumer.h>
-#include <ui/DisplayInfo.h>
-#include <utils/String8.h>
-
-#include <rfb/rfb.h>
-#undef max
-
-#define VNC_AUTH_FILE "/data/system/vncauth"
-#define NUM_BUFS 1
-
-namespace android {
-
-class VNCFlinger : public RefBase {
-  public:
-    VNCFlinger();
-
-    virtual ~VNCFlinger() {
-    }
-
-    virtual status_t start();
-    virtual status_t stop();
-
-    virtual size_t addClient();
-    virtual size_t removeClient();
-
-    virtual status_t setPort(unsigned int port);
-    virtual status_t setV4Address(const String8& address);
-    virtual status_t setV6Address(const String8& address);
-    virtual status_t setScale(float scale);
-
-    virtual status_t clearPassword();
-    virtual status_t setPassword(const String8& passwd);
-
-  private:
-    class FrameListener : public CpuConsumer::FrameAvailableListener {
-      public:
-        FrameListener(VNCFlinger* vnc) : mVNC(vnc) {
-        }
-
-        virtual void onFrameAvailable(const BufferItem& item);
-
-      private:
-        FrameListener(FrameListener&) {
-        }
-        VNCFlinger* mVNC;
-    };
-
-    virtual void eventLoop();
-
-    virtual status_t createVirtualDisplay();
-    virtual status_t destroyVirtualDisplayLocked();
-
-    virtual status_t createVNCServer();
-    virtual status_t startVNCServer();
-
-    virtual void processFrame();
-
-    virtual bool isDeviceRotated(int orientation);
-    virtual bool updateDisplayProjection();
-    virtual bool updateFBSize(CpuConsumer::LockedBuffer& buf);
-
-    // vncserver callbacks
-    static ClientGoneHookPtr onClientGone(rfbClientPtr cl);
-    static enum rfbNewClientAction onNewClient(rfbClientPtr cl);
-    static void onFrameStart(rfbClientPtr cl);
-    static void onFrameDone(rfbClientPtr cl, int result);
-    static void rfbLogger(const char* format, ...);
-
-    bool mRunning;
-    bool mFrameAvailable;
-    bool mRotate;
-    bool mVDSActive;
-
-    Mutex mEventMutex;
-    Mutex mUpdateMutex;
-
-    Condition mEventCond;
-
-    uint32_t mWidth, mHeight;
-    uint32_t mSourceWidth, mSourceHeight;
-    int32_t mOrientation;
-    float mScale;
-
-    size_t mClientCount;
-
-    // Framebuffers
-    uint64_t mFrameNumber;
-    uint64_t mFrameSize;
-    nsecs_t mFrameStartWhen;
-
-    // Server instance
-    rfbScreenInfoPtr mVNCScreen;
-
-    // Primary display
-    sp<IBinder> mMainDpy;
-
-    // Virtual display
-    sp<IBinder> mDpy;
-
-    // Producer side of queue, passed into the virtual display.
-    sp<IGraphicBufferProducer> mProducer;
-
-    // This receives frames from the virtual display and makes them available
-    sp<CpuConsumer> mCpuConsumer;
-
-    // Consumer callback
-    sp<FrameListener> mListener;
-};
-};
-#endif
diff --git a/src/VirtualDisplay.h b/src/VirtualDisplay.h
new file mode 100644
index 0000000..f23d32d
--- /dev/null
+++ b/src/VirtualDisplay.h
@@ -0,0 +1,26 @@
+#include <gui/CpuConsumer.h>
+
+namespace vncflinger {
+
+class VirtualDisplay {
+  public:
+    VirtualDisplay();
+
+    virtual void onFrameAvailable(const BufferItem& item);
+
+  private:
+    Mutex mEventMutex;
+    Condition mEventCond;
+
+    bool mFrameAvailable;
+
+    // Virtual display
+    sp<IBinder> mDpy;
+
+    // Producer side of queue, passed into the virtual display.
+    sp<IGraphicBufferProducer> mProducer;
+
+    // This receives frames from the virtual display and makes them available
+    sp<CpuConsumer> mCpuConsumer;
+};
+};
diff --git a/src/main.cpp b/src/main.cpp
index 29178ff..c22f075 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,148 +1,168 @@
-//
-// vncflinger - Copyright (C) 2017 Steve Kondik
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-#include <getopt.h>
+#define LOG_TAG "VNCFlinger"
+#include <utils/Log.h>
 
-#include <csignal>
-#include <iostream>
+#include <fcntl.h>
 
-#include <binder/IServiceManager.h>
+#include "AndroidDesktop.h"
 
-#include "VNCFlinger.h"
-#include "VNCService.h"
+#include <network/Socket.h>
+#include <network/TcpSocket.h>
+#include <rfb/Configuration.h>
+#include <rfb/Logger_android.h>
+#include <rfb/VNCServerST.h>
+#include <rfb/util.h>
 
-using namespace android;
+using namespace vncflinger;
 
-static sp<VNCFlinger> gVNC;
+static char* gProgramName;
+static bool gCaughtSignal = false;
 
-static const char* const shortOpts = "4:6:p:cs:l:vh";
-static const option longOpts[] = {
-    {"listen", 1, nullptr, '4'},
-    {"listen6", 1, nullptr, '6'},
-    {"port", 1, nullptr, 'p'},
-    {"password", 1, nullptr, 's'},
-    {"clear-password", 0, nullptr, 'c'},
-    {"scale", 1, nullptr, 'l'},
-    {"version", 0, nullptr, 'v'},
-    {"help", 0, nullptr, 'h'},
-};
+static rfb::IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol", 5900);
 
-static void onSignal(int signal) {
-    ALOGV("Shutting down on signal %d", signal);
-    gVNC->stop();
+static void printVersion(FILE* fp) {
+    fprintf(fp, "VNCFlinger 1.0");
 }
 
-static void printVersion() {
-    std::cout << "VNCFlinger-" << VNCFLINGER_VERSION << std::endl;
-    exit(0);
-}
-
-static void printHelp() {
-    std::cout << "Usage: vncflinger [OPTIONS]\n\n"
-              << "  -4 <addr>        IPv4 address to listen (default: localhost)\n"
-              << "  -6 <addr>        IPv6 address to listen (default: localhost)\n"
-              << "  -p <num>         Port to listen on (default: 5900)\n"
-              << "  -s <pass>        Store server password\n"
-              << "  -c               Clear server password\n"
-              << "  -l <scale>       Scaling value (default: 1.0)\n"
-              << "  -v               Show server version\n"
-              << "  -h               Show help\n\n";
+static void usage() {
+    printVersion(stderr);
+    fprintf(stderr, "\nUsage: %s [<parameters>]\n", gProgramName);
+    fprintf(stderr, "       %s --version\n", gProgramName);
+    fprintf(stderr,
+            "\n"
+            "Parameters can be turned on with -<param> or off with -<param>=0\n"
+            "Parameters which take a value can be specified as "
+            "-<param> <value>\n"
+            "Other valid forms are <param>=<value> -<param>=<value> "
+            "--<param>=<value>\n"
+            "Parameter names are case-insensitive.  The parameters are:\n\n");
+    rfb::Configuration::listParams(79, 14);
     exit(1);
 }
 
-static void parseArgs(int argc, char** argv) {
-    String8 arg;
-
-    while (true) {
-        const auto opt = getopt_long(argc, argv, shortOpts, longOpts, nullptr);
-
-        if (opt < 0) {
-            break;
-        }
-
-        switch (opt) {
-            case 's':
-                arg = optarg;
-                if (gVNC->setPassword(arg) != OK) {
-                    std::cerr << "Failed to set password\n";
-                    exit(1);
-                }
-                exit(0);
-
-            case 'c':
-                if (gVNC->clearPassword() != OK) {
-                    std::cerr << "Failed to clear password\n";
-                    exit(1);
-                }
-                exit(0);
-
-            case '4':
-                arg = optarg;
-                if (gVNC->setV4Address(arg) != OK) {
-                    std::cerr << "Failed to set IPv4 address\n";
-                    exit(1);
-                }
-                break;
-
-            case '6':
-                arg = optarg;
-                if (gVNC->setV6Address(arg) != OK) {
-                    std::cerr << "Failed to set IPv6 address\n";
-                    exit(1);
-                }
-                break;
-
-            case 'p':
-                if (gVNC->setPort(std::stoi(optarg)) != OK) {
-                    std::cerr << "Failed to set port\n";
-                    exit(1);
-                }
-                break;
-
-            case 'l':
-                if (gVNC->setScale(std::stof(optarg)) != OK) {
-                    std::cerr << "Invalid scaling value (must be between 0.0 and 2.0)\n";
-                    exit(1);
-                }
-                break;
-
-            case 'v':
-                printVersion();
-                break;
-
-            case 'h':
-            case '?':
-            default:
-                printHelp();
-                break;
-        }
-    }
-}
-
 int main(int argc, char** argv) {
-    std::signal(SIGINT, onSignal);
-    std::signal(SIGHUP, onSignal);
+    rfb::initAndroidLogger();
+    rfb::LogWriter::setLogParams("*:android:30");
 
-    gVNC = new VNCFlinger();
+    gProgramName = argv[0];
 
-    parseArgs(argc, argv);
+    rfb::Configuration::enableServerParams();
 
-    // binder interface
-    defaultServiceManager()->addService(String16("vnc"), new VNCService(gVNC));
+    for (int i = 1; i < argc; i++) {
+        if (rfb::Configuration::setParam(argv[i])) continue;
 
-    gVNC->start();
-    gVNC.clear();
+        if (argv[i][0] == '-') {
+            if (i + 1 < argc) {
+                if (rfb::Configuration::setParam(&argv[i][1], argv[i + 1])) {
+                    i++;
+                    continue;
+                }
+            }
+            if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "-version") == 0 ||
+                strcmp(argv[i], "--version") == 0) {
+                printVersion(stdout);
+                return 0;
+            }
+            usage();
+        }
+        usage();
+    }
+
+    std::list<network::TcpListener*> listeners;
+
+    try {
+        sp<AndroidDesktop> desktop = new AndroidDesktop();
+        rfb::VNCServerST server("vncflinger", desktop.get());
+        network::createTcpListeners(&listeners, 0, (int)rfbport);
+
+        int eventFd = desktop->getEventFd();
+        fcntl(eventFd, F_SETFL, O_NONBLOCK);
+
+        ALOGI("Listening on port %d", (int)rfbport);
+
+        while (!gCaughtSignal) {
+            int wait_ms;
+            struct timeval tv;
+            fd_set rfds, wfds;
+            std::list<network::Socket*> sockets;
+            std::list<network::Socket*>::iterator i;
+
+            FD_ZERO(&rfds);
+            FD_ZERO(&wfds);
+
+            FD_SET(eventFd, &rfds);
+            for (std::list<network::TcpListener*>::iterator i = listeners.begin();
+                 i != listeners.end(); i++)
+                FD_SET((*i)->getFd(), &rfds);
+
+            server.getSockets(&sockets);
+            int clients_connected = 0;
+            for (i = sockets.begin(); i != sockets.end(); i++) {
+                if ((*i)->isShutdown()) {
+                    server.removeSocket(*i);
+                    delete (*i);
+                } else {
+                    FD_SET((*i)->getFd(), &rfds);
+                    if ((*i)->outStream().bufferUsage() > 0) FD_SET((*i)->getFd(), &wfds);
+                    clients_connected++;
+                }
+            }
+
+            wait_ms = 0;
+
+            rfb::soonestTimeout(&wait_ms, server.checkTimeouts());
+
+            tv.tv_sec = wait_ms / 1000;
+            tv.tv_usec = (wait_ms % 1000) * 1000;
+
+            int n = select(FD_SETSIZE, &rfds, &wfds, 0, wait_ms ? &tv : NULL);
+
+            if (n < 0) {
+                if (errno == EINTR) {
+                    ALOGV("Interrupted select() system call");
+                    continue;
+                } else {
+                    throw rdr::SystemException("select", errno);
+                }
+            }
+
+            // Accept new VNC connections
+            for (std::list<network::TcpListener*>::iterator i = listeners.begin();
+                 i != listeners.end(); i++) {
+                if (FD_ISSET((*i)->getFd(), &rfds)) {
+                    network::Socket* sock = (*i)->accept();
+                    if (sock) {
+                        sock->outStream().setBlocking(false);
+                        server.addSocket(sock);
+                    } else {
+                        ALOGW("Client connection rejected");
+                    }
+                }
+            }
+
+            server.checkTimeouts();
+
+            // Client list could have been changed.
+            server.getSockets(&sockets);
+
+            // Nothing more to do if there are no client connections.
+            if (sockets.empty()) continue;
+
+            // Process events on existing VNC connections
+            for (i = sockets.begin(); i != sockets.end(); i++) {
+                if (FD_ISSET((*i)->getFd(), &rfds)) server.processSocketReadEvent(*i);
+                if (FD_ISSET((*i)->getFd(), &wfds)) server.processSocketWriteEvent(*i);
+            }
+
+            // Process events from the display
+            uint64_t eventVal;
+            int status = read(eventFd, &eventVal, sizeof(eventVal));
+            if (status > 0 && eventVal > 0) {
+                desktop->processFrames();
+            }
+        }
+
+    } catch (rdr::Exception& e) {
+        ALOGE("%s", e.str());
+        return 1;
+    }
 }
