summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/VBox/Additions/x11/VBoxClient/Makefile.kmk1
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-host.cpp83
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-host.h57
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp2
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless-x11.h18
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless.cpp55
-rw-r--r--src/VBox/Additions/x11/VBoxClient/seamless.h21
-rw-r--r--src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp3
-rw-r--r--src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp1
9 files changed, 108 insertions, 133 deletions
diff --git a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
index cbbfabe6f41..94b09f5b7c2 100644
--- a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
+++ b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
@@ -58,7 +58,6 @@ VBoxClient_LIBS += \
ifdef VBOX_X11_SEAMLESS_GUEST
VBoxClient_DEFS += SEAMLESS_GUEST DYNAMIC_RESIZE
VBoxClient_SOURCES += \
- seamless.cpp \
seamless-host.cpp \
seamless-x11.cpp \
display.cpp \
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
index f3bbe2d0fc4..9e8bd28dd96 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
@@ -1,10 +1,11 @@
/** @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
* available from http://www.virtualbox.org. This file is free software;
@@ -18,11 +19,15 @@
/*****************************************************************************
* 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"
@@ -49,6 +54,11 @@ int VBoxGuestSeamlessHost::start(void)
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");
@@ -67,13 +77,13 @@ int VBoxGuestSeamlessHost::start(void)
}
/** Stops the service. */
-void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */)
+void VBoxGuestSeamlessHost::stop()
{
LogRelFlowFunc(("\n"));
if (!mThread) /* Assertion */
LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
else
- stopThread(cMillies);
+ stopThread();
if (mX11MonitorRTThread)
stopX11Thread();
VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
@@ -102,7 +112,6 @@ int VBoxGuestSeamlessHost::nextEvent(void)
#ifdef DEBUG
LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
#endif
- mState = ENABLE;
mX11ThreadStopping = false;
/** @todo Do something on failure, like bail out. */
if (RT_FAILURE(RTThreadCreate(&mX11MonitorRTThread,
@@ -121,7 +130,6 @@ int VBoxGuestSeamlessHost::nextEvent(void)
#ifdef DEBUG
LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
#endif
- mState = DISABLE;
if (mX11MonitorRTThread)
stopX11Thread();
else
@@ -181,7 +189,7 @@ int VBoxGuestSeamlessHost::threadFunction(RTTHREAD self, void *pvUser)
/**
* Send a signal to the thread that it should exit
*/
-void VBoxGuestSeamlessHost::stopThread(RTMSINTERVAL cMillies)
+void VBoxGuestSeamlessHost::stopThread()
{
int rc;
@@ -216,14 +224,14 @@ int VBoxGuestSeamlessHost::x11ThreadFunction(RTTHREAD self, void *pvUser)
int rc = VINF_SUCCESS;
LogRelFlowFunc(("\n"));
- rc = pHost->mX11Monitor->start();
+ rc = pHost->mX11Monitor.start();
if (RT_SUCCESS(rc))
{
while (!pHost->mX11ThreadStopping)
{
- pHost->mX11Monitor->nextEvent();
+ pHost->mX11Monitor.nextEvent();
}
- pHost->mX11Monitor->stop();
+ pHost->mX11Monitor.stop();
}
LogRelFlowFunc(("returning %Rrc\n", rc));
return rc;
@@ -237,7 +245,7 @@ void VBoxGuestSeamlessHost::stopX11Thread(void)
int rc;
mX11ThreadStopping = true;
- mX11Monitor->interruptEvent();
+ mX11Monitor.interruptEvent();
rc = RTThreadWait(mX11MonitorRTThread, RT_INDEFINITE_WAIT, NULL);
if (RT_SUCCESS(rc))
mX11MonitorRTThread = NIL_RTTHREAD;
@@ -245,3 +253,54 @@ void VBoxGuestSeamlessHost::stopX11Thread(void)
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;
+}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.h b/src/VBox/Additions/x11/VBoxClient/seamless-host.h
index 90bdf573c55..d80a9d06fac 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-host.h
@@ -23,23 +23,12 @@
#include <VBox/log.h>
#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:
/** Events which can be reported by this class */
@@ -58,11 +47,14 @@ private:
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;
- /** X11 event monitor class */
- VBoxGuestSeamlessX11 *mX11Monitor;
/** Should the X11 monitor thread be stopping? */
volatile bool mX11ThreadStopping;
/** Host seamless event thread. */
@@ -71,8 +63,6 @@ private:
volatile bool mThreadRunning;
/** Should the thread be stopping? */
volatile bool mThreadStopping;
- /** Last request issued by the host. */
- meEvent mState;
/**
* Waits for a seamless state change events from the host and dispatch it. This is
@@ -92,7 +82,7 @@ private:
static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
/** Helper to stop the event query thread again. */
- void stopThread(RTMSINTERVAL cMillies);
+ void stopThread();
/** Thread function to monitor X11 window configuration changes. */
static DECLCALLBACK(int) x11ThreadFunction(RTTHREAD self, void *pvUser);
@@ -107,17 +97,17 @@ public:
*
* @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;
}
/**
@@ -130,10 +120,7 @@ public:
* Stops the service.
* @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();
/**
* Update the set of visible rectangles in the host.
@@ -142,23 +129,19 @@ public:
VBoxGuestSeamlessHost(void)
{
+ mIsInitialised = false;
mX11MonitorRTThread = NIL_RTTHREAD;
- mX11Monitor = NULL;
mX11ThreadStopping = false;
mThread = NIL_RTTHREAD;
mThreadRunning = false;
mThreadStopping = false;
- mState = NONE;
}
~VBoxGuestSeamlessHost()
{
LogRelFlowFunc(("\n"));
- if (mThread) /* Assertion */
- {
- LogRel(("VBoxClient: seamless host object still running! Stopping...\n"));
- stop(2000);
- }
+ if (mThread)
+ stop();
LogRelFlowFunc(("returning\n"));
}
};
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
index 826a75cb5f8..57515228c5a 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
@@ -70,7 +70,7 @@ static unsigned char *XXGetProperty (Display *aDpy, Window aWnd, Atom aPropType,
*
* @returns true if it can handle seamless, false otherwise
*/
-int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessHostInt *pHost)
+int VBoxGuestSeamlessX11::init(SeamlessHostProxy *pHost)
{
int rc = VINF_SUCCESS;
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
index 111727d851f..dc517b060a0 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
@@ -22,9 +22,6 @@
#include <VBox/log.h>
#include <iprt/avl.h>
-#include "seamless-x11.h"
-#include "seamless-host.h"
-
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
@@ -35,6 +32,17 @@
/* 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.
Used inside of VBoxGuestWindowList. */
struct VBoxGuestWinInfo {
@@ -155,7 +163,7 @@ private:
// Private member variables
/** Pointer to the host class. */
- VBoxGuestSeamlessHostInt *mHost;
+ SeamlessHostProxy *mHost;
/** Our connection to the X11 display we are running on. */
Display *mDisplay;
/** Class to keep track of visible guest windows. */
@@ -200,7 +208,7 @@ public:
*
* @returns iprt status code
*/
- int init(VBoxGuestSeamlessHostInt *pHost);
+ int init(SeamlessHostProxy *pHost);
/**
* Shutdown seamless event monitoring.
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless.cpp b/src/VBox/Additions/x11/VBoxClient/seamless.cpp
deleted file mode 100644
index e3ab64a877a..00000000000
--- a/src/VBox/Additions/x11/VBoxClient/seamless.cpp
+++ /dev/null
@@ -1,55 +0,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;
-}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless.h b/src/VBox/Additions/x11/VBoxClient/seamless.h
index 2bf07906596..68460b8fa01 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless.h
@@ -27,7 +27,6 @@ class VBoxGuestSeamless
{
private:
VBoxGuestSeamlessHost mHost;
- VBoxGuestSeamlessX11 mGuest;
bool isInitialised;
public:
@@ -43,11 +42,7 @@ public:
}
if (RT_SUCCESS(rc))
{
- rc = mHost.init(&mGuest);
- }
- if (RT_SUCCESS(rc))
- {
- rc = mGuest.init(&mHost);
+ rc = mHost.init();
}
if (RT_SUCCESS(rc))
{
@@ -65,20 +60,8 @@ public:
return rc;
}
- 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() { }
};
#endif /* __Additions_xclient_seamless_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
index 88036cc7eee..b144a6b3c31 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
@@ -28,7 +28,6 @@
#include <iprt/string.h>
#include "../seamless.h"
-#include "../seamless-host.h"
#undef DefaultRootWindow
@@ -298,7 +297,7 @@ int XFlush(Display *display)
}
/** Dummy host class */
-class testHost: public VBoxGuestSeamlessHostInt
+class testHost: public SeamlessHostProxy
{
bool mfNotified;
public:
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
index 638f2cff73b..30032f748e3 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
@@ -126,6 +126,5 @@ int main( int argc, char **argv)
RTPrintf("Failed to initialise seamless Additions, rc = %d\n", rc);
}
RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
- seamless.uninit();
return rc;
}