VirtualBox

Changeset 99600 in vbox


Ignore:
Timestamp:
May 4, 2023 10:29:18 AM (19 months ago)
Author:
vboxsync
Message:

Guest Additions/VBoxClient: Moved the X11-specific code for seamless mode into an own submodule and using the actual service as a (runtime) wrapper (for also the Wayland-specific code later). bugref:10427

Location:
trunk/src/VBox/Additions/x11/VBoxClient
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp

    r98535 r99600  
    3636#include <VBox/log.h>
    3737
     38#include "seamless.h"
    3839#include "seamless-x11.h"
    3940#include "VBoxClient.h"
     
    9091 * @returns true if it can handle seamless, false otherwise
    9192 */
    92 int SeamlessX11::init(PFNSENDREGIONUPDATE pHostCallback)
     93int VBClX11SeamlessMonitor::init(PFNSENDREGIONUPDATE pHostCallback)
    9394{
    9495    int rc = VINF_SUCCESS;
     
    115116 * Shutdown seamless event monitoring.
    116117 */
    117 void SeamlessX11::uninit(void)
     118void VBClX11SeamlessMonitor::uninit(void)
    118119{
    119120    if (mHostCallback)
     
    150151 * @todo This function should switch the guest to fullscreen mode.
    151152 */
    152 int SeamlessX11::start(void)
     153int VBClX11SeamlessMonitor::start(void)
    153154{
    154155    int rc = VINF_SUCCESS;
     
    169170/** Stop reporting seamless events to the host.  Free information about guest windows
    170171    and stop requesting updates. */
    171 void SeamlessX11::stop(void)
     172void VBClX11SeamlessMonitor::stop(void)
    172173{
    173174    LogRelFlowFuncEnter();
     
    180181}
    181182
    182 void SeamlessX11::monitorClientList(void)
     183void VBClX11SeamlessMonitor::monitorClientList(void)
    183184{
    184185    LogRelFlowFuncEnter();
     
    186187}
    187188
    188 void SeamlessX11::unmonitorClientList(void)
     189void VBClX11SeamlessMonitor::unmonitorClientList(void)
    189190{
    190191    LogRelFlowFuncEnter();
     
    196197 * X server.
    197198 */
    198 void SeamlessX11::rebuildWindowTree(void)
     199void VBClX11SeamlessMonitor::rebuildWindowTree(void)
    199200{
    200201    LogRelFlowFuncEnter();
     
    211212 * @param hRoot the virtual root window to be examined
    212213 */
    213 void SeamlessX11::addClients(const Window hRoot)
     214void VBClX11SeamlessMonitor::addClients(const Window hRoot)
    214215{
    215216    /** Unused out parameters of XQueryTree */
     
    233234
    234235
    235 void SeamlessX11::addClientWindow(const Window hWin)
     236void VBClX11SeamlessMonitor::addClientWindow(const Window hWin)
    236237{
    237238    LogRelFlowFuncEnter();
     
    297298 * @param hWin the window to be examined
    298299 */
    299 bool SeamlessX11::isVirtualRoot(Window hWin)
     300bool VBClX11SeamlessMonitor::isVirtualRoot(Window hWin)
    300301{
    301302    unsigned char *windowTypeRaw = NULL;
     
    331332 * Free all information in the tree of visible windows
    332333 */
    333 void SeamlessX11::freeWindowTree(void)
     334void VBClX11SeamlessMonitor::freeWindowTree(void)
    334335{
    335336    /* We use post-increment in the operation to prevent the iterator from being invalidated. */
     
    345346 * @note Called from the guest event thread.
    346347 */
    347 void SeamlessX11::nextConfigurationEvent(void)
     348void VBClX11SeamlessMonitor::nextConfigurationEvent(void)
    348349{
    349350    XEvent event;
     
    423424 * @param hWin the window to be examined
    424425 */
    425 void SeamlessX11::doConfigureEvent(Window hWin)
     426void VBClX11SeamlessMonitor::doConfigureEvent(Window hWin)
    426427{
    427428    VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
     
    445446 * @param hWin the window to be examined
    446447 */
    447 void SeamlessX11::doShapeEvent(Window hWin)
     448void VBClX11SeamlessMonitor::doShapeEvent(Window hWin)
    448449{
    449450    LogRelFlowFuncEnter();
     
    471472 * Gets the list of visible rectangles
    472473 */
    473 RTRECT *SeamlessX11::getRects(void)
     474RTRECT *VBClX11SeamlessMonitor::getRects(void)
    474475{
    475476    return mpRects;
     
    479480 * Gets the number of rectangles in the visible rectangle list
    480481 */
    481 size_t SeamlessX11::getRectCount(void)
     482size_t VBClX11SeamlessMonitor::getRectCount(void)
    482483{
    483484    return mcRects;
     
    529530 * Updates the list of seamless rectangles
    530531 */
    531 int SeamlessX11::updateRects(void)
     532int VBClX11SeamlessMonitor::updateRects(void)
    532533{
    533534    LogRelFlowFuncEnter();
     
    554555 * @note This function should only be called from the host event thread.
    555556 */
    556 bool SeamlessX11::interruptEventWait(void)
     557bool VBClX11SeamlessMonitor::interruptEventWait(void)
    557558{
    558559    LogRelFlowFuncEnter();
     
    587588    return rc;
    588589}
     590
     591
     592/*********************************************************************************************************************************
     593 * VBClX11SeamlessSvc implementation                                                                                             *
     594 ********************************************************************************************************************************/
     595
     596VBClX11SeamlessSvc::VBClX11SeamlessSvc(void)
     597{
     598    mX11MonitorThread         = NIL_RTTHREAD;
     599    mX11MonitorThreadStopping = false;
     600
     601    mMode    = VMMDev_Seamless_Disabled;
     602    mfPaused = true;
     603}
     604
     605VBClX11SeamlessSvc::~VBClX11SeamlessSvc()
     606{
     607    /* Stopping will be done via main.cpp. */
     608}
     609
     610/** @copydoc VBCLSERVICE::pfnInit */
     611int VBClX11SeamlessSvc::init(void)
     612{
     613    int rc;
     614    const char *pcszStage;
     615
     616    do
     617    {
     618        pcszStage = "Connecting to the X server";
     619        rc = mX11Monitor.init(VBClSeamnlessSendRegionUpdate);
     620        if (RT_FAILURE(rc))
     621            break;
     622        pcszStage = "Setting guest IRQ filter mask";
     623        rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
     624        if (RT_FAILURE(rc))
     625            break;
     626        pcszStage = "Reporting support for seamless capability";
     627        rc = VbglR3SeamlessSetCap(true);
     628        if (RT_FAILURE(rc))
     629            break;
     630        rc = startX11MonitorThread();
     631        if (RT_FAILURE(rc))
     632            break;
     633
     634    } while(0);
     635
     636    if (RT_FAILURE(rc))
     637        VBClLogError("Failed to start in stage '%s' -- error %Rrc\n", pcszStage, rc);
     638
     639    return rc;
     640}
     641
     642/** @copydoc VBCLSERVICE::pfnWorker */
     643int VBClX11SeamlessSvc::worker(bool volatile *pfShutdown)
     644{
     645    int rc = VINF_SUCCESS;
     646
     647    /* Let the main thread know that it can continue spawning services. */
     648    RTThreadUserSignal(RTThreadSelf());
     649
     650    /* This will only exit if something goes wrong. */
     651    for (;;)
     652    {
     653        if (ASMAtomicReadBool(pfShutdown))
     654            break;
     655
     656        rc = nextStateChangeEvent();
     657
     658        if (rc == VERR_TRY_AGAIN)
     659            rc = VINF_SUCCESS;
     660
     661        if (RT_FAILURE(rc))
     662            break;
     663
     664        if (ASMAtomicReadBool(pfShutdown))
     665            break;
     666
     667        /* If we are not stopping, sleep for a bit to avoid using up too
     668           much CPU while retrying. */
     669        RTThreadYield();
     670    }
     671
     672    return rc;
     673}
     674
     675/** @copydoc VBCLSERVICE::pfnStop */
     676void VBClX11SeamlessSvc::stop(void)
     677{
     678    VbglR3SeamlessSetCap(false);
     679    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
     680    stopX11MonitorThread();
     681}
     682
     683/** @copydoc VBCLSERVICE::pfnTerm */
     684int VBClX11SeamlessSvc::term(void)
     685{
     686    mX11Monitor.uninit();
     687    return VINF_SUCCESS;
     688}
     689
     690/**
     691 * Waits for a seamless state change events from the host and dispatch it.
     692 *
     693 * @returns VBox return code, or
     694 *          VERR_TRY_AGAIN if no new status is available and we have to try it again
     695 *          at some later point in time.
     696 */
     697int VBClX11SeamlessSvc::nextStateChangeEvent(void)
     698{
     699    VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
     700
     701    int rc = VbglR3SeamlessWaitEvent(&newMode);
     702    if (RT_SUCCESS(rc))
     703    {
     704        mMode = newMode;
     705        switch (newMode)
     706        {
     707            case VMMDev_Seamless_Visible_Region:
     708                /* A simplified seamless mode, obtained by making the host VM window
     709                 * borderless and making the guest desktop transparent. */
     710                VBClLogVerbose(2, "\"Visible region\" mode requested\n");
     711                break;
     712            case VMMDev_Seamless_Disabled:
     713                VBClLogVerbose(2, "\"Disabled\" mode requested\n");
     714                break;
     715            case VMMDev_Seamless_Host_Window:
     716                /* One host window represents one guest window.  Not yet implemented. */
     717                VBClLogVerbose(2, "Unsupported \"host window\" mode requested\n");
     718                return VERR_NOT_SUPPORTED;
     719            default:
     720                VBClLogError("Unsupported mode %d requested\n", newMode);
     721                return VERR_NOT_SUPPORTED;
     722        }
     723    }
     724    if (   RT_SUCCESS(rc)
     725        || rc == VERR_TRY_AGAIN)
     726    {
     727        if (mMode == VMMDev_Seamless_Visible_Region)
     728            mfPaused = false;
     729        else
     730            mfPaused = true;
     731        mX11Monitor.interruptEventWait();
     732    }
     733    else
     734        VBClLogError("VbglR3SeamlessWaitEvent returned %Rrc\n", rc);
     735
     736    return rc;
     737}
     738
     739/**
     740 * The actual X11 window configuration change monitor thread function.
     741 */
     742int VBClX11SeamlessSvc::x11MonitorThread(RTTHREAD hThreadSelf, void *pvUser)
     743{
     744    RT_NOREF(hThreadSelf);
     745
     746    VBClX11SeamlessSvc *pThis = (VBClX11SeamlessSvc *)pvUser;
     747    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     748
     749    int rc = VINF_SUCCESS;
     750
     751    RTThreadUserSignal(hThreadSelf);
     752
     753    VBClLogVerbose(2, "X11 monitor thread started\n");
     754
     755    while (!pThis->mX11MonitorThreadStopping)
     756    {
     757        if (!pThis->mfPaused)
     758        {
     759            rc = pThis->mX11Monitor.start();
     760            if (RT_FAILURE(rc))
     761                VBClLogFatalError("Failed to change the X11 seamless service state, mfPaused=%RTbool, rc=%Rrc\n",
     762                                  pThis->mfPaused, rc);
     763        }
     764
     765        pThis->mX11Monitor.nextConfigurationEvent();
     766
     767        if (   pThis->mfPaused
     768            || pThis->mX11MonitorThreadStopping)
     769        {
     770            pThis->mX11Monitor.stop();
     771        }
     772    }
     773
     774    VBClLogVerbose(2, "X11 monitor thread ended\n");
     775
     776    return rc;
     777}
     778
     779/**
     780 * Start the X11 window configuration change monitor thread.
     781 */
     782int VBClX11SeamlessSvc::startX11MonitorThread(void)
     783{
     784    mX11MonitorThreadStopping = false;
     785
     786    if (isX11MonitorThreadRunning())
     787        return VINF_SUCCESS;
     788
     789    int rc = RTThreadCreate(&mX11MonitorThread, x11MonitorThread, this, 0,
     790                            RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
     791                            "seamless x11");
     792    if (RT_SUCCESS(rc))
     793        rc = RTThreadUserWait(mX11MonitorThread, RT_MS_30SEC);
     794
     795    if (RT_FAILURE(rc))
     796        VBClLogError("Failed to start X11 monitor thread, rc=%Rrc\n", rc);
     797
     798    return rc;
     799}
     800
     801/**
     802 * Stops the monitor thread.
     803 */
     804int VBClX11SeamlessSvc::stopX11MonitorThread(void)
     805{
     806    if (!isX11MonitorThreadRunning())
     807        return VINF_SUCCESS;
     808
     809    mX11MonitorThreadStopping = true;
     810    if (!mX11Monitor.interruptEventWait())
     811    {
     812        VBClLogError("Unable to notify X11 monitor thread\n");
     813        return VERR_INVALID_STATE;
     814    }
     815
     816    int rcThread;
     817    int rc = RTThreadWait(mX11MonitorThread, RT_MS_30SEC, &rcThread);
     818    if (RT_SUCCESS(rc))
     819        rc = rcThread;
     820
     821    if (RT_SUCCESS(rc))
     822    {
     823        mX11MonitorThread = NIL_RTTHREAD;
     824    }
     825    else
     826        VBClLogError("Waiting for X11 monitor thread to stop failed, rc=%Rrc\n", rc);
     827
     828    return rc;
     829}
     830
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h

    r98103 r99600  
    175175};
    176176
    177 class SeamlessX11
     177class VBClX11SeamlessMonitor
    178178{
    179179private:
    180180    // We don't want a copy constructor or assignment operator
    181     SeamlessX11(const SeamlessX11&);
    182     SeamlessX11& operator=(const SeamlessX11&);
     181    VBClX11SeamlessMonitor(const VBClX11SeamlessMonitor&);
     182    VBClX11SeamlessMonitor& operator=(const VBClX11SeamlessMonitor&);
    183183
    184184    // Private member variables
     
    259259    void doShapeEvent(Window hWin);
    260260
    261     SeamlessX11(void)
     261    VBClX11SeamlessMonitor(void)
    262262        : mHostCallback(NULL), mDisplay(NULL), mpRects(NULL), mcRects(0),
    263263          mSupportsShape(false), mEnabled(false), mChanged(false) {}
    264264
    265     ~SeamlessX11()
     265    ~VBClX11SeamlessMonitor()
    266266    {
    267267        uninit();
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp

    r98474 r99600  
    11/* $Id$ */
    22/** @file
    3  * X11 Guest client - seamless mode: main logic, communication with the host and
    4  * wrapper interface for the main code of the VBoxClient deamon.  The
    5  * X11-specific parts are split out into their own file for ease of testing.
     3 * Guest Additions - Common seamless mode wrapper service.
    64 */
    75
     
    5149*********************************************************************************************************************************/
    5250
    53 /**
    54  * Struct for keeping a service instance.
    55  */
    56 struct SEAMLESSSERVICE
    57 {
    58     /** Seamless service object. */
    59     SeamlessMain mSeamless;
    60 };
    61 
    62 /** Service instance data. */
    63 static SEAMLESSSERVICE g_Svc;
     51/** Pointer to the DnD interface class. */
     52static VBClSeamlessSvc *g_pSvc = NULL;
    6453
    6554
    66 SeamlessMain::SeamlessMain(void)
    67 {
    68     mX11MonitorThread         = NIL_RTTHREAD;
    69     mX11MonitorThreadStopping = false;
    70 
    71     mMode    = VMMDev_Seamless_Disabled;
    72     mfPaused = true;
    73 }
    74 
    75 SeamlessMain::~SeamlessMain()
    76 {
    77     /* Stopping will be done via main.cpp. */
    78 }
     55/*********************************************************************************************************************************
     56*   Common functions                                                                                                             *
     57*********************************************************************************************************************************/
    7958
    8059/**
    81  * Update the set of visible rectangles in the host.
     60 * Reports region updates to the host.
     61 *
     62 * @param   pRects              Pointer to array of regions to report.
     63 * @param   cRects              Number of regions in \a pRect.
    8264 */
    83 static void sendRegionUpdate(RTRECT *pRects, size_t cRects)
     65void VBClSeamnlessSendRegionUpdate(RTRECT *pRects, size_t cRects)
    8466{
    8567    if (   cRects
     
    9274}
    9375
    94 /** @copydoc VBCLSERVICE::pfnInit */
    95 int SeamlessMain::init(void)
    96 {
    97     int rc;
    98     const char *pcszStage;
    9976
    100     do
    101     {
    102         pcszStage = "Connecting to the X server";
    103         rc = mX11Monitor.init(sendRegionUpdate);
    104         if (RT_FAILURE(rc))
    105             break;
    106         pcszStage = "Setting guest IRQ filter mask";
    107         rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
    108         if (RT_FAILURE(rc))
    109             break;
    110         pcszStage = "Reporting support for seamless capability";
    111         rc = VbglR3SeamlessSetCap(true);
    112         if (RT_FAILURE(rc))
    113             break;
    114         rc = startX11MonitorThread();
    115         if (RT_FAILURE(rc))
    116             break;
    117 
    118     } while(0);
    119 
    120     if (RT_FAILURE(rc))
    121         VBClLogError("Failed to start in stage '%s' -- error %Rrc\n", pcszStage, rc);
    122 
    123     return rc;
    124 }
    125 
    126 /** @copydoc VBCLSERVICE::pfnWorker */
    127 int SeamlessMain::worker(bool volatile *pfShutdown)
    128 {
    129     int rc = VINF_SUCCESS;
    130 
    131     /* Let the main thread know that it can continue spawning services. */
    132     RTThreadUserSignal(RTThreadSelf());
    133 
    134     /* This will only exit if something goes wrong. */
    135     for (;;)
    136     {
    137         if (ASMAtomicReadBool(pfShutdown))
    138             break;
    139 
    140         rc = nextStateChangeEvent();
    141 
    142         if (rc == VERR_TRY_AGAIN)
    143             rc = VINF_SUCCESS;
    144 
    145         if (RT_FAILURE(rc))
    146             break;
    147 
    148         if (ASMAtomicReadBool(pfShutdown))
    149             break;
    150 
    151         /* If we are not stopping, sleep for a bit to avoid using up too
    152            much CPU while retrying. */
    153         RTThreadYield();
    154     }
    155 
    156     return rc;
    157 }
    158 
    159 /** @copydoc VBCLSERVICE::pfnStop */
    160 void SeamlessMain::stop(void)
    161 {
    162     VbglR3SeamlessSetCap(false);
    163     VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
    164     stopX11MonitorThread();
    165 }
    166 
    167 /** @copydoc VBCLSERVICE::pfnTerm */
    168 int SeamlessMain::term(void)
    169 {
    170     mX11Monitor.uninit();
    171     return VINF_SUCCESS;
    172 }
    173 
    174 /**
    175  * Waits for a seamless state change events from the host and dispatch it.
    176  *
    177  * @returns VBox return code, or
    178  *          VERR_TRY_AGAIN if no new status is available and we have to try it again
    179  *          at some later point in time.
    180  */
    181 int SeamlessMain::nextStateChangeEvent(void)
    182 {
    183     VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
    184 
    185     int rc = VbglR3SeamlessWaitEvent(&newMode);
    186     if (RT_SUCCESS(rc))
    187     {
    188         mMode = newMode;
    189         switch (newMode)
    190         {
    191             case VMMDev_Seamless_Visible_Region:
    192                 /* A simplified seamless mode, obtained by making the host VM window
    193                  * borderless and making the guest desktop transparent. */
    194                 VBClLogVerbose(2, "\"Visible region\" mode requested\n");
    195                 break;
    196             case VMMDev_Seamless_Disabled:
    197                 VBClLogVerbose(2, "\"Disabled\" mode requested\n");
    198                 break;
    199             case VMMDev_Seamless_Host_Window:
    200                 /* One host window represents one guest window.  Not yet implemented. */
    201                 VBClLogVerbose(2, "Unsupported \"host window\" mode requested\n");
    202                 return VERR_NOT_SUPPORTED;
    203             default:
    204                 VBClLogError("Unsupported mode %d requested\n", newMode);
    205                 return VERR_NOT_SUPPORTED;
    206         }
    207     }
    208     if (   RT_SUCCESS(rc)
    209         || rc == VERR_TRY_AGAIN)
    210     {
    211         if (mMode == VMMDev_Seamless_Visible_Region)
    212             mfPaused = false;
    213         else
    214             mfPaused = true;
    215         mX11Monitor.interruptEventWait();
    216     }
    217     else
    218         VBClLogError("VbglR3SeamlessWaitEvent returned %Rrc\n", rc);
    219 
    220     return rc;
    221 }
    222 
    223 /**
    224  * The actual X11 window configuration change monitor thread function.
    225  */
    226 int SeamlessMain::x11MonitorThread(RTTHREAD hThreadSelf, void *pvUser)
    227 {
    228     RT_NOREF(hThreadSelf);
    229 
    230     SeamlessMain *pThis = (SeamlessMain *)pvUser;
    231     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    232 
    233     int rc = VINF_SUCCESS;
    234 
    235     RTThreadUserSignal(hThreadSelf);
    236 
    237     VBClLogVerbose(2, "X11 monitor thread started\n");
    238 
    239     while (!pThis->mX11MonitorThreadStopping)
    240     {
    241         if (!pThis->mfPaused)
    242         {
    243             rc = pThis->mX11Monitor.start();
    244             if (RT_FAILURE(rc))
    245                 VBClLogFatalError("Failed to change the X11 seamless service state, mfPaused=%RTbool, rc=%Rrc\n",
    246                                   pThis->mfPaused, rc);
    247         }
    248 
    249         pThis->mX11Monitor.nextConfigurationEvent();
    250 
    251         if (   pThis->mfPaused
    252             || pThis->mX11MonitorThreadStopping)
    253         {
    254             pThis->mX11Monitor.stop();
    255         }
    256     }
    257 
    258     VBClLogVerbose(2, "X11 monitor thread ended\n");
    259 
    260     return rc;
    261 }
    262 
    263 /**
    264  * Start the X11 window configuration change monitor thread.
    265  */
    266 int SeamlessMain::startX11MonitorThread(void)
    267 {
    268     mX11MonitorThreadStopping = false;
    269 
    270     if (isX11MonitorThreadRunning())
    271         return VINF_SUCCESS;
    272 
    273     int rc = RTThreadCreate(&mX11MonitorThread, x11MonitorThread, this, 0,
    274                             RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    275                             "seamless x11");
    276     if (RT_SUCCESS(rc))
    277         rc = RTThreadUserWait(mX11MonitorThread, RT_MS_30SEC);
    278 
    279     if (RT_FAILURE(rc))
    280         VBClLogError("Failed to start X11 monitor thread, rc=%Rrc\n", rc);
    281 
    282     return rc;
    283 }
    284 
    285 /**
    286  * Stops the monitor thread.
    287  */
    288 int SeamlessMain::stopX11MonitorThread(void)
    289 {
    290     if (!isX11MonitorThreadRunning())
    291         return VINF_SUCCESS;
    292 
    293     mX11MonitorThreadStopping = true;
    294     if (!mX11Monitor.interruptEventWait())
    295     {
    296         VBClLogError("Unable to notify X11 monitor thread\n");
    297         return VERR_INVALID_STATE;
    298     }
    299 
    300     int rcThread;
    301     int rc = RTThreadWait(mX11MonitorThread, RT_MS_30SEC, &rcThread);
    302     if (RT_SUCCESS(rc))
    303         rc = rcThread;
    304 
    305     if (RT_SUCCESS(rc))
    306     {
    307         mX11MonitorThread = NIL_RTTHREAD;
    308     }
    309     else
    310         VBClLogError("Waiting for X11 monitor thread to stop failed, rc=%Rrc\n", rc);
    311 
    312     return rc;
    313 }
     77/*********************************************************************************************************************************
     78*   Service wrapper                                                                                                              *
     79*********************************************************************************************************************************/
    31480
    31581/**
     
    31884static DECLCALLBACK(int) vbclSeamlessInit(void)
    31985{
    320     return g_Svc.mSeamless.init();
     86    switch (VBClGetSessionType())
     87    {
     88        case VBGHSESSIONTYPE_X11:
     89            g_pSvc = new VBClX11SeamlessSvc();
     90            break;
     91
     92        case VBGHSESSIONTYPE_WAYLAND:
     93            RT_FALL_THROUGH();
     94        default:
     95            return VERR_NOT_SUPPORTED;
     96    }
     97
     98    if (!g_pSvc)
     99        return VERR_NO_MEMORY;
     100
     101    return g_pSvc->init();
    321102}
    322103
     
    326107static DECLCALLBACK(int) vbclSeamlessWorker(bool volatile *pfShutdown)
    327108{
    328     return g_Svc.mSeamless.worker(pfShutdown);
     109    return g_pSvc->worker(pfShutdown);
    329110}
    330111
     
    334115static DECLCALLBACK(void) vbclSeamlessStop(void)
    335116{
    336     return g_Svc.mSeamless.stop();
     117    return g_pSvc->stop();
    337118}
    338119
     
    342123static DECLCALLBACK(int) vbclSeamlessTerm(void)
    343124{
    344     return g_Svc.mSeamless.term();
     125    int rc = VINF_SUCCESS;
     126
     127    if (g_pSvc)
     128    {
     129        rc = g_pSvc->term();
     130
     131        delete g_pSvc;
     132        g_pSvc = NULL;
     133    }
     134
     135    return rc;
    345136}
    346137
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless.h

    r98103 r99600  
    3333#endif
    3434
     35#include <iprt/asm.h>
    3536#include <iprt/thread.h>
    3637
     
    4041#include "seamless-x11.h"
    4142
     43/** @name Generic seamless functions
     44 * @{ */
     45void VBClSeamnlessSendRegionUpdate(RTRECT *pRects, size_t cRects);
     46/** @} */
     47
    4248/**
    43  * Interface to the host
     49 * Interface class for seamless mode service implementation.
    4450 */
    45 class SeamlessMain
     51class VBClSeamlessSvc
    4652{
     53protected:
     54
     55    /* Note: Constructor must not throw, as we don't have exception handling on the guest side. */
     56    VBClSeamlessSvc(void) { }
     57
     58public:
     59
     60    virtual ~VBClSeamlessSvc(void) { }
     61
     62public:
     63
     64    virtual int  init(void) { return VINF_SUCCESS; }
     65    virtual int  worker(bool volatile *pfShutdown) { RT_NOREF(pfShutdown); return VINF_SUCCESS; }
     66    virtual void reset(void) { }
     67    virtual void stop(void) { }
     68    virtual int  term(void) { return VINF_SUCCESS; }
     69
     70#ifdef IN_GUEST
     71    RTMEM_IMPLEMENT_NEW_AND_DELETE();
     72#endif
     73};
     74
     75/**
     76 * Service class which implements seamless mode for X11.
     77 */
     78class VBClX11SeamlessSvc : public VBClSeamlessSvc
     79{
     80public:
     81    VBClX11SeamlessSvc(void);
     82
     83    virtual ~VBClX11SeamlessSvc();
     84
     85public:
     86
     87    /** @copydoc VBCLSERVICE::pfnInit */
     88    virtual int init(void);
     89
     90    /** @copydoc VBCLSERVICE::pfnWorker */
     91    virtual int worker(bool volatile *pfShutdown);
     92
     93    /** @copydoc VBCLSERVICE::pfnStop */
     94    virtual void stop(void);
     95
     96    /** @copydoc VBCLSERVICE::pfnTerm */
     97    virtual int term(void);
     98
    4799private:
    48     // We don't want a copy constructor or assignment operator
    49     SeamlessMain(const SeamlessMain&);
    50     SeamlessMain& operator=(const SeamlessMain&);
     100    /** Note: We don't want a copy constructor or assignment operator. */
     101    VBClX11SeamlessSvc(const VBClX11SeamlessSvc&);
     102    VBClX11SeamlessSvc& operator=(const VBClX11SeamlessSvc&);
    51103
    52     /** X11 event monitor object */
    53     SeamlessX11 mX11Monitor;
     104    /** X11 event monitor object. */
     105    VBClX11SeamlessMonitor mX11Monitor;
    54106
    55107    /** Thread to start and stop when we enter and leave seamless mode which
     
    86138        return mX11MonitorThread != NIL_RTTHREAD;
    87139    }
    88 
    89 public:
    90     SeamlessMain(void);
    91     virtual ~SeamlessMain();
    92 #ifdef RT_NEED_NEW_AND_DELETE
    93     RTMEM_IMPLEMENT_NEW_AND_DELETE();
    94 #endif
    95 
    96     /** @copydoc VBCLSERVICE::pfnInit */
    97     int init(void);
    98 
    99     /** @copydoc VBCLSERVICE::pfnWorker */
    100     int worker(bool volatile *pfShutdown);
    101 
    102     /** @copydoc VBCLSERVICE::pfnStop */
    103     void stop(void);
    104 
    105     /** @copydoc VBCLSERVICE::pfnTerm */
    106     int term(void);
    107140};
    108141
  • trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp

    r98103 r99600  
    676676static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
    677677{
    678     SeamlessX11 subject;
     678    VBClX11SeamlessMonitor subject;
    679679    unsigned cErrs = 0;
    680680
  • trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp

    r98103 r99600  
    3333#include <iprt/string.h>
    3434#include <iprt/stream.h>
     35
    3536#include <VBox/VBoxGuestLib.h>
     37#include <VBox/GuestHost/SessionType.h>
    3638
    3739#include "../seamless.h"
    3840
    3941static RTSEMEVENT eventSem;
     42
     43VBGHSESSIONTYPE VBClGetSessionType(void)
     44{
     45    return VBGHSESSIONTYPE_X11;
     46}
    4047
    4148void VBClLogError(const char *pszFormat, ...)
     
    169176    RTSemEventCreate(&eventSem);
    170177    /** Our instance of the seamless class. */
    171     SeamlessMain seamless;
     178    VBClX11SeamlessSvc seamless;
    172179    LogRel(("Starting seamless Guest Additions...\n"));
    173180    rc = seamless.init();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette