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; }
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) 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; }