Changeset 44150 in vbox
- Timestamp:
- Dec 18, 2012 2:19:07 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r44149 r44150 418 418 419 419 #ifdef VBOX_WITH_WDDM 420 /**/421 typedef DECLCALLBACK(VOID) FNVBOXSCREENMONRUNNER_CB(void *pvCb);422 typedef FNVBOXSCREENMONRUNNER_CB *PFNVBOXSCREENMONRUNNER_CB;423 424 typedef struct VBOXSCREENMON425 {426 HANDLE hThread;427 DWORD idThread;428 HANDLE hEvent;429 HWND hWnd;430 PFNVBOXSCREENMONRUNNER_CB pfnCb;431 void *pvCb;432 } VBOXSCREENMON, *PVBOXSCREENMON;433 434 435 static VBOXSCREENMON g_VBoxScreenMon;436 437 438 #define VBOX_E_INSUFFICIENT_BUFFER HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)439 #define VBOX_E_NOT_SUPPORTED HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)440 441 442 static void vboxScreenMonOnChange()443 {444 PVBOXSCREENMON pMon = &g_VBoxScreenMon;445 pMon->pfnCb(pMon->pvCb);446 }447 448 static LRESULT CALLBACK vboxScreenMonWndProc(HWND hwnd,449 UINT uMsg,450 WPARAM wParam,451 LPARAM lParam452 )453 {454 switch(uMsg)455 {456 case WM_DISPLAYCHANGE:457 {458 vboxScreenMonOnChange();459 }460 case WM_CLOSE:461 Log((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd));462 return 0;463 case WM_DESTROY:464 Log((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd));465 return 0;466 case WM_NCHITTEST:467 Log((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd));468 return HTNOWHERE;469 }470 471 return DefWindowProc(hwnd, uMsg, wParam, lParam);472 }473 474 #define VBOXSCREENMONWND_NAME "VboxScreenMonWnd"475 476 static HRESULT vboxScreenMonWndCreate(HWND *phWnd)477 {478 HRESULT hr = S_OK;479 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);480 /* Register the Window Class. */481 WNDCLASS wc;482 if (!GetClassInfo(hInstance, VBOXSCREENMONWND_NAME, &wc))483 {484 wc.style = 0;//CS_OWNDC;485 wc.lpfnWndProc = vboxScreenMonWndProc;486 wc.cbClsExtra = 0;487 wc.cbWndExtra = 0;488 wc.hInstance = hInstance;489 wc.hIcon = NULL;490 wc.hCursor = NULL;491 wc.hbrBackground = NULL;492 wc.lpszMenuName = NULL;493 wc.lpszClassName = VBOXSCREENMONWND_NAME;494 if (!RegisterClass(&wc))495 {496 DWORD winErr = GetLastError();497 Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));498 hr = E_FAIL;499 }500 }501 502 if (hr == S_OK)503 {504 HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW,505 VBOXSCREENMONWND_NAME, VBOXSCREENMONWND_NAME,506 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,507 -100, -100,508 10, 10,509 NULL, //GetDesktopWindow() /* hWndParent */,510 NULL /* hMenu */,511 hInstance,512 NULL /* lpParam */);513 Assert(hWnd);514 if (hWnd)515 {516 *phWnd = hWnd;517 }518 else519 {520 DWORD winErr = GetLastError();521 Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));522 hr = E_FAIL;523 }524 }525 526 return hr;527 }528 529 static HRESULT vboxScreenMonWndDestroy(HWND hWnd)530 {531 BOOL bResult = DestroyWindow(hWnd);532 if (bResult)533 return S_OK;534 535 DWORD winErr = GetLastError();536 Log((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));537 Assert(0);538 539 return HRESULT_FROM_WIN32(winErr);540 }541 542 static HRESULT vboxScreenMonWndInit()543 {544 PVBOXSCREENMON pMon = &g_VBoxScreenMon;545 return vboxScreenMonWndCreate(&pMon->hWnd);546 }547 548 HRESULT vboxScreenMonWndTerm()549 {550 PVBOXSCREENMON pMon = &g_VBoxScreenMon;551 HRESULT tmpHr = vboxScreenMonWndDestroy(pMon->hWnd);552 Assert(tmpHr == S_OK);553 554 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);555 UnregisterClass(VBOXSCREENMONWND_NAME, hInstance);556 557 return S_OK;558 }559 560 #define WM_VBOXSCREENMON_INIT_QUIT (WM_APP+2)561 562 HRESULT vboxScreenMonRun()563 {564 PVBOXSCREENMON pMon = &g_VBoxScreenMon;565 MSG Msg;566 567 HRESULT hr = S_FALSE;568 569 PeekMessage(&Msg,570 NULL /* HWND hWnd */,571 WM_USER /* UINT wMsgFilterMin */,572 WM_USER /* UINT wMsgFilterMax */,573 PM_NOREMOVE);574 575 BOOL bCheck = TRUE;576 577 do578 {579 if (bCheck)580 {581 vboxScreenMonOnChange();582 583 bCheck = FALSE;584 }585 586 BOOL bResult = GetMessage(&Msg,587 0 /*HWND hWnd*/,588 0 /*UINT wMsgFilterMin*/,589 0 /*UINT wMsgFilterMax*/590 );591 592 if(!bResult) /* WM_QUIT was posted */593 {594 hr = S_FALSE;595 break;596 }597 598 if(bResult == -1) /* error occurred */599 {600 DWORD winEr = GetLastError();601 hr = HRESULT_FROM_WIN32(winEr);602 Assert(0);603 /* just ensure we never return success in this case */604 Assert(hr != S_OK);605 Assert(hr != S_FALSE);606 if (hr == S_OK || hr == S_FALSE)607 hr = E_FAIL;608 break;609 }610 611 switch (Msg.message)612 {613 case WM_VBOXSCREENMON_INIT_QUIT:614 case WM_CLOSE:615 {616 PostQuitMessage(0);617 break;618 }619 case WM_DISPLAYCHANGE:620 bCheck = TRUE;621 default:622 TranslateMessage(&Msg);623 DispatchMessage(&Msg);624 break;625 }626 } while (1);627 return 0;628 }629 630 static DWORD WINAPI vboxScreenMonRunnerThread(void *pvUser)631 {632 PVBOXSCREENMON pMon = &g_VBoxScreenMon;633 634 BOOL bRc = SetEvent(pMon->hEvent);635 if (!bRc)636 {637 DWORD winErr = GetLastError();638 Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr));639 HRESULT tmpHr = HRESULT_FROM_WIN32(winErr);640 Assert(0);641 Assert(tmpHr != S_OK);642 }643 644 HRESULT hr = vboxScreenMonWndInit();645 Assert(hr == S_OK);646 if (hr == S_OK)647 {648 hr = vboxScreenMonRun();649 Assert(hr == S_OK);650 651 vboxScreenMonWndTerm();652 }653 654 return 0;655 }656 657 HRESULT VBoxScreenMonInit(PFNVBOXSCREENMONRUNNER_CB pfnCb, void *pvCb)658 {659 HRESULT hr = E_FAIL;660 PVBOXSCREENMON pMon = &g_VBoxScreenMon;661 memset(pMon, 0, sizeof (*pMon));662 663 pMon->pfnCb = pfnCb;664 pMon->pvCb = pvCb;665 666 pMon->hEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes*/667 TRUE, /* BOOL bManualReset*/668 FALSE, /* BOOL bInitialState */669 NULL /* LPCTSTR lpName */670 );671 if (pMon->hEvent)672 {673 pMon->hThread = CreateThread(NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,674 0 /* SIZE_T dwStackSize */,675 vboxScreenMonRunnerThread,676 pMon,677 0 /* DWORD dwCreationFlags */,678 &pMon->idThread);679 if (pMon->hThread)680 {681 DWORD dwResult = WaitForSingleObject(pMon->hEvent, INFINITE);682 if (dwResult == WAIT_OBJECT_0)683 return S_OK;684 else685 {686 Log(("WaitForSingleObject failed!"));687 hr = E_FAIL;688 }689 }690 else691 {692 DWORD winErr = GetLastError();693 Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));694 hr = HRESULT_FROM_WIN32(winErr);695 Assert(0);696 Assert(hr != S_OK);697 }698 CloseHandle(pMon->hEvent);699 }700 else701 {702 DWORD winErr = GetLastError();703 Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr));704 hr = HRESULT_FROM_WIN32(winErr);705 Assert(0);706 Assert(hr != S_OK);707 }708 709 return hr;710 }711 712 VOID VBoxScreenMonTerm()713 {714 HRESULT hr;715 PVBOXSCREENMON pMon = &g_VBoxScreenMon;716 if (!pMon->hThread)717 return;718 719 BOOL bResult = PostThreadMessage(pMon->idThread, WM_VBOXSCREENMON_INIT_QUIT, 0, 0);720 DWORD winErr;721 if (bResult722 || (winErr = GetLastError()) == ERROR_INVALID_THREAD_ID) /* <- could be that the thread is terminated */723 {724 DWORD dwErr = WaitForSingleObject(pMon->hThread, INFINITE);725 if (dwErr == WAIT_OBJECT_0)726 {727 hr = S_OK;728 }729 else730 {731 winErr = GetLastError();732 hr = HRESULT_FROM_WIN32(winErr);733 Assert(0);734 }735 }736 else737 {738 hr = HRESULT_FROM_WIN32(winErr);739 Assert(0);740 }741 742 CloseHandle(pMon->hThread);743 pMon->hThread = 0;744 CloseHandle(pMon->hEvent);745 pMon->hThread = 0;746 }747 /**/748 749 420 typedef struct VBOXDISPIF_WDDM_INTERNAL 750 421 { 751 422 PCVBOXDISPIF pIf; 752 753 HANDLE hResizeEvent;754 423 } VBOXDISPIF_WDDM_INTERNAL, *PVBOXDISPIF_WDDM_INTERNAL; 755 424 … … 920 589 } 921 590 922 static DECLCALLBACK(VOID) vboxDispIfWddmScreenMonCb(void *pvCb)923 {924 PVBOXDISPIF_WDDM_INTERNAL pData = (PVBOXDISPIF_WDDM_INTERNAL)pvCb;925 926 SetEvent(pData->hResizeEvent);927 }928 929 591 static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf) 930 592 { 931 593 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 932 594 g_VBoxDispIfWddm.pIf = pIf; 933 g_VBoxDispIfWddm.hResizeEvent = CreateEvent(NULL, 934 FALSE, /* BOOL bManualReset */ 935 FALSE, /* BOOL bInitialState */ 936 NULL /* LPCTSTR lpName */ 937 ); 938 if (g_VBoxDispIfWddm.hResizeEvent) 939 { 940 HRESULT hr = VBoxScreenMonInit(vboxDispIfWddmScreenMonCb, &g_VBoxDispIfWddm); 941 if (SUCCEEDED(hr)) 942 { 943 /* ensure event is reset */ 944 WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 0); 945 return ERROR_SUCCESS; 946 } 947 CloseHandle(g_VBoxDispIfWddm.hResizeEvent); 948 } 949 return ERROR_GEN_FAILURE; 595 return ERROR_SUCCESS; 950 596 } 951 597 952 598 static void vboxDispIfWddmTerm(PCVBOXDISPIF pIf) 953 599 { 954 VBoxScreenMonTerm();955 CloseHandle(g_VBoxDispIfWddm.hResizeEvent);956 600 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 957 601 } … … 1182 826 * make the driver invalidate VidPn, 1183 827 * which is done by emulating a monitor re-plug currently */ 1184 /* ensure event is reset */1185 WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 0);1186 1187 828 uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE] = {0}; 1188 829 ASMBitSet(ScreenMask, iChangedMode); … … 1190 831 1191 832 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1192 1193 // for (UINT i = 0; i < 4; ++i)1194 // {1195 // WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 500);1196 // winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes);1197 // if (winEr == NO_ERROR)1198 // break;1199 // }1200 833 1201 834 Assert(winEr == NO_ERROR);
Note:
See TracChangeset
for help on using the changeset viewer.