seamless.h revision 3b3b3f38fab88ab36be8fef50a2a1edb7fca7e51
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** @file
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Guest client: seamless mode.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Copyright (C) 2006-2007 Oracle Corporation
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * available from http://www.virtualbox.org. This file is free software;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * General Public License (GPL) as published by the Free Software
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifndef __Additions_xclient_seamless_h
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# define __Additions_xclient_seamless_h
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <VBox/log.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "seamless-host.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "seamless-guest.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "seamless-glue.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** Thread function class for VBoxGuestSeamlessGuest. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncclass VBoxGuestSeamlessGuestThread: public VBoxGuestThreadFunction
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsyncprivate:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** The guest class "owning" us. */
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessGuestImpl *mGuest;
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync /** The guest observer monitoring the guest. */
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessObserver *mObserver;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** Should we exit the thread? */
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync bool mExit;
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync // Copying or assigning a thread object is not sensible
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessGuestThread(const VBoxGuestSeamlessGuestThread&);
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessGuestThread& operator=(const VBoxGuestSeamlessGuestThread&);
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsyncpublic:
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessGuestThread(VBoxGuestSeamlessGuestImpl *pGuest,
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync VBoxGuestSeamlessObserver *pObserver)
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync { mGuest = pGuest; mObserver = pObserver; mExit = false; }
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync virtual ~VBoxGuestSeamlessGuestThread(void) {}
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync /**
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync * The actual thread function.
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync *
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync * @returns iprt status code as thread return value
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync * @param pParent the VBoxGuestThread running this thread function
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync */
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync virtual int threadFunction(VBoxGuestThread *pThread)
236b6e0fdf652661ff4c655314fe488998c5c17dvboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("\n"));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = mGuest->start();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (!pThread->isStopping())
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuest->nextEvent();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuest->stop();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("returning %Rrc\n", rc));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Send a signal to the thread function that it should exit
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync virtual void stop(void) { mGuest->interruptEvent(); }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** Observer for the host class - start and stop seamless reporting in the guest when the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync host requests. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncclass VBoxGuestSeamlessHostObserver : public VBoxGuestSeamlessObserver
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncprivate:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessHost *mHost;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestThread *mGuestThread;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncpublic:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessHostObserver(VBoxGuestSeamlessHost *pHost,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestThread *pGuestThread)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mHost = pHost;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuestThread = pGuestThread;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync virtual void notify(void)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch (mHost->getState())
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case VBoxGuestSeamlessHost::ENABLE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuestThread->start();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case VBoxGuestSeamlessHost::DISABLE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuestThread->stop(RT_INDEFINITE_WAIT, 0);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** Observer for the guest class - send the host updated seamless rectangle information when
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync it becomes available. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncclass VBoxGuestSeamlessGuestObserver : public VBoxGuestSeamlessObserver
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncprivate:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessHost *mHost;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestImpl *mGuest;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncpublic:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestObserver(VBoxGuestSeamlessHost *pHost,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestImpl *pGuest)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mHost = pHost;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuest = pGuest;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync virtual void notify(void)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mHost->updateRects(mGuest->getRects(), mGuest->getRectCount());
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncclass VBoxGuestSeamless
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncprivate:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessHost mHost;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestImpl mGuest;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestThread mGuestFunction;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestThread mGuestThread;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessHostObserver mHostObs;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamlessGuestObserver mGuestObs;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bool isInitialised;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncpublic:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int init(void)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("\n"));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (isInitialised) /* Assertion */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFunc(("error: called a second time! (VBoxClient)\n"));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_INTERNAL_ERROR;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = mHost.init(&mHostObs);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = mGuest.init(&mGuestObs);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = mHost.start();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync isInitialised = true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_FAILURE(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFunc(("returning %Rrc (VBoxClient)\n", rc));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("returning %Rrc\n", rc));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync void uninit(RTMSINTERVAL cMillies = RT_INDEFINITE_WAIT)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("\n"));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (isInitialised)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mHost.stop(cMillies);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuestThread.stop(cMillies, 0);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuest.uninit();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync isInitialised = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync LogRelFlowFunc(("returning\n"));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestSeamless() : mGuestFunction(&mGuest, &mGuestObs),
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mGuestThread(&mGuestFunction, 0, RTTHREADTYPE_MSG_PUMP,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTTHREADFLAGS_WAITABLE, "Guest events"),
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mHostObs(&mHost, &mGuestThread), mGuestObs(&mHost, &mGuest)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync isInitialised = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ~VBoxGuestSeamless() { uninit(); }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif /* __Additions_xclient_seamless_h not defined */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync