VirtualBox

Changeset 6290 in vbox


Ignore:
Timestamp:
Jan 9, 2008 10:49:16 AM (17 years ago)
Author:
vboxsync
Message:

Guest Additions: update for the Linux seamless additions

Location:
trunk/src
Files:
1 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp

    r6000 r6290  
    5454#ifdef DEBUG
    5555    if (RT_SUCCESS(rc))
    56         LogRel(("Successfully enabled seamless mode on the host.\n"));
     56        LogRel(("Successfully set the seamless capability on the host.\n"));
    5757    else
    58         LogRel(("Failed to enabled seamless mode on the host, rc = %Rrc.\n", rc));
     58        LogRel(("Failed to set the seamless capability on the host, rc = %Rrc.\n", rc));
    5959#endif
    6060    return rc;
     
    116116    int rc;
    117117
     118    if (0 == cRects)
     119        return VINF_SUCCESS;
    118120    rc = VbglR3GRAlloc((VMMDevRequestHeader **)&req,
    119121                       sizeof(VMMDevVideoSetVisibleRegion) + (cRects - 1) * sizeof(RTRECT),
  • trunk/src/VBox/Additions/x11/xclient/Makefile.kmk

    r6233 r6290  
    2020
    2121ifneq ($(USERNAME),bird) # crap
    22 PROGRAMS = vboxadd-xclient
     22 PROGRAMS = vboxadd-xclient
    2323endif
    2424
     
    2727vboxadd-xclient_TEMPLATE = VBOXLNX32GUESTR3EXE
    2828vboxadd-xclient_SOURCES  = clipboard.cpp main.cpp
     29vboxadd-xclient_DEFS    += CLIPBOARD_LINUX
     30
    2931ifdef LINUX_SEAMLESS_GUEST
    30 vboxadd-xclient_SOURCES += \
    31                 seamless-host.cpp \
    32                 seamless-x11.cpp \
    33                 thread.cpp
     32 vboxadd-xclient_SOURCES += \
     33                 seamless-host.cpp \
     34                 seamless-x11.cpp \
     35                 thread.cpp
    3436endif
    3537vboxadd-xclient_LIBPATH  = $(PATH_TARGET)/vboxadd-xclient $(VBOX_LIBPATH32_X11)
     38# Ugly recursive dependency between the runtime and the guest library.  Sorry.
    3639vboxadd-xclient_LIBS     = \
    3740                $(PATH_LIB)/RuntimeLnx32GuestR3.a \
    3841                $(PATH_LIB)/VBoxGuestR3LibLinux.a \
     42                $(PATH_LIB)/RuntimeLnx32GuestR3.a \
    3943                pthread \
    4044                rt \
     
    4246                Xext \
    4347                X11
    44 vboxadd-xclient_DEFS     = _GNU_SOURCE VBOX_HGCM
     48vboxadd-xclient_DEFS    += _GNU_SOURCE VBOX_HGCM
     49
    4550ifdef LINUX_SEAMLESS_GUEST
    46 vboxadd-xclient_DEFS     += LINUX_SEAMLESS
     51 vboxadd-xclient_DEFS     += SEAMLESS_LINUX
    4752endif
    4853
     
    5560
    5661ifdef LINUX_SEAMLESS_GUEST
    57 ifdef VBOX_WITH_CPPUNIT_TESTCASES
    58  PROGRAMS                  += tstSeamlessX11
    59  tstSeamlessX11_TEMPLATE    = VBOXCPPUNITEXE
    60  tstSeamlessX11_SOURCES     = \
    61          testcase/tstSeamlessX11.cpp \
    62          seamless-x11.cpp
    63  tstSeamlessX11_INST        = $(INST_TESTCASE)
    64 endif
     62 ifdef VBOX_WITH_TESTCASES
     63 # Additional testcase designed to be run manually, which initiates and starts the Linux
     64 # guest client part of the seamless additions in the host, faking seamless events from
     65 # the host and writing information about guest events to standard output.
     66  PROGRAMS                  += tstSeamlessX11
     67  tstSeamlessX11_TEMPLATE  = VBOXR3EXE
     68  tstSeamlessX11_SOURCES   = \
     69          testcase/tstSeamlessX11.cpp \
     70          seamless-host.cpp \
     71          seamless-x11.cpp \
     72          thread.cpp
     73  tstSeamlessX11_LIBS      = \
     74          $(LIB_RUNTIME) \
     75          Xext \
     76          X11
     77  tstSeamlessX11_INST      = $(INST_TESTCASE)
     78 endif
    6579endif
    6680
  • trunk/src/VBox/Additions/x11/xclient/main.cpp

    r6202 r6290  
    1717 */
    1818
    19 #define LOG_GROUP LOG_GROUP_DEV_VMM_BACKDOOR
     19// #define LOG_GROUP LOG_GROUP_DEV_VMM_BACKDOOR
    2020
    2121#include <VBox/VBoxGuest.h>
     
    2424
    2525#include <iostream>
    26 
    27 using std::cout;
    28 using std::endl;
    2926
    3027#include <sys/types.h>
     
    9491
    9592/**
    96  * Xlib error handler, so that we don't abort when we get a BadAtom error.
    97  */
    98 int vboxClipboardXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
     93 * Xlib error handler for certain errors that we can't avoid.
     94 */
     95int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
    9996{
    10097    char errorText[1024];
    10198
    102     LogFlowFunc(("\n"));
    10399    if (pError->error_code == BadAtom)
    104100    {
    105101        /* This can be triggered in debug builds if a guest application passes a bad atom
    106102           in its list of supported clipboard formats.  As such it is harmless. */
    107         LogFlowFunc(("ignoring BadAtom error and returning\n"));
     103        Log(("VBoxService: ignoring BadAtom error and returning\n"));
    108104        return 0;
    109105    }
     106    if (pError->error_code == BadWindow)
     107    {
     108        /* This can be triggered if a guest application destroys a window before we notice. */
     109        Log(("VBoxService: ignoring BadWindow error and returning\n"));
     110        return 0;
     111    }
     112#ifdef CLIPBOARD_LINUX
    110113    vboxClipboardDisconnect();
     114#endif
    111115    XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText));
    112     if (!gbDaemonise)
    113     {
    114         cout << "An X Window protocol error occurred: " << errorText << endl
    115             << "  Request code: " << int(pError->request_code) << endl
    116             << "  Minor code: " << int(pError->minor_code) << endl
    117             << "  Serial number of the failed request: " << int(pError->serial) << endl;
    118     }
    119     Log(("%s: an X Window protocol error occurred: %s.  Request code: %d, minor code: %d, serial number: %d\n",
    120          __PRETTY_FUNCTION__, pError->error_code, pError->request_code, pError->minor_code,
    121          pError->serial));
    122     LogFlowFunc(("exiting\n"));
     116    LogRel(("VBoxService: an X Window protocol error occurred: %s.  Request code: %d, minor code: %d, serial number: %d\n",
     117         pError->error_code, pError->request_code, pError->minor_code, pError->serial));
    123118    exit(1);
    124119}
     
    145140            if (optind < argc)
    146141            {
    147                 cout << "Unrecognized command line argument: " << argv[argc] << endl;
     142                std::cout << "Unrecognized command line argument: " << argv[argc] << std::endl;
    148143                exit(1);
    149144            }
     
    156151            break;
    157152        default:
    158             cout << "Unrecognized command line option: " << static_cast<char>(cOpt) << endl;
     153            std::cout << "Unrecognized command line option: " << static_cast<char>(cOpt)
     154                      << std::endl;
    159155        case '?':
    160156            exit(1);
     
    167163    /* Initialise our runtime before all else. */
    168164    RTR3Init(false);
    169     LogFlowFunc(("\n"));
     165    rc = VbglR3Init();
     166    if (RT_FAILURE(rc))
     167    {
     168        std::cout << "Failed to connect to the VirtualBox kernel service" << std::endl;
     169        return 1;
     170    }
     171    LogRel(("VBoxService: starting...\n"));
    170172    /* Initialise threading in X11 and in Xt. */
    171173    if (!XInitThreads() || !XtToolkitThreadInitialize())
    172174    {
    173         LogRelFunc(("Error initialising threads in X11, returning 1."));
    174         cout << "Your guest system appears to be using an old, single-threaded version of the X Window System libraries.  This program cannot continue." << endl;
     175        LogRel(("VBoxService: error initialising threads in X11, exiting."));
    175176        return 1;
    176177    }
    177     /* Set an X11 error handler, so that we don't die when we get BadAtom errors. */
    178     XSetErrorHandler(vboxClipboardXLibErrorHandler);
     178    /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
     179    XSetErrorHandler(vboxClientXLibErrorHandler);
     180#ifdef CLIPBOARD_LINUX
    179181    /* Connect to the host clipboard. */
    180     LogRel(("Starting clipboard Guest Additions...\n"));
     182    LogRel(("VBoxService: starting clipboard Guest Additions...\n"));
    181183    rc = vboxClipboardConnect();
    182     if (rc != VINF_SUCCESS)
    183     {
    184         LogRel(("vboxClipboardConnect failed with rc = %d\n", rc));
    185         cout << "Failed to connect to the host clipboard." << endl;
    186     }
     184    if (RT_SUCCESS(rc))
     185    {
     186        LogRel(("VBoxService: vboxClipboardConnect failed with rc = %Rrc\n", rc));
     187    }
     188#endif  /* CLIPBOARD_LINUX defined */
    187189#ifdef SEAMLESS_LINUX
    188190    try
    189191    {
    190         LogRel(("Starting seamless Guest Additions...\n"));
     192        LogRel(("VBoxService: starting seamless Guest Additions...\n"));
    191193        rc = seamless.init();
    192         if (rc != VINF_SUCCESS)
    193         {
    194             LogRel(("Failed to initialise seamless Additions, rc = %d\n", rc));
    195             cout << "Failed to initialise seamless Additions." << endl;
     194        if (RT_FAILURE(rc))
     195        {
     196            LogRel(("VBoxService: failed to initialise seamless Additions, rc = %Rrc\n", rc));
    196197        }
    197198    }
    198199    catch (std::exception e)
    199200    {
    200         LogRel(("Failed to initialise seamless Additions - caught exception: %s\n", e.what()));
    201         cout << "Failed to initialise seamless Additions\n" << endl;
     201        LogRel(("VBoxService: failed to initialise seamless Additions - caught exception: %s\n", e.what()));
    202202        rc = VERR_UNRESOLVED_ERROR;
    203203    }
    204204    catch (...)
    205205    {
    206         LogRel(("Failed to initialise seamless Additions - caught unknown exception.\n"));
    207         cout << "Failed to initialise seamless Additions\n" << endl;
     206        LogRel(("VBoxService: failed to initialise seamless Additions - caught unknown exception.\n"));
    208207        rc = VERR_UNRESOLVED_ERROR;
    209208    }
    210209#endif /* SEAMLESS_LINUX defined */
     210#ifdef CLIPBOARD_LINUX
     211    LogRel(("VBoxService: connecting to the shared clipboard service.\n"));
    211212    vboxClipboardMain();
    212213    vboxClipboardDisconnect();
     214#else  /* CLIPBOARD_LINUX not defined */
     215    LogRel(("VBoxService: sleeping...\n"));
     216    pause();
     217    LogRel(("VBoxService: exiting...\n"));
     218#endif  /* CLIPBOARD_LINUX not defined */
    213219#ifdef SEAMLESS_LINUX
    214220    try
     
    218224    catch (std::exception e)
    219225    {
    220         LogRel(("Error shutting down seamless Additions - caught exception: %s\n", e.what()));
     226        LogRel(("VBoxService: error shutting down seamless Additions - caught exception: %s\n", e.what()));
    221227        rc = VERR_UNRESOLVED_ERROR;
    222228    }
    223229    catch (...)
    224230    {
    225         LogRel(("Error shutting down seamless Additions - caught unknown exception.\n"));
     231        LogRel(("VBoxService: error shutting down seamless Additions - caught unknown exception.\n"));
    226232        rc = VERR_UNRESOLVED_ERROR;
    227233    }
    228234#endif /* SEAMLESS_LINUX defined */
    229     LogFlowFunc(("returning %Vrc\n", rc));
    230235    return rc;
    231236}
  • trunk/src/VBox/Additions/x11/xclient/seamless-glue.h

    r6202 r6290  
    2020# define __Additions_client_seamless_glue_h
    2121
    22 #if 0
    23 
    24 #include "seamless-host.h"
    25 #include "seamless-guest.h"
    26 
    27 #endif
    28 
    2922class VBoxGuestSeamlessObserver
    3023{
     
    3427};
    3528
    36 #if 0
    37 /**
    38  * Observer to connect the guest and the host parts of the seamless guest client.
    39  * It starts the host part when the guest reports that it supports seamless mode and
    40  * stops it when the guest no longer supports seamless.  It also proxies enter and
    41  * exit seamless mode requests from the host part to the guest and informs the host
    42  * part when the guest's visible area changes.
    43  */
    44 class VBoxGuestSeamlessGlue
    45 {
    46 private:
    47     VBoxGuestSeamlessHost *mHost;
    48     VBoxGuestSeamlessGuestImpl *mGuest;
    49 
    50 public:
    51     VBoxGuestSeamlessGlue(VBoxGuestSeamlessHost *pHost, VBoxGuestSeamlessGuestImpl *pGuest)
    52             : mHost(pHost), mGuest(pGuest) {}
    53     ~VBoxGuestSeamlessGlue();
    54 
    55     /** State change notification callback for the guest. */
    56     void guestNotify(VBoxGuestSeamlessGuest::meEvent event)
    57     {
    58         switch(event)
    59         {
    60             case VBoxGuestSeamlessGuest::CAPABLE:
    61                 mHost->start();
    62                 break;
    63             case VBoxGuestSeamlessGuest::INCAPABLE:
    64                 mHost->stop();
    65                 break;
    66             case VBoxGuestSeamlessGuest::UPDATE:
    67                 mHost->updateRects(mGuest->getRects());
    68                 break;
    69             default:
    70                 break;
    71         }
    72     }
    73 
    74     /** State change notification callback for the host. */
    75     void hostNotify(VBoxGuestSeamlessHost::meEvent event)
    76     {
    77         switch(event)
    78         {
    79             case VBoxGuestSeamlessHost::ENABLE:
    80                 mGuest->start();
    81                 break;
    82             case VBoxGuestSeamlessHost::DISABLE:
    83                 mGuest->stop();
    84                 break;
    85             default:
    86                 break;
    87         }
    88     }
    89 };
    90 #endif /* 0 */
    91 
    9229#endif /* __Additions_client_seamless_glue_h not defined */
  • trunk/src/VBox/Additions/x11/xclient/seamless-guest.h

    r6202 r6290  
    7373    /** Get the current list of visible rectangles. */
    7474    std::auto_ptr<std::vector<RTRECT> > getRects(void);
     75    /** Process next event in the guest event queue - called by the event thread. */
     76    void nextEvent(void);
     77    /** Wake up the event thread if it is waiting for an event so that it can exit. */
     78    bool interruptEvent(void);
    7579};
    7680
  • trunk/src/VBox/Additions/x11/xclient/seamless-host.cpp

    r6202 r6290  
    2626#include "seamless-host.h"
    2727
    28 #ifdef DEBUG
    29 # include <stdio.h>
    30 # define DPRINT(a) printf a
    31 #else
    32 # define DPRINT(a)
    33 #endif
    34 
    3528/**
    3629 * Start the service.
     
    4336    if (mRunning)  /* Assertion */
    4437    {
    45         LogRelThisFunc(("Service started twice!\n"));
    46         DPRINT(("Service started twice!\n"));
     38        LogRel(("VBoxService: seamless service started twice!\n"));
    4739        return VERR_INTERNAL_ERROR;
    4840    }
    49     if (VbglR3SeamlessSetCap(true))
     41    rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
     42    if (RT_FAILURE(rc))
    5043    {
    51         DPRINT(("Enabled host seamless.\n"));
     44        LogRel(("VBoxService (seamless): failed to set the guest IRQ filter mask, rc=%Rrc\n", rc));
     45    }
     46    rc = VbglR3SeamlessSetCap(true);
     47    if (RT_SUCCESS(rc))
     48    {
     49        Log(("VBoxService: enabled seamless capability on host.\n"));
    5250        rc = mThread.start();
    5351        if (RT_SUCCESS(rc))
     
    5755        else
    5856        {
    59             DPRINT(("Disabled host seamless again.\n"));
     57            LogRel(("VBoxService: failed to start seamless event thread, rc=%Rrc.  Disabled seamless capability on host again.\n", rc));
    6058            VbglR3SeamlessSetCap(false);
    6159        }
     
    6361    if (RT_FAILURE(rc))
    6462    {
    65         DPRINT(("Failed to enable host seamless, rc=%d\n", rc));
     63        Log(("VBoxService (seamless): failed to enable seamless capability on host, rc=%Rrc\n", rc));
    6664    }
    6765    return rc;
     
    7371    if (!mRunning)  /* Assertion */
    7472    {
    75         LogRelThisFunc(("Service not running!\n"));
     73        LogRel(("VBoxService: tried to stop seamless service which is not running!\n"));
    7674        return;
    7775    }
    7876    mThread.stop(0, 0);
     77    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
    7978    VbglR3SeamlessSetCap(false);
    8079    mRunning = false;
     
    8887int VBoxGuestSeamlessHost::nextEvent(void)
    8988{
    90     VMMDevSeamlessMode newMode;
     89    VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
    9190
    9291    int rc = VbglR3SeamlessWaitEvent(&newMode);
    93     switch(newMode)
     92    if (RT_SUCCESS(rc))
    9493    {
    95         case VMMDev_Seamless_Visible_Region:
    96         /* A simplified seamless mode, obtained by making the host VM window borderless and
    97           making the guest desktop transparent. */
    98             mState = ENABLE;
    99             mObserver->notify();
    100             break;
    101         case VMMDev_Seamless_Host_Window:
    102         /* One host window represents one guest window.  Not yet implemented. */
    103             LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received.\n"));
    104             /* fall through to default */
    105         default:
    106             LogRelFunc(("Warning: unsupported VMMDev_Seamless request received.\n"));
    107             /* fall through to case VMMDev_Seamless_Disabled */
    108         case VMMDev_Seamless_Disabled:
    109             mState = DISABLE;
    110             mObserver->notify();
     94        switch(newMode)
     95        {
     96            case VMMDev_Seamless_Visible_Region:
     97            /* A simplified seamless mode, obtained by making the host VM window borderless and
     98              making the guest desktop transparent. */
     99    #ifdef DEBUG
     100                LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxService).\n"));
     101    #endif
     102                mState = ENABLE;
     103                mObserver->notify();
     104                break;
     105            case VMMDev_Seamless_Host_Window:
     106            /* One host window represents one guest window.  Not yet implemented. */
     107                LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received (VBoxService).\n"));
     108                /* fall through to default */
     109            default:
     110                LogRelFunc(("Warning: unsupported VMMDev_Seamless request %d received (VBoxService).\n", newMode));
     111                /* fall through to case VMMDev_Seamless_Disabled */
     112            case VMMDev_Seamless_Disabled:
     113    #ifdef DEBUG
     114                LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxService).\n"));
     115    #endif
     116                mState = DISABLE;
     117                mObserver->notify();
     118        }
     119    }
     120    else
     121    {
     122        LogFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxService)\n", rc));
    111123    }
    112124    return rc;
  • trunk/src/VBox/Additions/x11/xclient/seamless-host.h

    r6202 r6290  
    123123        if (mObserver != 0)  /* Assertion */
    124124        {
    125             LogRelThisFunc(("ERROR: attempt to initialise service twice!\n"));
     125            LogRel(("VBoxService: ERROR: attempt to initialise seamless host object twice!\n"));
    126126            return VERR_INTERNAL_ERROR;
    127127        }
     
    149149    VBoxGuestSeamlessHost(void) : mThreadFunction(this),
    150150                                  mThread(&mThreadFunction, 0, RTTHREADTYPE_MAIN_WORKER,
    151                                   RTTHREADFLAGS_WAITABLE, "Seamless host event thead")
     151                                  RTTHREADFLAGS_WAITABLE, "Host events")
    152152    {
    153153        mObserver = 0;
     
    160160        if (mRunning)  /* Assertion */
    161161        {
    162             LogRelThisFunc(("Service still running!  Stopping...\n"));
     162            LogRel(("VBoxService: seamless host object still running!  Stopping...\n"));
    163163            stop();
    164164        }
  • trunk/src/VBox/Additions/x11/xclient/seamless-x11.cpp

    r6202 r6290  
    6767{
    6868    int rc = VINF_SUCCESS;
    69     /** Dummy values for XShapeQueryExtension */
    70     int error, event;
     69    /** Dummy value for XXGetProperty */
     70    unsigned long nItems;
    7171
    7272    if (0 != mObserver)  /* Assertion */
    7373    {
    74         LogRelThisFunc(("ERROR: attempt to initialise service twice!\n"));
     74        LogRel(("VBoxService: ERROR: attempt to initialise seamless guest object twice!\n"));
    7575        return VERR_INTERNAL_ERROR;
    7676    }
    77     if (!mDisplay.isValid())
    78     {
    79         LogRelThisFunc(("Failed to acquire a connection to the display.\n"));
     77    if (!mDisplay.init())
     78    {
     79        LogRel(("VBoxService: seamless guest object failed to acquire a connection to the display.\n"));
    8080        return VERR_ACCESS_DENIED;
    8181    }
    82     if (!XShapeQueryExtension(mDisplay, &event, &error))
    83     {
    84         LogFlowFunc(("X11 shape extension not supported, returning.\n"));
    85         return VERR_NOT_SUPPORTED;
     82    if (0 == XXGetProperty(mDisplay, DefaultRootWindow(mDisplay.get()), XA_WINDOW,
     83                           NET_CLIENT_LIST, &nItems).get())
     84    {
     85        LogRel(("VBoxService: _NET_CLIENT_LIST property not supported by guest window manager.  Seamless mode will not be enabled.\n"));
    8686    }
    8787    mObserver = pObserver;
     
    100100{
    101101    int rc = VINF_SUCCESS;
    102 
    103     isEnabled = true;
    104     monitorDesktopWindows();
     102    /** Dummy values for XShapeQueryExtension */
     103    int error, event;
     104
     105    mSupportsShape = XShapeQueryExtension(mDisplay, &event, &error);
     106    mEnabled = true;
     107    monitorClientList();
     108    rebuildWindowTree();
    105109    return rc;
    106110}
     
    110114void VBoxGuestSeamlessX11::stop(void)
    111115{
    112     isEnabled = false;
     116    mEnabled = false;
     117    unmonitorClientList();
    113118    freeWindowTree();
    114119}
    115120
    116 void VBoxGuestSeamlessX11::monitorDesktopWindows(void)
    117 {
    118     VBoxGuestX11Pointer<unsigned char> virtualRoots;
     121void VBoxGuestSeamlessX11::monitorClientList(void)
     122{
     123    XSelectInput(mDisplay, DefaultRootWindow(mDisplay.get()), PropertyChangeMask);
     124}
     125
     126void VBoxGuestSeamlessX11::unmonitorClientList(void)
     127{
     128    XSelectInput(mDisplay, DefaultRootWindow(mDisplay.get()), 0);
     129}
     130
     131void VBoxGuestSeamlessX11::rebuildWindowTree(void)
     132{
     133    VBoxGuestX11Pointer<unsigned char> clientListRaw;
     134    VBoxGuestX11Pointer<Window> clientList;
    119135    unsigned long nItems;
    120136
    121     XSelectInput(mDisplay, DefaultRootWindow(mDisplay.get()), PropertyChangeMask);
    122     virtualRoots = XXGetProperty(mDisplay, DefaultRootWindow(mDisplay.get()), XA_CARDINAL,
    123                                  VIRTUAL_ROOTS_PROP, &nItems);
    124     if ((0 != virtualRoots.get()) && (0 != nItems))
    125     {
    126         rebuildWindowTree();
    127     }
    128 }
    129 
    130 void VBoxGuestSeamlessX11::rebuildWindowTree(void)
    131 {
    132     VBoxGuestX11Pointer<unsigned char> virtualRoots;
    133     Window *desktopWindows;
    134     unsigned long nItems;
    135 
    136137    freeWindowTree();
    137     virtualRoots = XXGetProperty(mDisplay, DefaultRootWindow(mDisplay.get()), XA_CARDINAL,
    138                                  VIRTUAL_ROOTS_PROP, &nItems);
    139     desktopWindows = reinterpret_cast<Window *>(virtualRoots.get());
     138    clientListRaw = XXGetProperty(mDisplay, DefaultRootWindow(mDisplay.get()), XA_WINDOW,
     139                                  NET_CLIENT_LIST, &nItems);
     140    clientList = reinterpret_cast<Window *>(clientListRaw.release());
    140141    for (unsigned i = 0; i < nItems; ++i)
    141142    {
    142         addDesktopWindow(desktopWindows[i]);
    143     }
    144     /* This must be done last, so that we do not treat the desktop windows just added as
    145        child windows. */
    146     addDesktopWindow(DefaultRootWindow(mDisplay.get()));
    147 }
    148 
    149 /**
    150  * Store information about a desktop window and register for structure events on it.
    151  * If it is mapped, go through the list of it's children and add information about
    152  * mapped children to the tree of visible windows, making sure that those windows are
    153  * not already in our list of desktop windows.
    154  *
    155  * @param   hWin     the window concerned - should be a "desktop" window
    156  */
    157 void VBoxGuestSeamlessX11::addDesktopWindow(Window hWin)
    158 {
    159     unsigned int cChildren = 0;
    160     VBoxGuestX11Pointer<Window> children;
    161     XWindowAttributes winAttrib;
    162     /** Dummies */
    163     Window root, parent, *pChildren;
    164 
    165     if (!XGetWindowAttributes(mDisplay, hWin, &winAttrib))
    166     {
    167         LogRelFunc(("Failed to get the window attributes for window %d\n", hWin));
    168         return;
    169     }
    170     mDesktopWindows.push_back(VBoxGuestDesktopInfo(hWin, winAttrib.x, winAttrib.y,
    171                               (IsUnmapped != winAttrib.map_state)));
    172     XSelectInput(mDisplay, hWin,
    173                  StructureNotifyMask | SubstructureNotifyMask | PropertyChangeMask);
    174     XQueryTree(mDisplay, hWin, &root, &parent, &pChildren, &cChildren);
    175     children = pChildren;
    176     if (0 == children.get())
    177     {
    178         LogRelFunc(("Failed to get the tree of active X11 windows.\n"));
    179     }
    180     else
    181     {
    182         for (unsigned int i = 0; i < cChildren; ++i)
     143        VBoxGuestX11Pointer<unsigned char> windowTypeRaw;
     144        VBoxGuestX11Pointer<Atom> windowType;
     145        unsigned long ulCount;
     146
     147        windowTypeRaw = XXGetProperty(mDisplay, clientList.get()[i], XA_ATOM,
     148                                      WM_TYPE_PROP, &ulCount);
     149        windowType = reinterpret_cast<Atom *>(windowTypeRaw.release());
     150        if (   (ulCount != 0)
     151            && (*windowType != XInternAtom(mDisplay, WM_TYPE_DESKTOP_PROP, True)))
    183152        {
    184             bool found = false;
    185 
    186             for (unsigned int j = 0; j < mDesktopWindows.size() && !found; ++j)
    187             {
    188                 if (children.get()[i] == mDesktopWindows[j].mWin)
    189                 {
    190                     found = true;
    191                 }
    192             }
    193             if (!found)
    194             {
    195                 addWindowToList(children.get()[i], hWin);
    196             }
     153            addClientWindow(clientList.get()[i]);
    197154        }
    198155    }
    199156}
    200157
    201 void VBoxGuestSeamlessX11::addWindowToList(const Window hWin, const Window hParent)
     158void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
    202159{
    203160    XWindowAttributes winAttrib;
    204161    VBoxGuestX11Pointer<XRectangle> rects;
    205     int cRects, iOrdering;
    206     unsigned iParent;
    207     bool isVisible = false, found = false;
     162    int cRects = 0, iOrdering;
     163    int x, y;
     164    /** Dummy value for XTranslateCoordinates */
     165    Window dummyWin;
    208166
    209167    if (!XGetWindowAttributes(mDisplay, hWin, &winAttrib))
    210168    {
    211         LogRelFunc(("Failed to get the window attributes for window %d\n", hWin));
     169        LogRelFunc(("VBoxService: Failed to get the window attributes for window %d\n", hWin));
    212170        return;
    213171    }
    214     XShapeSelectInput(mDisplay, hWin, ShapeNotify);
    215     rects = XShapeGetRectangles(mDisplay, hWin, ShapeClip, &cRects, &iOrdering);
    216     if (0 == rects.get())
    217     {
    218         cRects = 0;
    219     }
    220     if (IsViewable == winAttrib.map_state)
    221     {
    222         isVisible = true;
    223     }
    224     for (iParent = 0; iParent < mDesktopWindows.size() && !found; ++iParent)
    225     {
    226         if (hParent == mDesktopWindows[iParent].mWin)
     172    if (mSupportsShape)
     173    {
     174        XShapeSelectInput(mDisplay, hWin, ShapeNotify);
     175        rects = XShapeGetRectangles(mDisplay, hWin, ShapeClip, &cRects, &iOrdering);
     176        if (0 == rects.get())
    227177        {
    228             found = true;
     178            cRects = 0;
    229179        }
    230180    }
    231     if (found)
    232     {
    233         mGuestWindows.addWindow(hWin, isVisible, winAttrib.x, winAttrib.y,
    234                                 winAttrib.width, winAttrib.height, cRects, rects, hParent);
    235     }
     181    XSelectInput(mDisplay, hWin, StructureNotifyMask);
     182    XTranslateCoordinates(mDisplay, hWin, DefaultRootWindow(mDisplay.get()), winAttrib.x,
     183                          winAttrib.y, &x, &y, &dummyWin);
     184    mGuestWindows.addWindow(hWin, winAttrib.map_state != IsUnmapped, x, y,
     185                            winAttrib.width, winAttrib.height, cRects, rects);
    236186}
    237187
     
    241191void VBoxGuestSeamlessX11::freeWindowTree(void)
    242192{
    243     for (unsigned int i = 0; i != mDesktopWindows.size(); ++i)
    244     {
    245         XSelectInput(mDisplay, mDesktopWindows[i].mWin, 0);
    246     }
    247     mDesktopWindows.clear();
    248193    /* We use post-increment in the operation to prevent the iterator from being invalidated. */
    249194    for (VBoxGuestWindowList::iterator it = mGuestWindows.begin(); it != mGuestWindows.end();
    250195                 mGuestWindows.removeWindow(it++))
    251196    {
     197        XSelectInput(mDisplay, it->first, 0);
    252198        XShapeSelectInput(mDisplay, it->first, 0);
    253199    }
     
    290236
    291237/**
    292  * Handle a configuration event in the seamless event thread by setting the new position and
    293  * updating the host's rectangle information.
     238 * Handle a configuration event in the seamless event thread by setting the new position.
    294239 *
    295240 * @param event the X11 event structure
     
    297242void VBoxGuestSeamlessX11::doConfigureEvent(const XConfigureEvent *event)
    298243{
    299     bool found = false;
    300     unsigned i = 0;
    301 
    302     for (i = 0; i < mDesktopWindows.size() && !found; ++i)
    303     {
    304         if (event->window == mDesktopWindows[i].mWin)
    305         {
    306             found = true;
    307         }
    308     }
    309     if (found)
    310     {
    311         mDesktopWindows[i].mx = event->x;
    312         mDesktopWindows[i].my = event->y;
    313     }
    314     else
    315     {
    316         VBoxGuestWindowList::iterator iter;
    317 
    318         iter = mGuestWindows.find(event->window);
    319         if (iter != mGuestWindows.end())
    320         {
    321             iter->second->mx = event->x;
    322             iter->second->my = event->y;
    323         }
    324     }
    325 }
    326 
    327 /**
    328  * Handle a map event in the seamless event thread by adding the guest window to the list of
    329  * visible windows and updating the host's rectangle information.
     244    VBoxGuestWindowList::iterator iter;
     245
     246    iter = mGuestWindows.find(event->window);
     247    if (iter != mGuestWindows.end())
     248    {
     249        iter->second->mX = event->x;
     250        iter->second->mY = event->y;
     251        iter->second->mWidth = event->width;
     252        iter->second->mHeight = event->height;
     253    }
     254}
     255
     256/**
     257 * Handle a map event in the seamless event thread.
    330258 *
    331259 * @param event the X11 event structure
     
    334262{
    335263    VBoxGuestWindowList::iterator iter;
    336     bool found = false;
    337 
    338     /* Is one of our desktop windows? */
    339     for (unsigned i = 0; i < mDesktopWindows.size() && !found; ++i)
    340     {
    341         if (event->window == mDesktopWindows[i].mWin)
    342         {
    343             mDesktopWindows[i].mMapped = true;
    344             found = true;
    345         }
    346     }
    347     if (!found)
    348     {
    349         /* Make sure that the window is not already present in the tree */
    350         iter = mGuestWindows.find(event->window);
    351         if (iter != mGuestWindows.end())
    352         {
    353             LogRelFunc(("Warning: MapNotify event received for a window listed as mapped\n"));
    354             mGuestWindows.removeWindow(event->window);
    355         }
    356         addWindowToList(event->window, event->event);
    357     }
    358 }
    359 
    360 /**
    361  * If the list of virtual root windows changes, completely rescan visible windows.
     264
     265    iter = mGuestWindows.find(event->window);
     266    if (iter != mGuestWindows.end())
     267    {
     268        iter->second->mMapped = true;
     269    }
     270}
     271
     272/**
     273 * If the list of client windows changes, rebuild the list.
    362274 *
    363275 * @param event the X11 event structure
     
    365277void VBoxGuestSeamlessX11::doPropertyEvent(const XPropertyEvent *event)
    366278{
    367     if (XInternAtom(mDisplay, VIRTUAL_ROOTS_PROP, true) == event->atom)
     279    if (XInternAtom(mDisplay, NET_CLIENT_LIST, true) == event->atom)
    368280    {
    369281        rebuildWindowTree();
     
    372284
    373285/**
    374  * Handle a window shape change event in the seamless event thread by changing the set of
    375  * visible rectangles for the window in the list of visible guest windows and updating the
    376  * host's rectangle information.
     286 * Handle a window shape change event in the seamless event thread.
    377287 *
    378288 * @param event the X11 event structure
     
    398308
    399309/**
    400  * Handle an unmap event in the seamless event thread by removing the guest window from the
    401  * list of visible windows and updating the host's rectangle information.
     310 * Handle an unmap event in the seamless event thread.
    402311 *
    403312 * @param event the X11 event structure
     
    406315{
    407316    VBoxGuestWindowList::iterator iter;
    408     bool found = false;
    409 
    410     /* Is this is one of our desktop windows? */
    411     for (unsigned i = 0; i < mDesktopWindows.size() && !found; ++i)
    412     {
    413         if (event->window == mDesktopWindows[i].mWin)
    414         {
    415             mDesktopWindows[i].mMapped = false;
    416             found = true;
    417         }
    418     }
    419     if (!found)
    420     {
    421         /* Make sure that the window is not already present in the tree */
    422         iter = mGuestWindows.find(event->window);
    423         if (iter != mGuestWindows.end())
    424         {
    425             mGuestWindows.removeWindow(event->window);
    426         }
    427         else
    428         {
    429             LogRelFunc(("Warning: UnmapNotify event received for a window not listed as mapped\n"));
    430         }
     317
     318    iter = mGuestWindows.find(event->window);
     319    if (iter != mGuestWindows.end())
     320    {
     321        iter->second->mMapped = true;
    431322    }
    432323}
     
    447338         it != mGuestWindows.end(); ++it)
    448339    {
    449         Window hParent = it->second->mParent;
    450         unsigned iParent;
    451         bool found = false;
    452 
    453         for (iParent = 0; iParent < mDesktopWindows.size() && !found; ++iParent)
     340        if (it->second->mMapped)
    454341        {
    455             if (mDesktopWindows[iParent].mWin == hParent)
     342            if (it->second->mcRects > 0)
    456343            {
    457                 found = true;
     344                for (int i = 0; i < it->second->mcRects; ++i)
     345                {
     346                    RTRECT rect;
     347                    rect.xLeft   =   it->second->mX
     348                                   + it->second->mapRects.get()[i].x;
     349                    rect.yBottom =   it->second->mY
     350                                   + it->second->mapRects.get()[i].y
     351                                   + it->second->mapRects.get()[i].height;
     352                    rect.xRight  =   it->second->mX
     353                                   + it->second->mapRects.get()[i].x
     354                                   + it->second->mapRects.get()[i].width;
     355                    rect.yTop    =   it->second->mY
     356                                   + it->second->mapRects.get()[i].y;
     357                    apRects.get()->push_back(rect);
     358                }
     359                cRects += it->second->mcRects;
     360            }
     361            else
     362            {
     363                RTRECT rect;
     364                rect.xLeft   =  it->second->mX;
     365                rect.yBottom =  it->second->mY
     366                              + it->second->mHeight;
     367                rect.xRight  =  it->second->mX
     368                              + it->second->mWidth;
     369                rect.yTop    =  it->second->mY;
     370                apRects.get()->push_back(rect);
     371                ++cRects;
    458372            }
    459373        }
    460         if (found && mDesktopWindows[iParent - 1].mMapped && it->second->mMapped)
    461         {
    462             for (int i = 0; i < it->second->mcRects; ++i)
    463             {
    464                 RTRECT rect;
    465                 rect.xLeft   =   it->second->mx
    466                               + it->second->mapRects.get()[i].x
    467                               + mDesktopWindows[iParent].mx;
    468                 rect.yBottom =   it->second->my
    469                               + it->second->mapRects.get()[i].y
    470                               + it->second->mapRects.get()[i].height
    471                               + mDesktopWindows[iParent].my;
    472                 rect.xRight  =   it->second->mx
    473                               + it->second->mapRects.get()[i].x
    474                               + it->second->mapRects.get()[i].width
    475                               + mDesktopWindows[iParent].mx;
    476                 rect.yTop    =   it->second->my
    477                               + it->second->mapRects.get()[i].y
    478                               + mDesktopWindows[iParent].my;
    479                 apRects.get()->push_back(rect);
    480             }
    481             cRects += it->second->mcRects;
    482         }
    483374    }
    484375    mcRects = cRects;
     
    493384bool VBoxGuestSeamlessX11::interruptEvent(void)
    494385{
    495     XClientMessageEvent clientMessage = { ClientMessage };  /* Other members set to zero. */
    496     XSendEvent(mDisplay, DefaultRootWindow(mDisplay.get()), false, StructureNotifyMask,
    497                reinterpret_cast<XEvent *>(&clientMessage));
    498     return true;
    499 }
     386    /* Message contents set to zero. */
     387    XClientMessageEvent clientMessage = { ClientMessage, 0, 0, 0, 0, 0, 8 };
     388
     389    if (0 != XSendEvent(mDisplay, DefaultRootWindow(mDisplay.get()), false, PropertyChangeMask,
     390                   reinterpret_cast<XEvent *>(&clientMessage)))
     391    {
     392        XFlush(mDisplay);
     393        return true;
     394    }
     395    return false;
     396}
  • trunk/src/VBox/Additions/x11/xclient/seamless-x11.h

    r6202 r6290  
    2929
    3030#define VIRTUAL_ROOTS_PROP "_NET_VIRTUAL_ROOTS"
     31#define WM_TYPE_PROP "_NET_WM_WINDOW_TYPE"
     32#define WM_TYPE_DESKTOP_PROP "_NET_WM_WINDOW_TYPE_DESKTOP"
     33#define NET_CLIENT_LIST "_NET_CLIENT_LIST"
    3134
    3235/**
     
    132135    Display *mDisplay;
    133136public:
    134     VBoxGuestX11Display(char *name = 0)
     137    VBoxGuestX11Display(void) {}
     138    bool init(char *name = 0)
    135139    {
    136140        mDisplay = XOpenDisplay(name);
     141        return (0 != mDisplay);
    137142    }
    138143    operator Display *() { return mDisplay; }
     
    147152struct VBoxGuestWinInfo {
    148153public:
    149     /** Is this window currently mapped? */
     154    /** Is the window currently mapped? */
    150155    bool mMapped;
    151156    /** Co-ordinates in the guest screen. */
    152     int mx, my;
     157    int mX, mY;
    153158    /** Window dimensions. */
    154     int mwidth, mheight;
     159    int mWidth, mHeight;
    155160    /** Number of rectangles used to represent the visible area. */
    156161    int mcRects;
     
    158163        and will be freed automatically if non-null when the class is destroyed. */
    159164    VBoxGuestX11Pointer<XRectangle> mapRects;
    160     /** The index of the virtual root that this window is a child of. */
    161     int mParent;
    162165    /** Constructor. */
    163     VBoxGuestWinInfo(bool mapped, int x, int y, int w, int h, int cRects,
    164                      VBoxGuestX11Pointer<XRectangle> rects, int parent)
     166    VBoxGuestWinInfo(bool isMapped, int x, int y, int w, int h, int cRects,
     167                     VBoxGuestX11Pointer<XRectangle> rects)
    165168            : mapRects(rects)
    166169    {
    167         mMapped = mapped; mx = x; my = y; mwidth = w; mheight = h; mcRects = cRects;
    168         mParent = parent;
     170        mMapped = isMapped, mX = x; mY = y; mWidth = w; mHeight = h; mcRects = cRects;
    169171    }
    170172
     
    214216
    215217    void addWindow(Window hWin, bool isMapped, int x, int y, int w, int h, int cRects,
    216                    VBoxGuestX11Pointer<XRectangle> rects, int parent)
     218                   VBoxGuestX11Pointer<XRectangle> rects)
    217219    {
    218220        VBoxGuestWinInfo *pInfo = new VBoxGuestWinInfo(isMapped, x, y, w, h, cRects,
    219                                                        rects, parent);
     221                                                       rects);
    220222        mWindows.insert(std::pair<Window, VBoxGuestWinInfo *>(hWin, pInfo));
    221223    }
     
    230232    {
    231233        removeWindow(find(hWin));
    232     }
    233 };
    234 
    235 /** Structure containing information about a windows handle and position, for keeping
    236     track of desktop windows.  Used internally by VBoxGuestSeamlessX11. */
    237 struct VBoxGuestDesktopInfo
    238 {
    239     /** The Window handle for this window. */
    240     Window mWin;
    241     /** Co-ordinates relative to the root window (I hope!). */
    242     int mx, my;
    243     /** Is this window mapped? */
    244     bool mMapped;
    245 
    246     /** Constructor */
    247     VBoxGuestDesktopInfo(Window hWin, int x, int y, bool mapped)
    248     {
    249         mWin = hWin;
    250         mx = x;
    251         my = y;
    252         mMapped = mapped;
    253234    }
    254235};
     
    268249    /** Our connection to the X11 display we are running on. */
    269250    VBoxGuestX11Display mDisplay;
    270     /** Vector to keep track of which windows are to be treated as desktop windows. */
    271     std::vector<VBoxGuestDesktopInfo> mDesktopWindows;
    272251    /** Class to keep track of visible guest windows. */
    273252    VBoxGuestWindowList mGuestWindows;
     
    276255        the vector of rectangles passed to the host. */
    277256    int mcRects;
     257    /** Do we support the X shaped window extension? */
     258    bool mSupportsShape;
    278259    /** Is seamles mode currently enabled?  */
    279     bool isEnabled;
     260    bool mEnabled;
    280261
    281262    // Private methods
     
    297278     * @param   hWin     the window concerned - should be a "desktop" window
    298279     */
    299     void addDesktopWindow(Window hWin);
    300     bool addNonDesktopWindow(Window hWin);
    301     void addWindowToList(Window hWin, Window hParent);
    302     void monitorDesktopWindows(void);
     280    void monitorClientList(void);
     281    void unmonitorClientList(void);
    303282    void rebuildWindowTree(void);
     283    void addClientWindow(Window hWin);
    304284    void freeWindowTree(void);
    305285    void updateHostSeamlessInfo(void);
     
    337317    std::auto_ptr<std::vector<RTRECT> > getRects(void);
    338318
    339     /** Process next event in the X11 event queue - called by the event thread. */
     319    /** Process next event in the guest event queue - called by the event thread. */
    340320    void nextEvent(void);
    341     /** Send ourselves an X11 client event to wake up the event thread - called by
    342         the event thread. */
     321    /** Wake up the event thread if it is waiting for an event so that it can exit. */
    343322    bool interruptEvent(void);
    344323
    345324    VBoxGuestSeamlessX11(void)
    346325    {
    347         mObserver = 0; mcRects = 0; isEnabled = false;
     326        mObserver = 0; mcRects = 0; mEnabled = false; mSupportsShape = false;
    348327    }
    349328
  • trunk/src/VBox/Additions/x11/xclient/seamless.h

    r6202 r6290  
    2929    /** The guest class "owning" us. */
    3030    VBoxGuestSeamlessGuestImpl *mGuest;
     31    /** The guest observer monitoring the guest. */
     32    VBoxGuestSeamlessObserver *mObserver;
    3133    /** Should we exit the thread? */
    3234    bool mExit;
     
    3739
    3840public:
    39     VBoxGuestSeamlessGuestThread(VBoxGuestSeamlessGuestImpl *pGuest)
    40     { mGuest = pGuest; mExit = false; }
     41    VBoxGuestSeamlessGuestThread(VBoxGuestSeamlessGuestImpl *pGuest,
     42                                 VBoxGuestSeamlessObserver *pObserver)
     43    { mGuest = pGuest; mObserver = pObserver; mExit = false; }
    4144    virtual ~VBoxGuestSeamlessGuestThread(void) {}
    4245    /**
     
    4851    virtual int threadFunction(VBoxGuestThread *pThread)
    4952    {
    50         while (!pThread->isStopping)
     53        int rc = VINF_SUCCESS;
     54
     55        rc = mGuest->start();
     56        if (RT_SUCCESS(rc))
    5157        {
    52             mGuest->nextEvent();
     58            while (!pThread->isStopping())
     59            {
     60                mGuest->nextEvent();
     61            }
     62            mGuest->stop();
    5363        }
    54         return VINF_SUCCESS;
     64        return rc;
    5565    }
    5666    /**
     
    6676private:
    6777    VBoxGuestSeamlessHost *mHost;
    68     VBoxGuestSeamlessGuestImpl *mGuest;
     78    VBoxGuestThread *mGuestThread;
    6979
    7080public:
    7181    VBoxGuestSeamlessHostObserver(VBoxGuestSeamlessHost *pHost,
    72                                   VBoxGuestSeamlessGuestImpl *pGuest)
     82                                  VBoxGuestThread *pGuestThread)
    7383    {
    7484        mHost = pHost;
    75         mGuest = pGuest;
     85        mGuestThread = pGuestThread;
    7686    }
    7787
    78     void notify(void)
     88    virtual void notify(void)
    7989    {
    8090        switch (mHost->getState())
    8191        {
    82         case VBoxGuestSeamlessGuest::ENABLE:
    83              mGuest->start();
     92        case VBoxGuestSeamlessHost::ENABLE:
     93             mGuestThread->start();
    8494            break;
    85         case VBoxGuestSeamlessGuest::DISABLE:
    86              mGuest->stop();
     95        case VBoxGuestSeamlessHost::DISABLE:
     96             mGuestThread->stop(RT_INDEFINITE_WAIT, 0);
    8797            break;
    8898        default:
     
    108118    }
    109119
    110     void notify(void)
     120    virtual void notify(void)
    111121    {
    112122        mHost->updateRects(mGuest->getRects());
     
    119129    VBoxGuestSeamlessHost mHost;
    120130    VBoxGuestSeamlessGuestImpl mGuest;
     131    VBoxGuestSeamlessGuestThread mGuestFunction;
     132    VBoxGuestThread mGuestThread;
    121133    VBoxGuestSeamlessHostObserver mHostObs;
    122134    VBoxGuestSeamlessGuestObserver mGuestObs;
    123     VBoxGuestSeamlessGuestThread mGuestFunction;
    124     VBoxGuestThread mGuestThread;
    125135
    126136    bool isInitialised;
     
    132142        if (isInitialised)  /* Assertion */
    133143        {
    134             LogRelFunc(("error: called a second time!\n"));
     144            LogRelFunc(("error: called a second time! (VBoxService)\n"));
    135145            rc = VERR_INTERNAL_ERROR;
    136146        }
     
    149159        if (RT_SUCCESS(rc))
    150160        {
    151             rc = mGuestThread.start();
     161            isInitialised = true;
    152162        }
    153         isInitialised = true;
     163        if (RT_FAILURE(rc))
     164        {
     165            LogFunc(("returning %Rrc (VBoxService)\n", rc));
     166        }
    154167        return rc;
    155168    }
     
    159172        if (isInitialised)
    160173        {
    161             mGuestThread.stop();
    162174            mHost.stop();
     175            mGuestThread.stop(RT_INDEFINITE_WAIT, 0);
    163176            mGuest.uninit();
    164177            isInitialised = false;
     
    166179    }
    167180
    168     VBoxGuestSeamless() : mHostObs(&mHost, &mGuest), mHostObs(&mHost, &mGuest),
    169                           mGuestFunction(&mGuest), mGuestThread(&mGuestFunction)
     181    VBoxGuestSeamless() : mGuestFunction(&mGuest, &mGuestObs),
     182                          mGuestThread(&mGuestFunction, 0, RTTHREADTYPE_MSG_PUMP,
     183                                       RTTHREADFLAGS_WAITABLE, "Guest events"),
     184                          mHostObs(&mHost, &mGuestThread), mGuestObs(&mHost, &mGuest)
    170185    {
    171186        isInitialised = false;
  • trunk/src/VBox/Additions/x11/xclient/thread.h

    r6202 r6290  
    3030{
    3131public:
    32     VBoxGuestThreadFunction(void);
     32    // VBoxGuestThreadFunction(void);
    3333    virtual ~VBoxGuestThreadFunction(void) {}
    3434    /**
  • trunk/src/testcase/tstRunTestcases.cpp

    r5999 r6290  
    6161    "testcase/tstSDL",
    6262    "testcase/tstTime-3",
     63    "testcase/tstSeamlessX11",
    6364    "./tstRunTestcases",
    6465    "./tstAnimate",
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