Index: /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk	(revision 50337)
@@ -59,5 +59,4 @@
  VBoxClient_DEFS += SEAMLESS_GUEST DYNAMIC_RESIZE
  VBoxClient_SOURCES += \
-	seamless.cpp \
 	seamless-host.cpp \
 	seamless-x11.cpp \
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp	(revision 50337)
@@ -1,9 +1,10 @@
 /** @file
- * X11 Guest client - seamless mode, missing proper description while using the
- * potentially confusing word 'host'.
+ * X11 Guest client - seamless mode: main logic, communication with the host and
+ * wrapper interface for the main code of the VBoxClient deamon.  The
+ * X11-specific parts are split out into their own file for ease of testing.
  */
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -19,4 +20,7 @@
 *   Header files                                                             *
 *****************************************************************************/
+
+#include <X11/Xlib.h>
+
 #include <VBox/log.h>
 #include <VBox/VMMDev.h>
@@ -24,4 +28,5 @@
 #include <iprt/err.h>
 
+#include "VBoxClient.h"
 #include "seamless-host.h"
 #include "seamless-x11.h"
@@ -50,4 +55,9 @@
     {
         LogRel(("VBoxClient: enabled seamless capability on host.\n"));
+        /* Create a thread to wait for requests from the host.  This is currently
+         * done on a separate thread as the main thread monitors the X11 server
+         * for disconnections. */
+        /** @todo Move the disconnection monitoring to its own thread (better, the
+         *  VT monitor thread) and run this logic on the main service thread. */
         rc = RTThreadCreate(&mThread, threadFunction, this, 0,
                             RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
@@ -68,5 +78,5 @@
 
 /** Stops the service. */
-void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */)
+void VBoxGuestSeamlessHost::stop()
 {
     LogRelFlowFunc(("\n"));
@@ -74,5 +84,5 @@
         LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
     else
-        stopThread(cMillies);
+        stopThread();
     if (mX11MonitorRTThread)
         stopX11Thread();
@@ -103,5 +113,4 @@
                 LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
 #endif
-                mState = ENABLE;
                 mX11ThreadStopping = false;
                 /** @todo Do something on failure, like bail out. */
@@ -122,5 +131,4 @@
                 LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
 #endif
-                mState = DISABLE;
                 if (mX11MonitorRTThread)
                     stopX11Thread();
@@ -182,5 +190,5 @@
  * Send a signal to the thread that it should exit
  */
-void VBoxGuestSeamlessHost::stopThread(RTMSINTERVAL cMillies)
+void VBoxGuestSeamlessHost::stopThread()
 {
     int rc;
@@ -217,12 +225,12 @@
 
     LogRelFlowFunc(("\n"));
-    rc = pHost->mX11Monitor->start();
+    rc = pHost->mX11Monitor.start();
     if (RT_SUCCESS(rc))
     {
         while (!pHost->mX11ThreadStopping)
         {
-            pHost->mX11Monitor->nextEvent();
-        }
-        pHost->mX11Monitor->stop();
+            pHost->mX11Monitor.nextEvent();
+        }
+        pHost->mX11Monitor.stop();
     }
     LogRelFlowFunc(("returning %Rrc\n", rc));
@@ -238,5 +246,5 @@
 
     mX11ThreadStopping = true;
-    mX11Monitor->interruptEvent();
+    mX11Monitor.interruptEvent();
     rc = RTThreadWait(mX11MonitorRTThread, RT_INDEFINITE_WAIT, NULL);
     if (RT_SUCCESS(rc))
@@ -246,2 +254,53 @@
                         rc));
 }
+
+/** VBoxClient service class wrapping the logic for the seamless service while
+ *  the main VBoxClient code provides the daemon logic needed by all services.
+ */
+class SeamlessService : public VBoxClient::Service
+{
+private:
+    VBoxGuestSeamlessHost mSeamless;
+    bool mIsInitialised;
+public:
+    virtual const char *getPidFilePath()
+    {
+        return ".vboxclient-seamless.pid";
+    }
+    virtual int run(bool fDaemonised /* = false */)
+    {
+        int rc;
+
+        if (mIsInitialised)  /* Assertion */
+        {
+            LogRelFunc(("error: called a second time! (VBoxClient)\n"));
+            rc = VERR_INTERNAL_ERROR;
+        }
+        if (RT_SUCCESS(rc))
+            rc = mSeamless.init();
+        if (RT_SUCCESS(rc))
+            rc = mSeamless.start();
+        if (RT_SUCCESS(rc))
+            mIsInitialised = true;
+        if (RT_FAILURE(rc))
+        {
+            LogRelFunc(("returning %Rrc (VBoxClient)\n", rc));
+            return rc;
+        }
+        /* Stay running as long as X does... */
+        Display *pDisplay = XOpenDisplay(NULL);
+        XEvent ev;
+        while (true)
+            XNextEvent(pDisplay, &ev);
+        return VERR_INTERRUPTED;
+    }
+    virtual void cleanup()
+    {
+        VbglR3SeamlessSetCap(false);
+    }
+};
+
+VBoxClient::Service *VBoxClient::GetSeamlessService()
+{
+    return new SeamlessService;
+}
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.h	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.h	(revision 50337)
@@ -24,21 +24,10 @@
 #include <VBox/VBoxGuestLib.h>      /* for the R3 guest library functions  */
 
-class VBoxGuestSeamlessX11;
-
-/**
- * Small virtual class which provides the interface for notifying the host of
- * changes to the X11 window configuration, mainly split out from
- * @a VBoxGuestSeamlessHost to simplify the unit test.
- */
-class VBoxGuestSeamlessHostInt
-{
-public:
-    virtual void notify(RTRECT *pRects, size_t cRects) = 0;
-};
+#include "seamless-x11.h"
 
 /**
  * Interface to the host
  */
-class VBoxGuestSeamlessHost : public VBoxGuestSeamlessHostInt
+class VBoxGuestSeamlessHost : public SeamlessHostProxy
 {
 public:
@@ -59,9 +48,12 @@
     VBoxGuestSeamlessHost& operator=(const VBoxGuestSeamlessHost&);
 
+    /** Have we been initialised yet? */
+    bool mIsInitialised;
+    /** X11 event monitor object */
+    VBoxGuestSeamlessX11 mX11Monitor;
+
     /** Thread to start and stop when we enter and leave seamless mode which
      *  monitors X11 windows in the guest. */
     RTTHREAD mX11MonitorRTThread;
-    /** X11 event monitor class */
-    VBoxGuestSeamlessX11 *mX11Monitor;
     /** Should the X11 monitor thread be stopping? */
     volatile bool mX11ThreadStopping;
@@ -72,6 +64,4 @@
     /** Should the thread be stopping? */
     volatile bool mThreadStopping;
-    /** Last request issued by the host. */
-    meEvent mState;
 
     /**
@@ -93,5 +83,5 @@
 
     /** Helper to stop the event query thread again. */
-    void stopThread(RTMSINTERVAL cMillies);
+    void stopThread();
 
     /** Thread function to monitor X11 window configuration changes. */
@@ -108,15 +98,15 @@
      * @returns iprt status code
      */
-    int init(VBoxGuestSeamlessX11 *pX11Monitor)
+    int init(void)
     {
+        int rc;
+
         LogRelFlowFunc(("\n"));
-        if (mX11Monitor != NULL)  /* Assertion */
-        {
-            LogRel(("VBoxClient: ERROR: attempt to initialise seamless host object twice!\n"));
+        if (mIsInitialised)
             return VERR_INTERNAL_ERROR;
-        }
-        mX11Monitor = pX11Monitor;
-        LogRelFlowFunc(("returning VINF_SUCCESS\n"));
-        return VINF_SUCCESS;
+        rc = mX11Monitor.init(this);
+        if (RT_SUCCESS(rc))
+            mIsInitialised = true;
+        return rc;
     }
 
@@ -131,8 +121,5 @@
      * @param cMillies how long to wait for the thread to exit
      */
-    void stop(RTMSINTERVAL cMillies = RT_INDEFINITE_WAIT);
-
-    /** Returns the current state of the host - i.e. requesting seamless or not. */
-    meEvent getState(void) { return mState; }
+    void stop();
 
     /**
@@ -143,11 +130,10 @@
     VBoxGuestSeamlessHost(void)
     {
+        mIsInitialised = false;
         mX11MonitorRTThread = NIL_RTTHREAD;
-        mX11Monitor = NULL;
         mX11ThreadStopping = false;
         mThread = NIL_RTTHREAD;
         mThreadRunning = false;
         mThreadStopping = false;
-        mState = NONE;
     }
 
@@ -155,9 +141,6 @@
     {
         LogRelFlowFunc(("\n"));
-        if (mThread)  /* Assertion */
-        {
-            LogRel(("VBoxClient: seamless host object still running!  Stopping...\n"));
-            stop(2000);
-        }
+        if (mThread)
+            stop();
         LogRelFlowFunc(("returning\n"));
     }
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp	(revision 50337)
@@ -71,5 +71,5 @@
   * @returns true if it can handle seamless, false otherwise
   */
-int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessHostInt *pHost)
+int VBoxGuestSeamlessX11::init(SeamlessHostProxy *pHost)
 {
     int rc = VINF_SUCCESS;
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h	(revision 50337)
@@ -23,7 +23,4 @@
 #include <iprt/avl.h>
 
-#include "seamless-x11.h"
-#include "seamless-host.h"
-
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -35,4 +32,15 @@
 /* This is defined wrong in my X11 header files! */
 #define VBoxShapeNotify 64
+
+/**
+ * Small virtual class which provides the interface for notifying the host of
+ * changes to the X11 window configuration, mainly split out from
+ * @a VBoxGuestSeamlessHost to simplify the unit test.
+ */
+class SeamlessHostProxy
+{
+public:
+    virtual void notify(RTRECT *pRects, size_t cRects) = 0;
+};
 
 /** Structure containing information about a guest window's position and visible area.
@@ -156,5 +164,5 @@
     // Private member variables
     /** Pointer to the host class. */
-    VBoxGuestSeamlessHostInt *mHost;
+    SeamlessHostProxy *mHost;
     /** Our connection to the X11 display we are running on. */
     Display *mDisplay;
@@ -201,5 +209,5 @@
      * @returns iprt status code
      */
-    int init(VBoxGuestSeamlessHostInt *pHost);
+    int init(SeamlessHostProxy *pHost);
 
     /**
Index: unk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp	(revision 50336)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/** @file
- *
- * Guest client: seamless mode.
- */
-
-/*
- * Copyright (C) 2006-2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include <unistd.h>
-
-#include <X11/Xlib.h>
-
-#include "VBoxClient.h"
-#include "seamless.h"
-
-class SeamlessService : public VBoxClient::Service
-{
-private:
-    VBoxGuestSeamless mSeamless;
-public:
-    virtual const char *getPidFilePath()
-    {
-        return ".vboxclient-seamless.pid";
-    }
-    virtual int run(bool fDaemonised /* = false */)
-    {
-        int rc = mSeamless.init();
-        if (RT_FAILURE(rc))
-            return rc;
-        /* Stay running as long as X does... */
-        Display *pDisplay = XOpenDisplay(NULL);
-        XEvent ev;
-        while (true)
-            XNextEvent(pDisplay, &ev);
-        return VERR_INTERRUPTED;
-    }
-    virtual void cleanup()
-    {
-        VbglR3SeamlessSetCap(false);
-    }
-};
-
-VBoxClient::Service *VBoxClient::GetSeamlessService()
-{
-    return new SeamlessService;
-}
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless.h	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless.h	(revision 50337)
@@ -28,5 +28,4 @@
 private:
     VBoxGuestSeamlessHost mHost;
-    VBoxGuestSeamlessX11 mGuest;
 
     bool isInitialised;
@@ -44,9 +43,5 @@
         if (RT_SUCCESS(rc))
         {
-            rc = mHost.init(&mGuest);
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = mGuest.init(&mHost);
+            rc = mHost.init();
         }
         if (RT_SUCCESS(rc))
@@ -66,18 +61,6 @@
     }
 
-    void uninit(RTMSINTERVAL cMillies = RT_INDEFINITE_WAIT)
-    {
-        LogRelFlowFunc(("\n"));
-        if (isInitialised)
-        {
-            mHost.stop(cMillies);
-            mGuest.uninit();
-            isInitialised = false;
-        }
-        LogRelFlowFunc(("returning\n"));
-    }
-
     VBoxGuestSeamless() { isInitialised = false; }
-    ~VBoxGuestSeamless() { uninit(); }
+    ~VBoxGuestSeamless() { }
 };
 
Index: /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp	(revision 50337)
@@ -29,5 +29,4 @@
 
 #include "../seamless.h"
-#include "../seamless-host.h"
 
 #undef DefaultRootWindow
@@ -299,5 +298,5 @@
 
 /** Dummy host class */
-class testHost: public VBoxGuestSeamlessHostInt
+class testHost: public SeamlessHostProxy
 {
     bool mfNotified;
Index: /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp	(revision 50336)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp	(revision 50337)
@@ -127,5 +127,4 @@
     }
     RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
-    seamless.uninit();
     return rc;
 }
