Index: /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk	(revision 50338)
@@ -59,5 +59,5 @@
  VBoxClient_DEFS += SEAMLESS_GUEST DYNAMIC_RESIZE
  VBoxClient_SOURCES += \
-	seamless-host.cpp \
+	seamless.cpp \
 	seamless-x11.cpp \
 	display.cpp \
@@ -109,5 +109,5 @@
    tstSeamlessX11_SOURCES = \
            testcase/tstSeamlessX11.cpp \
-           seamless-host.cpp \
+           seamless.cpp \
            seamless-x11.cpp
    tstSeamlessX11_LIBPATH = \
Index: unk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp	(revision 50337)
+++ 	(revision )
@@ -1,306 +1,0 @@
-/** @file
- * 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-2014 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.
- */
-
-/*****************************************************************************
-*   Header files                                                             *
-*****************************************************************************/
-
-#include <X11/Xlib.h>
-
-#include <VBox/log.h>
-#include <VBox/VMMDev.h>
-#include <VBox/VBoxGuestLib.h>
-#include <iprt/err.h>
-
-#include "VBoxClient.h"
-#include "seamless-host.h"
-#include "seamless-x11.h"
-
-/**
- * Start the service.
- * @returns iprt status value
- */
-int VBoxGuestSeamlessHost::start(void)
-{
-    int rc = VERR_NOT_SUPPORTED;
-
-    LogRelFlowFunc(("\n"));
-    if (mThread)  /* Assertion */
-    {
-        LogRel(("VBoxClient: seamless service started twice!\n"));
-        return VERR_INTERNAL_ERROR;
-    }
-    rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
-    if (RT_FAILURE(rc))
-    {
-        LogRel(("VBoxClient (seamless): failed to set the guest IRQ filter mask, rc=%Rrc\n", rc));
-    }
-    rc = VbglR3SeamlessSetCap(true);
-    if (RT_SUCCESS(rc))
-    {
-        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,
-                            "Host events");
-        if (RT_FAILURE(rc))
-        {
-            LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc.  Disabled seamless capability on host again.\n", rc));
-            VbglR3SeamlessSetCap(false);
-        }
-    }
-    if (RT_FAILURE(rc))
-    {
-        LogRel(("VBoxClient (seamless): failed to enable seamless capability on host, rc=%Rrc\n", rc));
-    }
-    LogRelFlowFunc(("returning %Rrc\n", rc));
-    return rc;
-}
-
-/** Stops the service. */
-void VBoxGuestSeamlessHost::stop()
-{
-    LogRelFlowFunc(("\n"));
-    if (!mThread)  /* Assertion */
-        LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
-    else
-        stopThread();
-    if (mX11MonitorRTThread)
-        stopX11Thread();
-    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
-    VbglR3SeamlessSetCap(false);
-    LogRelFlowFunc(("returning\n"));
-}
-
-/**
- * Waits for a seamless state change events from the host and dispatch it.
- *
- * @returns        IRPT return code.
- */
-int VBoxGuestSeamlessHost::nextEvent(void)
-{
-    VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
-
-    LogRelFlowFunc(("\n"));
-    int rc = VbglR3SeamlessWaitEvent(&newMode);
-    if (RT_SUCCESS(rc))
-    {
-        switch(newMode)
-        {
-            case VMMDev_Seamless_Visible_Region:
-            /* A simplified seamless mode, obtained by making the host VM window borderless and
-              making the guest desktop transparent. */
-#ifdef DEBUG
-                LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
-#endif
-                mX11ThreadStopping = false;
-                /** @todo Do something on failure, like bail out. */
-                if (RT_FAILURE(RTThreadCreate(&mX11MonitorRTThread,
-                               x11ThreadFunction, this, 0, RTTHREADTYPE_MSG_PUMP,
-                               RTTHREADFLAGS_WAITABLE, "X11 events")))
-                    LogRelFunc(("Warning: failed to start X11 monitor thread (VBoxClient).\n"));
-                break;
-            case VMMDev_Seamless_Host_Window:
-            /* One host window represents one guest window.  Not yet implemented. */
-                LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received (VBoxClient).\n"));
-                /* fall through to default */
-            default:
-                LogRelFunc(("Warning: unsupported VMMDev_Seamless request %d received (VBoxClient).\n", newMode));
-                /* fall through to case VMMDev_Seamless_Disabled */
-            case VMMDev_Seamless_Disabled:
-#ifdef DEBUG
-                LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
-#endif
-                if (mX11MonitorRTThread)
-                    stopX11Thread();
-                else
-                    LogRelThisFunc(("Attempted to stop X11 monitor thread which is not running (VBoxClient)!\n"));
-        }
-    }
-    else
-    {
-        LogRelFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxClient)\n", rc));
-    }
-    LogRelFlowFunc(("returning %Rrc\n", rc));
-    return rc;
-}
-
-/**
- * Update the set of visible rectangles in the host.
- */
-void VBoxGuestSeamlessHost::notify(RTRECT *pRects, size_t cRects)
-{
-    LogRelFlowFunc(("\n"));
-    if (cRects && !pRects)  /* Assertion */
-    {
-        LogRelThisFunc(("ERROR: called with null pointer!\n"));
-        return;
-    }
-    VbglR3SeamlessSendRects(cRects, pRects);
-    LogRelFlowFunc(("returning\n"));
-}
-
-
-/**
- * The actual event thread function.
- */
-int VBoxGuestSeamlessHost::threadFunction(RTTHREAD self, void *pvUser)
-{
-    VBoxGuestSeamlessHost *pHost = (VBoxGuestSeamlessHost *)pvUser;
-
-    LogRelFlowFunc(("\n"));
-    pHost->mThreadRunning = true;
-    if (0 != pHost)
-    {
-        while (!pHost->mThreadStopping)
-        {
-            if (RT_FAILURE(pHost->nextEvent()) && !pHost->mThreadStopping)
-            {
-                /* If we are not stopping, sleep for a bit to avoid using up too
-                    much CPU while retrying. */
-                RTThreadYield();
-            }
-        }
-    }
-    pHost->mThreadRunning = false;
-    LogRelFlowFunc(("returning VINF_SUCCESS\n"));
-    return VINF_SUCCESS;
-}
-
-/**
- * Send a signal to the thread that it should exit
- */
-void VBoxGuestSeamlessHost::stopThread()
-{
-    int rc;
-
-    LogRelFlowFunc(("\n"));
-    /**
-     * @todo is this reasonable?  If the thread is in the event loop then the cancelEvent()
-     *       will cause it to exit.  If it enters or exits the event loop it will also
-     *       notice that we wish it to exit.  And if it is somewhere in-between, the
-     *       yield() should give it time to get to one of places mentioned above.
-     */
-    mThreadStopping = true;
-    for (int i = 0; (i < 5) && mThreadRunning; ++i)
-    {
-        cancelEvent();
-        RTThreadYield();
-    }
-    rc = RTThreadWait(mThread, RT_INDEFINITE_WAIT, NULL);
-    if (RT_SUCCESS(rc))
-        mThread = NIL_RTTHREAD;
-    else
-        LogRelThisFunc(("Failed to stop seamless event thread, rc=%Rrc!\n",
-                        rc));
-    LogRelFlowFunc(("returning\n"));
-}
-
-/**
- * The actual X11 event thread function.
- */
-int VBoxGuestSeamlessHost::x11ThreadFunction(RTTHREAD self, void *pvUser)
-{
-    VBoxGuestSeamlessHost *pHost = (VBoxGuestSeamlessHost *)pvUser;
-    int rc = VINF_SUCCESS;
-
-    LogRelFlowFunc(("\n"));
-    rc = pHost->mX11Monitor.start();
-    if (RT_SUCCESS(rc))
-    {
-        while (!pHost->mX11ThreadStopping)
-        {
-            pHost->mX11Monitor.nextEvent();
-        }
-        pHost->mX11Monitor.stop();
-    }
-    LogRelFlowFunc(("returning %Rrc\n", rc));
-    return rc;
-}
-
-/**
- * Send a signal to the thread function that it should exit
- */
-void VBoxGuestSeamlessHost::stopX11Thread(void)
-{
-    int rc;
-
-    mX11ThreadStopping = true;
-    mX11Monitor.interruptEvent();
-    rc = RTThreadWait(mX11MonitorRTThread, RT_INDEFINITE_WAIT, NULL);
-    if (RT_SUCCESS(rc))
-        mX11MonitorRTThread = NIL_RTTHREAD;
-    else
-        LogRelThisFunc(("Failed to stop X11 monitor thread, rc=%Rrc!\n",
-                        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: unk/src/VBox/Additions/x11/VBoxClient/seamless-host.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.h	(revision 50337)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/** @file
- * X11 Guest client - seamless mode, missing proper description while using the
- * potentially confusing word 'host'.
- */
-
-/*
- * Copyright (C) 2006-2011 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.
- */
-
-#ifndef __Additions_client_seamless_host_h
-# define __Additions_client_seamless_host_h
-
-#include <iprt/thread.h>
-
-#include <VBox/log.h>
-#include <VBox/VBoxGuestLib.h>      /* for the R3 guest library functions  */
-
-#include "seamless-x11.h"
-
-/**
- * Interface to the host
- */
-class VBoxGuestSeamlessHost : public SeamlessHostProxy
-{
-public:
-    /** Events which can be reported by this class */
-    enum meEvent
-    {
-        /** Empty event */
-        NONE,
-        /** Request to enable seamless mode */
-        ENABLE,
-        /** Request to disable seamless mode */
-        DISABLE
-    };
-
-private:
-    // We don't want a copy constructor or assignment operator
-    VBoxGuestSeamlessHost(const VBoxGuestSeamlessHost&);
-    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;
-    /** Should the X11 monitor thread be stopping? */
-    volatile bool mX11ThreadStopping;
-    /** Host seamless event thread. */
-    RTTHREAD mThread;
-    /** Is the thread running? */
-    volatile bool mThreadRunning;
-    /** Should the thread be stopping? */
-    volatile bool mThreadStopping;
-
-    /**
-     * Waits for a seamless state change events from the host and dispatch it.  This is
-     * meant to be called by the host event monitor thread exclusively.
-     *
-     * @returns        IRPT return code.
-     */
-    int nextEvent(void);
-
-    /**
-     * Interrupt an event wait and cause nextEvent() to return immediately.
-     */
-    void cancelEvent(void) { VbglR3InterruptEventWaits(); }
-    
-    /** Thread function to query seamless activation and deactivation events
-     *  from the host. */
-    static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
-
-    /** Helper to stop the event query thread again. */
-    void stopThread();
-
-    /** Thread function to monitor X11 window configuration changes. */
-    static DECLCALLBACK(int) x11ThreadFunction(RTTHREAD self, void *pvUser);
-
-    /** Helper to stop the X11 monitor thread again. */
-    void stopX11Thread(void);
-
-public:
-    /**
-     * Initialise the guest and ensure that it is capable of handling seamless mode
-     * @param   pX11Monitor Object to monitor X11 guest windows.
-     *
-     * @returns iprt status code
-     */
-    int init(void)
-    {
-        int rc;
-
-        LogRelFlowFunc(("\n"));
-        if (mIsInitialised)
-            return VERR_INTERNAL_ERROR;
-        rc = mX11Monitor.init(this);
-        if (RT_SUCCESS(rc))
-            mIsInitialised = true;
-        return rc;
-    }
-
-    /**
-      * Start the service.
-      * @returns iprt status value
-      */
-    int start(void);
-
-    /**
-     * Stops the service.
-     * @param cMillies how long to wait for the thread to exit
-     */
-    void stop();
-
-    /**
-     * Update the set of visible rectangles in the host.
-     */
-    virtual void notify(RTRECT *pRects, size_t cRects);
-
-    VBoxGuestSeamlessHost(void)
-    {
-        mIsInitialised = false;
-        mX11MonitorRTThread = NIL_RTTHREAD;
-        mX11ThreadStopping = false;
-        mThread = NIL_RTTHREAD;
-        mThreadRunning = false;
-        mThreadStopping = false;
-    }
-
-    ~VBoxGuestSeamlessHost()
-    {
-        LogRelFlowFunc(("\n"));
-        if (mThread)
-            stop();
-        LogRelFlowFunc(("returning\n"));
-    }
-};
-
-#endif /* __Additions_xclient_seamless_h not defined */
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp	(revision 50338)
@@ -71,5 +71,5 @@
   * @returns true if it can handle seamless, false otherwise
   */
-int VBoxGuestSeamlessX11::init(SeamlessHostProxy *pHost)
+int SeamlessX11::init(SeamlessHostProxy *pHost)
 {
     int rc = VINF_SUCCESS;
@@ -99,5 +99,5 @@
  * @todo This function should switch the guest to fullscreen mode.
  */
-int VBoxGuestSeamlessX11::start(void)
+int SeamlessX11::start(void)
 {
     int rc = VINF_SUCCESS;
@@ -116,5 +116,5 @@
 /** Stop reporting seamless events to the host.  Free information about guest windows
     and stop requesting updates. */
-void VBoxGuestSeamlessX11::stop(void)
+void SeamlessX11::stop(void)
 {
     LogRelFlowFunc(("\n"));
@@ -125,5 +125,5 @@
 }
 
-void VBoxGuestSeamlessX11::monitorClientList(void)
+void SeamlessX11::monitorClientList(void)
 {
     LogRelFlowFunc(("called\n"));
@@ -131,5 +131,5 @@
 }
 
-void VBoxGuestSeamlessX11::unmonitorClientList(void)
+void SeamlessX11::unmonitorClientList(void)
 {
     LogRelFlowFunc(("called\n"));
@@ -141,5 +141,5 @@
  * X server.
  */
-void VBoxGuestSeamlessX11::rebuildWindowTree(void)
+void SeamlessX11::rebuildWindowTree(void)
 {
     LogRelFlowFunc(("called\n"));
@@ -156,5 +156,5 @@
  * @param hRoot the virtual root window to be examined
  */
-void VBoxGuestSeamlessX11::addClients(const Window hRoot)
+void SeamlessX11::addClients(const Window hRoot)
 {
     /** Unused out parameters of XQueryTree */
@@ -178,5 +178,5 @@
 
 
-void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
+void SeamlessX11::addClientWindow(const Window hWin)
 {
     LogRelFlowFunc(("\n"));
@@ -241,5 +241,5 @@
  * @param hWin the window to be examined
  */
-bool VBoxGuestSeamlessX11::isVirtualRoot(Window hWin)
+bool SeamlessX11::isVirtualRoot(Window hWin)
 {
     unsigned char *windowTypeRaw = NULL;
@@ -275,5 +275,5 @@
  * Free all information in the tree of visible windows
  */
-void VBoxGuestSeamlessX11::freeWindowTree(void)
+void SeamlessX11::freeWindowTree(void)
 {
     /* We use post-increment in the operation to prevent the iterator from being invalidated. */
@@ -289,5 +289,5 @@
  * @note Called from the guest event thread.
  */
-void VBoxGuestSeamlessX11::nextEvent(void)
+void SeamlessX11::nextEvent(void)
 {
     XEvent event;
@@ -345,5 +345,5 @@
  * @param event the X11 event structure
  */
-void VBoxGuestSeamlessX11::doConfigureEvent(Window hWin)
+void SeamlessX11::doConfigureEvent(Window hWin)
 {
     VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
@@ -381,5 +381,5 @@
  * @param event the X11 event structure
  */
-void VBoxGuestSeamlessX11::doMapEvent(Window hWin)
+void SeamlessX11::doMapEvent(Window hWin)
 {
     LogRelFlowFunc(("\n"));
@@ -399,5 +399,5 @@
  * @param event the X11 event structure
  */
-void VBoxGuestSeamlessX11::doShapeEvent(Window hWin)
+void SeamlessX11::doShapeEvent(Window hWin)
 {
     LogRelFlowFunc(("\n"));
@@ -427,5 +427,5 @@
  * @param event the X11 event structure
  */
-void VBoxGuestSeamlessX11::doUnmapEvent(Window hWin)
+void SeamlessX11::doUnmapEvent(Window hWin)
 {
     LogRelFlowFunc(("\n"));
@@ -442,5 +442,5 @@
  * Gets the list of visible rectangles
  */
-RTRECT *VBoxGuestSeamlessX11::getRects(void)
+RTRECT *SeamlessX11::getRects(void)
 {
     return mpRects;
@@ -450,5 +450,5 @@
  * Gets the number of rectangles in the visible rectangle list
  */
-size_t VBoxGuestSeamlessX11::getRectCount(void)
+size_t SeamlessX11::getRectCount(void)
 {
     return mcRects;
@@ -501,5 +501,5 @@
  * Updates the list of seamless rectangles
  */
-int VBoxGuestSeamlessX11::updateRects(void)
+int SeamlessX11::updateRects(void)
 {
     LogRelFlowFunc(("\n"));
@@ -528,5 +528,5 @@
  * @note This function should only be called from the host event thread.
  */
-bool VBoxGuestSeamlessX11::interruptEvent(void)
+bool SeamlessX11::interruptEvent(void)
 {
     bool rc = false;
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h	(revision 50338)
@@ -155,10 +155,10 @@
 };
 
-class VBoxGuestSeamlessX11
+class SeamlessX11
 {
 private:
     // We don't want a copy constructor or assignment operator
-    VBoxGuestSeamlessX11(const VBoxGuestSeamlessX11&);
-    VBoxGuestSeamlessX11& operator=(const VBoxGuestSeamlessX11&);
+    SeamlessX11(const SeamlessX11&);
+    SeamlessX11& operator=(const SeamlessX11&);
 
     // Private member variables
@@ -248,9 +248,9 @@
     void doShapeEvent(Window hWin);
 
-    VBoxGuestSeamlessX11(void)
+    SeamlessX11(void)
         : mHost(0), mDisplay(NULL), mpRects(NULL), mcRects(0),
           mSupportsShape(false), mEnabled(false), mChanged(false) {}
 
-    ~VBoxGuestSeamlessX11()
+    ~SeamlessX11()
     {
         uninit();
Index: /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp	(revision 50338)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp	(revision 50338)
@@ -0,0 +1,305 @@
+/** @file
+ * 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-2014 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.
+ */
+
+/*****************************************************************************
+*   Header files                                                             *
+*****************************************************************************/
+
+#include <X11/Xlib.h>
+
+#include <VBox/log.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuestLib.h>
+#include <iprt/err.h>
+
+#include "VBoxClient.h"
+#include "seamless.h"
+
+/**
+ * Start the service.
+ * @returns iprt status value
+ */
+int SeamlessMain::start(void)
+{
+    int rc = VERR_NOT_SUPPORTED;
+
+    LogRelFlowFunc(("\n"));
+    if (mThread)  /* Assertion */
+    {
+        LogRel(("VBoxClient: seamless service started twice!\n"));
+        return VERR_INTERNAL_ERROR;
+    }
+    rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("VBoxClient (seamless): failed to set the guest IRQ filter mask, rc=%Rrc\n", rc));
+    }
+    rc = VbglR3SeamlessSetCap(true);
+    if (RT_SUCCESS(rc))
+    {
+        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,
+                            "Host events");
+        if (RT_FAILURE(rc))
+        {
+            LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc.  Disabled seamless capability on host again.\n", rc));
+            VbglR3SeamlessSetCap(false);
+        }
+    }
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("VBoxClient (seamless): failed to enable seamless capability on host, rc=%Rrc\n", rc));
+    }
+    LogRelFlowFunc(("returning %Rrc\n", rc));
+    return rc;
+}
+
+/** Stops the service. */
+void SeamlessMain::stop()
+{
+    LogRelFlowFunc(("\n"));
+    if (!mThread)  /* Assertion */
+        LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
+    else
+        stopThread();
+    if (mX11MonitorRTThread)
+        stopX11Thread();
+    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
+    VbglR3SeamlessSetCap(false);
+    LogRelFlowFunc(("returning\n"));
+}
+
+/**
+ * Waits for a seamless state change events from the host and dispatch it.
+ *
+ * @returns        IRPT return code.
+ */
+int SeamlessMain::nextEvent(void)
+{
+    VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
+
+    LogRelFlowFunc(("\n"));
+    int rc = VbglR3SeamlessWaitEvent(&newMode);
+    if (RT_SUCCESS(rc))
+    {
+        switch(newMode)
+        {
+            case VMMDev_Seamless_Visible_Region:
+            /* A simplified seamless mode, obtained by making the host VM window borderless and
+              making the guest desktop transparent. */
+#ifdef DEBUG
+                LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
+#endif
+                mX11ThreadStopping = false;
+                /** @todo Do something on failure, like bail out. */
+                if (RT_FAILURE(RTThreadCreate(&mX11MonitorRTThread,
+                               x11ThreadFunction, this, 0, RTTHREADTYPE_MSG_PUMP,
+                               RTTHREADFLAGS_WAITABLE, "X11 events")))
+                    LogRelFunc(("Warning: failed to start X11 monitor thread (VBoxClient).\n"));
+                break;
+            case VMMDev_Seamless_Host_Window:
+            /* One host window represents one guest window.  Not yet implemented. */
+                LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received (VBoxClient).\n"));
+                /* fall through to default */
+            default:
+                LogRelFunc(("Warning: unsupported VMMDev_Seamless request %d received (VBoxClient).\n", newMode));
+                /* fall through to case VMMDev_Seamless_Disabled */
+            case VMMDev_Seamless_Disabled:
+#ifdef DEBUG
+                LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
+#endif
+                if (mX11MonitorRTThread)
+                    stopX11Thread();
+                else
+                    LogRelThisFunc(("Attempted to stop X11 monitor thread which is not running (VBoxClient)!\n"));
+        }
+    }
+    else
+    {
+        LogRelFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxClient)\n", rc));
+    }
+    LogRelFlowFunc(("returning %Rrc\n", rc));
+    return rc;
+}
+
+/**
+ * Update the set of visible rectangles in the host.
+ */
+void SeamlessMain::notify(RTRECT *pRects, size_t cRects)
+{
+    LogRelFlowFunc(("\n"));
+    if (cRects && !pRects)  /* Assertion */
+    {
+        LogRelThisFunc(("ERROR: called with null pointer!\n"));
+        return;
+    }
+    VbglR3SeamlessSendRects(cRects, pRects);
+    LogRelFlowFunc(("returning\n"));
+}
+
+
+/**
+ * The actual event thread function.
+ */
+int SeamlessMain::threadFunction(RTTHREAD self, void *pvUser)
+{
+    SeamlessMain *pHost = (SeamlessMain *)pvUser;
+
+    LogRelFlowFunc(("\n"));
+    pHost->mThreadRunning = true;
+    if (0 != pHost)
+    {
+        while (!pHost->mThreadStopping)
+        {
+            if (RT_FAILURE(pHost->nextEvent()) && !pHost->mThreadStopping)
+            {
+                /* If we are not stopping, sleep for a bit to avoid using up too
+                    much CPU while retrying. */
+                RTThreadYield();
+            }
+        }
+    }
+    pHost->mThreadRunning = false;
+    LogRelFlowFunc(("returning VINF_SUCCESS\n"));
+    return VINF_SUCCESS;
+}
+
+/**
+ * Send a signal to the thread that it should exit
+ */
+void SeamlessMain::stopThread()
+{
+    int rc;
+
+    LogRelFlowFunc(("\n"));
+    /**
+     * @todo is this reasonable?  If the thread is in the event loop then the cancelEvent()
+     *       will cause it to exit.  If it enters or exits the event loop it will also
+     *       notice that we wish it to exit.  And if it is somewhere in-between, the
+     *       yield() should give it time to get to one of places mentioned above.
+     */
+    mThreadStopping = true;
+    for (int i = 0; (i < 5) && mThreadRunning; ++i)
+    {
+        cancelEvent();
+        RTThreadYield();
+    }
+    rc = RTThreadWait(mThread, RT_INDEFINITE_WAIT, NULL);
+    if (RT_SUCCESS(rc))
+        mThread = NIL_RTTHREAD;
+    else
+        LogRelThisFunc(("Failed to stop seamless event thread, rc=%Rrc!\n",
+                        rc));
+    LogRelFlowFunc(("returning\n"));
+}
+
+/**
+ * The actual X11 event thread function.
+ */
+int SeamlessMain::x11ThreadFunction(RTTHREAD self, void *pvUser)
+{
+    SeamlessMain *pHost = (SeamlessMain *)pvUser;
+    int rc = VINF_SUCCESS;
+
+    LogRelFlowFunc(("\n"));
+    rc = pHost->mX11Monitor.start();
+    if (RT_SUCCESS(rc))
+    {
+        while (!pHost->mX11ThreadStopping)
+        {
+            pHost->mX11Monitor.nextEvent();
+        }
+        pHost->mX11Monitor.stop();
+    }
+    LogRelFlowFunc(("returning %Rrc\n", rc));
+    return rc;
+}
+
+/**
+ * Send a signal to the thread function that it should exit
+ */
+void SeamlessMain::stopX11Thread(void)
+{
+    int rc;
+
+    mX11ThreadStopping = true;
+    mX11Monitor.interruptEvent();
+    rc = RTThreadWait(mX11MonitorRTThread, RT_INDEFINITE_WAIT, NULL);
+    if (RT_SUCCESS(rc))
+        mX11MonitorRTThread = NIL_RTTHREAD;
+    else
+        LogRelThisFunc(("Failed to stop X11 monitor thread, rc=%Rrc!\n",
+                        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:
+    SeamlessMain 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.h
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/seamless.h	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/seamless.h	(revision 50338)
@@ -1,5 +1,5 @@
 /** @file
- *
- * Guest client: seamless mode.
+ * X11 Guest client - seamless mode, missing proper description while using the
+ * potentially confusing word 'host'.
  */
 
@@ -16,51 +16,133 @@
  */
 
-#ifndef __Additions_xclient_seamless_h
-# define __Additions_xclient_seamless_h
+#ifndef __Additions_client_seamless_host_h
+# define __Additions_client_seamless_host_h
+
+#include <iprt/thread.h>
 
 #include <VBox/log.h>
+#include <VBox/VBoxGuestLib.h>      /* for the R3 guest library functions  */
 
-#include "seamless-host.h"
 #include "seamless-x11.h"
 
-class VBoxGuestSeamless
+/**
+ * Interface to the host
+ */
+class SeamlessMain : public SeamlessHostProxy
 {
+public:
+    /** Events which can be reported by this class */
+    enum meEvent
+    {
+        /** Empty event */
+        NONE,
+        /** Request to enable seamless mode */
+        ENABLE,
+        /** Request to disable seamless mode */
+        DISABLE
+    };
+
 private:
-    VBoxGuestSeamlessHost mHost;
+    // We don't want a copy constructor or assignment operator
+    SeamlessMain(const SeamlessMain&);
+    SeamlessMain& operator=(const SeamlessMain&);
 
-    bool isInitialised;
+    /** Have we been initialised yet? */
+    bool mIsInitialised;
+    /** X11 event monitor object */
+    SeamlessX11 mX11Monitor;
+
+    /** Thread to start and stop when we enter and leave seamless mode which
+     *  monitors X11 windows in the guest. */
+    RTTHREAD mX11MonitorRTThread;
+    /** Should the X11 monitor thread be stopping? */
+    volatile bool mX11ThreadStopping;
+    /** Host seamless event thread. */
+    RTTHREAD mThread;
+    /** Is the thread running? */
+    volatile bool mThreadRunning;
+    /** Should the thread be stopping? */
+    volatile bool mThreadStopping;
+
+    /**
+     * Waits for a seamless state change events from the host and dispatch it.  This is
+     * meant to be called by the host event monitor thread exclusively.
+     *
+     * @returns        IRPT return code.
+     */
+    int nextEvent(void);
+
+    /**
+     * Interrupt an event wait and cause nextEvent() to return immediately.
+     */
+    void cancelEvent(void) { VbglR3InterruptEventWaits(); }
+    
+    /** Thread function to query seamless activation and deactivation events
+     *  from the host. */
+    static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
+
+    /** Helper to stop the event query thread again. */
+    void stopThread();
+
+    /** Thread function to monitor X11 window configuration changes. */
+    static DECLCALLBACK(int) x11ThreadFunction(RTTHREAD self, void *pvUser);
+
+    /** Helper to stop the X11 monitor thread again. */
+    void stopX11Thread(void);
+
 public:
+    /**
+     * Initialise the guest and ensure that it is capable of handling seamless mode
+     * @param   pX11Monitor Object to monitor X11 guest windows.
+     *
+     * @returns iprt status code
+     */
     int init(void)
     {
-        int rc = VINF_SUCCESS;
+        int rc;
 
         LogRelFlowFunc(("\n"));
-        if (isInitialised)  /* Assertion */
-        {
-            LogRelFunc(("error: called a second time! (VBoxClient)\n"));
-            rc = VERR_INTERNAL_ERROR;
-        }
+        if (mIsInitialised)
+            return VERR_INTERNAL_ERROR;
+        rc = mX11Monitor.init(this);
         if (RT_SUCCESS(rc))
-        {
-            rc = mHost.init();
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = mHost.start();
-        }
-        if (RT_SUCCESS(rc))
-        {
-            isInitialised = true;
-        }
-        if (RT_FAILURE(rc))
-        {
-            LogRelFunc(("returning %Rrc (VBoxClient)\n", rc));
-        }
-        LogRelFlowFunc(("returning %Rrc\n", rc));
+            mIsInitialised = true;
         return rc;
     }
 
-    VBoxGuestSeamless() { isInitialised = false; }
-    ~VBoxGuestSeamless() { }
+    /**
+      * Start the service.
+      * @returns iprt status value
+      */
+    int start(void);
+
+    /**
+     * Stops the service.
+     * @param cMillies how long to wait for the thread to exit
+     */
+    void stop();
+
+    /**
+     * Update the set of visible rectangles in the host.
+     */
+    virtual void notify(RTRECT *pRects, size_t cRects);
+
+    SeamlessMain(void)
+    {
+        mIsInitialised = false;
+        mX11MonitorRTThread = NIL_RTTHREAD;
+        mX11ThreadStopping = false;
+        mThread = NIL_RTTHREAD;
+        mThreadRunning = false;
+        mThreadStopping = false;
+    }
+
+    ~SeamlessMain()
+    {
+        LogRelFlowFunc(("\n"));
+        if (mThread)
+            stop();
+        LogRelFlowFunc(("returning\n"));
+    }
 };
 
Index: /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp	(revision 50338)
@@ -598,5 +598,5 @@
 static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
 {
-    VBoxGuestSeamlessX11 subject;
+    SeamlessX11 subject;
     testHost host;
     unsigned cErrs = 0;
Index: /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp	(revision 50337)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp	(revision 50338)
@@ -119,5 +119,5 @@
     RTSemEventCreate(&eventSem);
     /** Our instance of the seamless class. */
-    VBoxGuestSeamless seamless;
+    SeamlessMain seamless;
     LogRel(("Starting seamless Guest Additions...\n"));
     rc = seamless.init();
