HRESULT vboxDispMpTstStop()
{
    HRESULT hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents();
    Assert(hr == S_OK);
#if 0
    if (hr == S_OK)
    {
        int rc = RTThreadWaitNoResume(g_VBoxDispMpTstThread, RT_INDEFINITE_WAIT, NULL);
        AssertRC(rc);
        if (RT_SUCCESS(rc))
        {
            BOOL bResult = FreeLibrary(g_hVBoxDispMpModule);
            Assert(bResult);
#ifdef DEBUG
            if (!bResult)
            {
                DWORD winEr = GetLastError();
                hr = HRESULT_FROM_WIN32(winEr);
            }
#endif
        }
        else
            hr = E_FAIL;
    }
#endif
    return hr;
}
static DECLCALLBACK(int) vboxDispMpTstThreadProc(RTTHREAD ThreadSelf, void *pvUser)
{
    VBOXDISPMP_REGIONS Regions;

    HRESULT hr = g_VBoxDispMpTstCallbacks.pfnEnableEvents();
    Assert(hr == S_OK);
    if (hr != S_OK)
        return VERR_GENERAL_FAILURE;

    do
    {
        hr = g_VBoxDispMpTstCallbacks.pfnGetRegions(&Regions, INFINITE);
        Assert(hr == S_OK);
        if (hr == S_OK)
        {
            vboxVDbgPrint(("\n>>>\n"));
            HWND hWnd = Regions.hWnd;
            if (Regions.pRegions->fFlags.bSetVisibleRects)
            {
                uint32_t iVisibleRects = 0;
                uint32_t cVisibleRects = Regions.pRegions->RectsInfo.cRects;
                if (Regions.pRegions->fFlags.bSetViewRect)
                {
                    iVisibleRects = 1;

                    vboxVDbgPrint(("hWnd (0x%p), position and/or size changed: ", hWnd));
                    vboxDispMpTstLogRect("", Regions.pRegions->RectsInfo.aRects, "\n");
                }

                vboxVDbgPrint(("hWnd (0x%p), visibleRects: \n", hWnd));
                for (uint32_t i = iVisibleRects; i < cVisibleRects; ++i)
                {
                    vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], "");
                }
            }
            else if (Regions.pRegions->fFlags.bAddHiddenRects)
            {
                vboxVDbgPrint(("hWnd (0x%p), hiddenRects: \n", hWnd));
                for (uint32_t i = 0; i < Regions.pRegions->RectsInfo.cRects; ++i)
                {
                    vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], "");
                }
            }

            vboxVDbgPrint(("\n<<<\n"));
        }
    } while (1);

    hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents();
    Assert(hr == S_OK);

    return VINF_SUCCESS;
}
Beispiel #3
0
static DECLCALLBACK(int) stubSyncThreadProc(RTTHREAD ThreadSelf, void *pvUser)
{
#ifdef WINDOWS
    MSG msg;
# ifdef VBOX_WITH_WDDM
    static VBOXDISPMP_CALLBACKS VBoxDispMpTstCallbacks = {NULL, NULL, NULL};
    HMODULE hVBoxD3D = NULL;
    VBOXCR_UPDATEWNDCB RegionsData;
    HRESULT hr;
    GLint spuConnection = 0;
# endif
#endif

    (void) pvUser;

    crDebug("Sync thread started");
#ifdef WINDOWS
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
# ifdef VBOX_WITH_WDDM
    hVBoxD3D = GetModuleHandle(VBOX_MODNAME_DISPD3D);
    if (hVBoxD3D)
    {
        hVBoxD3D = LoadLibrary(VBOX_MODNAME_DISPD3D);
    }

    if (hVBoxD3D)
    {
        PFNVBOXDISPMP_GETCALLBACKS pfnVBoxDispMpGetCallbacks;
        pfnVBoxDispMpGetCallbacks = (PFNVBOXDISPMP_GETCALLBACKS)GetProcAddress(hVBoxD3D, TEXT("VBoxDispMpGetCallbacks"));
        if (pfnVBoxDispMpGetCallbacks)
        {
            hr = pfnVBoxDispMpGetCallbacks(VBOXDISPMP_VERSION, &VBoxDispMpTstCallbacks);
            if (S_OK==hr)
            {
                CRASSERT(VBoxDispMpTstCallbacks.pfnEnableEvents);
                CRASSERT(VBoxDispMpTstCallbacks.pfnDisableEvents);
                CRASSERT(VBoxDispMpTstCallbacks.pfnGetRegions);

                hr = VBoxDispMpTstCallbacks.pfnEnableEvents();
                if (hr != S_OK)
                {
                    crWarning("VBoxDispMpTstCallbacks.pfnEnableEvents failed");
                }
                else
                {
                    crDebug("running with " VBOX_MODNAME_DISPD3D);
                    stub.trackWindowVisibleRgn = 0;
                    stub.bRunningUnderWDDM = true;
#ifdef VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS
                    crError("should not be here, visible rects should be processed in miniport!");
#endif
                }
            }
            else
            {
                crWarning("VBoxDispMpGetCallbacks failed");
            }
        }
    }
# endif /* VBOX_WITH_WDDM */
#endif /* WINDOWS */

    crLockMutex(&stub.mutex);
#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
    spuConnection =
#endif
            stub.spu->dispatch_table.VBoxPackSetInjectThread(NULL);
#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
    if (stub.bRunningUnderWDDM && !spuConnection)
    {
        crError("VBoxPackSetInjectThread failed!");
    }
#endif
    crUnlockMutex(&stub.mutex);

    RTThreadUserSignal(ThreadSelf);

    while(!stub.bShutdownSyncThread)
    {
#ifdef WINDOWS
        if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
# ifdef VBOX_WITH_WDDM
            if (VBoxDispMpTstCallbacks.pfnGetRegions)
            {
                hr = VBoxDispMpTstCallbacks.pfnGetRegions(&RegionsData.Regions, 50);
                if (S_OK==hr)
                {
                    RegionsData.fSendUpdateMsg = false;
#  if 0
                    uint32_t i;
                    crDebug(">>>Regions for HWND(0x%x)>>>", RegionsData.Regions.hWnd);
                    crDebug("Flags(0x%x)", RegionsData.Regions.pRegions->fFlags.Value);
                    for (i = 0; i < RegionsData.Regions.pRegions->RectsInfo.cRects; ++i)
                    {
                        RECT *pRect = &RegionsData.Regions.pRegions->RectsInfo.aRects[i];
                        crDebug("Rect(%d): left(%d), top(%d), right(%d), bottom(%d)", i, pRect->left, pRect->top, pRect->right, pRect->bottom);
                    }
                    crDebug("<<<<<");
#  endif
                    /*hacky way to make sure window wouldn't be deleted in another thread as we hold hashtable lock here*/
                    crHashtableWalk(stub.windowTable, stubSyncTrUpdateWindowCB, &RegionsData);
                    if (RegionsData.fSendUpdateMsg)
                    {
                        SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_NORMAL, 1000, NULL);
                    }
                }
                else
                {
                    if (WAIT_TIMEOUT!=hr)
                    {
                        crWarning("VBoxDispMpTstCallbacks.pfnGetRegions failed with 0x%x", hr);
                    }
                    crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
                }
            }
            else
# endif
            {
                crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
                RTThreadSleep(50);
            }
        }
        else
        {
            if (WM_QUIT==msg.message)
            {
                crDebug("Sync thread got WM_QUIT");
                break;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
#else
        crLockMutex(&stub.mutex);
        crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
        crUnlockMutex(&stub.mutex);
        RTThreadSleep(50);
#endif
    }

#ifdef VBOX_WITH_WDDM
    if (VBoxDispMpTstCallbacks.pfnDisableEvents)
    {
        VBoxDispMpTstCallbacks.pfnDisableEvents();
    }
    if (spuConnection)
    {
        stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
    }
    if (hVBoxD3D)
    {
        FreeLibrary(hVBoxD3D);
    }
#endif
    crDebug("Sync thread stopped");
    return 0;
}