Changeset 44550 in vbox
- Timestamp:
- Feb 5, 2013 4:11:03 PM (12 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r44528 r44550 418 418 419 419 #ifdef VBOX_WITH_WDDM 420 /**/ 421 #define VBOXRR_TIMER_ID 1234 422 423 typedef struct VBOXRR 424 { 425 HANDLE hThread; 426 DWORD idThread; 427 HANDLE hEvent; 428 HWND hWnd; 429 CRITICAL_SECTION CritSect; 430 UINT_PTR idTimer; 431 PCVBOXDISPIF pIf; 432 DISPLAY_DEVICE *paDisplayDevices; 433 DEVMODE *paDeviceModes; 434 UINT cDevModes; 435 } VBOXRR, *PVBOXRR; 436 437 static VBOXRR g_VBoxRr = {0}; 438 439 #define VBOX_E_INSUFFICIENT_BUFFER HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) 440 #define VBOX_E_NOT_SUPPORTED HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) 441 442 static void vboxRrRetryStopLocked() 443 { 444 PVBOXRR pMon = &g_VBoxRr; 445 if (pMon->pIf) 446 { 447 if (pMon->paDisplayDevices) 448 { 449 free(pMon->paDisplayDevices); 450 pMon->paDisplayDevices = NULL; 451 } 452 453 if (pMon->paDeviceModes) 454 { 455 free(pMon->paDeviceModes); 456 pMon->paDeviceModes = NULL; 457 } 458 459 if (pMon->idTimer) 460 { 461 KillTimer(pMon->hWnd, pMon->idTimer); 462 pMon->idTimer = 0; 463 } 464 465 pMon->cDevModes = 0; 466 pMon->pIf = NULL; 467 } 468 } 469 470 static void VBoxRrRetryStop() 471 { 472 PVBOXRR pMon = &g_VBoxRr; 473 EnterCriticalSection(&pMon->CritSect); 474 vboxRrRetryStopLocked(); 475 LeaveCriticalSection(&pMon->CritSect); 476 } 477 478 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 479 480 static void vboxRrRetryReschedule() 481 { 482 } 483 484 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 485 { 486 PVBOXRR pMon = &g_VBoxRr; 487 EnterCriticalSection(&pMon->CritSect); 488 vboxRrRetryStopLocked(); 489 490 pMon->pIf = pIf; 491 if (cDevModes) 492 { 493 pMon->paDisplayDevices = (DISPLAY_DEVICE*)malloc(sizeof (*paDisplayDevices) * cDevModes); 494 Assert(pMon->paDisplayDevices); 495 if (!pMon->paDisplayDevices) 496 { 497 Log(("malloc failed!")); 498 vboxRrRetryStopLocked(); 499 LeaveCriticalSection(&pMon->CritSect); 500 return; 501 } 502 memcpy(pMon->paDisplayDevices, paDisplayDevices, sizeof (*paDisplayDevices) * cDevModes); 503 504 pMon->paDeviceModes = (DEVMODE*)malloc(sizeof (*paDeviceModes) * cDevModes); 505 Assert(pMon->paDeviceModes); 506 if (!pMon->paDeviceModes) 507 { 508 Log(("malloc failed!")); 509 vboxRrRetryStopLocked(); 510 LeaveCriticalSection(&pMon->CritSect); 511 return; 512 } 513 memcpy(pMon->paDeviceModes, paDeviceModes, sizeof (*paDeviceModes) * cDevModes); 514 } 515 pMon->cDevModes = cDevModes; 516 517 pMon->idTimer = SetTimer(pMon->hWnd, VBOXRR_TIMER_ID, 1000, (TIMERPROC)NULL); 518 Assert(pMon->idTimer); 519 if (!pMon->idTimer) 520 { 521 Log(("SetTimer failed!, err %d", GetLastError())); 522 vboxRrRetryStopLocked(); 523 } 524 525 LeaveCriticalSection(&pMon->CritSect); 526 } 527 528 static void vboxRrRetryPerform() 529 { 530 PVBOXRR pMon = &g_VBoxRr; 531 EnterCriticalSection(&pMon->CritSect); 532 if (pMon->pIf) 533 { 534 DWORD dwErr = vboxDispIfWddmValidateFixResize(pMon->pIf, pMon->paDisplayDevices, pMon->paDeviceModes, pMon->cDevModes); 535 if (ERROR_RETRY != dwErr) 536 VBoxRrRetryStop(); 537 else 538 vboxRrRetryReschedule(); 539 } 540 LeaveCriticalSection(&pMon->CritSect); 541 } 542 543 static LRESULT CALLBACK vboxRrWndProc(HWND hwnd, 544 UINT uMsg, 545 WPARAM wParam, 546 LPARAM lParam 547 ) 548 { 549 switch(uMsg) 550 { 551 case WM_DISPLAYCHANGE: 552 { 553 VBoxRrRetryStop(); 554 return 0; 555 } 556 case WM_TIMER: 557 { 558 if (wParam == VBOXRR_TIMER_ID) 559 { 560 vboxRrRetryPerform(); 561 return 0; 562 } 563 break; 564 } 565 case WM_CLOSE: 566 Log((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd)); 567 return 0; 568 case WM_DESTROY: 569 Log((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd)); 570 return 0; 571 case WM_NCHITTEST: 572 Log((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd)); 573 return HTNOWHERE; 574 default: 575 break; 576 } 577 578 return DefWindowProc(hwnd, uMsg, wParam, lParam); 579 } 580 581 #define VBOXRRWND_NAME "VBoxRrWnd" 582 583 static HRESULT vboxRrWndCreate(HWND *phWnd) 584 { 585 HRESULT hr = S_OK; 586 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 587 /* Register the Window Class. */ 588 WNDCLASS wc; 589 if (!GetClassInfo(hInstance, VBOXRRWND_NAME, &wc)) 590 { 591 wc.style = 0;//CS_OWNDC; 592 wc.lpfnWndProc = vboxRrWndProc; 593 wc.cbClsExtra = 0; 594 wc.cbWndExtra = 0; 595 wc.hInstance = hInstance; 596 wc.hIcon = NULL; 597 wc.hCursor = NULL; 598 wc.hbrBackground = NULL; 599 wc.lpszMenuName = NULL; 600 wc.lpszClassName = VBOXRRWND_NAME; 601 if (!RegisterClass(&wc)) 602 { 603 DWORD winErr = GetLastError(); 604 Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr)); 605 hr = E_FAIL; 606 } 607 } 608 609 if (hr == S_OK) 610 { 611 HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW, 612 VBOXRRWND_NAME, VBOXRRWND_NAME, 613 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, 614 -100, -100, 615 10, 10, 616 NULL, //GetDesktopWindow() /* hWndParent */, 617 NULL /* hMenu */, 618 hInstance, 619 NULL /* lpParam */); 620 Assert(hWnd); 621 if (hWnd) 622 { 623 *phWnd = hWnd; 624 } 625 else 626 { 627 DWORD winErr = GetLastError(); 628 Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr)); 629 hr = E_FAIL; 630 } 631 } 632 633 return hr; 634 } 635 636 static HRESULT vboxRrWndDestroy(HWND hWnd) 637 { 638 BOOL bResult = DestroyWindow(hWnd); 639 if (bResult) 640 return S_OK; 641 642 DWORD winErr = GetLastError(); 643 Log((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd)); 644 645 return HRESULT_FROM_WIN32(winErr); 646 } 647 648 static HRESULT vboxRrWndInit() 649 { 650 PVBOXRR pMon = &g_VBoxRr; 651 return vboxRrWndCreate(&pMon->hWnd); 652 } 653 654 HRESULT vboxRrWndTerm() 655 { 656 PVBOXRR pMon = &g_VBoxRr; 657 HRESULT tmpHr = vboxRrWndDestroy(pMon->hWnd); 658 Assert(tmpHr == S_OK); 659 660 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 661 UnregisterClass(VBOXRRWND_NAME, hInstance); 662 663 return S_OK; 664 } 665 666 #define WM_VBOXRR_INIT_QUIT (WM_APP+2) 667 668 HRESULT vboxRrRun() 669 { 670 PVBOXRR pMon = &g_VBoxRr; 671 MSG Msg; 672 673 HRESULT hr = S_FALSE; 674 675 PeekMessage(&Msg, 676 NULL /* HWND hWnd */, 677 WM_USER /* UINT wMsgFilterMin */, 678 WM_USER /* UINT wMsgFilterMax */, 679 PM_NOREMOVE); 680 681 do 682 { 683 BOOL bResult = GetMessage(&Msg, 684 0 /*HWND hWnd*/, 685 0 /*UINT wMsgFilterMin*/, 686 0 /*UINT wMsgFilterMax*/ 687 ); 688 689 if(!bResult) /* WM_QUIT was posted */ 690 { 691 hr = S_FALSE; 692 VBoxRrRetryStop(); 693 break; 694 } 695 696 if(bResult == -1) /* error occurred */ 697 { 698 DWORD winEr = GetLastError(); 699 hr = HRESULT_FROM_WIN32(winEr); 700 Assert(0); 701 /* just ensure we never return success in this case */ 702 Assert(hr != S_OK); 703 Assert(hr != S_FALSE); 704 if (hr == S_OK || hr == S_FALSE) 705 hr = E_FAIL; 706 VBoxRrRetryStop(); 707 break; 708 } 709 710 switch (Msg.message) 711 { 712 case WM_VBOXRR_INIT_QUIT: 713 case WM_CLOSE: 714 { 715 VBoxRrRetryStop(); 716 PostQuitMessage(0); 717 break; 718 } 719 default: 720 TranslateMessage(&Msg); 721 DispatchMessage(&Msg); 722 break; 723 } 724 } while (1); 725 return 0; 726 } 727 728 static DWORD WINAPI vboxRrRunnerThread(void *pvUser) 729 { 730 PVBOXRR pMon = &g_VBoxRr; 731 732 BOOL bRc = SetEvent(pMon->hEvent); 733 if (!bRc) 734 { 735 DWORD winErr = GetLastError(); 736 Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr)); 737 HRESULT tmpHr = HRESULT_FROM_WIN32(winErr); 738 Assert(tmpHr != S_OK); 739 } 740 741 HRESULT hr = vboxRrWndInit(); 742 Assert(hr == S_OK); 743 if (hr == S_OK) 744 { 745 hr = vboxRrRun(); 746 Assert(hr == S_OK); 747 748 vboxRrWndTerm(); 749 } 750 751 return 0; 752 } 753 754 HRESULT VBoxRrInit() 755 { 756 HRESULT hr = E_FAIL; 757 PVBOXRR pMon = &g_VBoxRr; 758 memset(pMon, 0, sizeof (*pMon)); 759 760 InitializeCriticalSection(&pMon->CritSect); 761 762 pMon->hEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes*/ 763 TRUE, /* BOOL bManualReset*/ 764 FALSE, /* BOOL bInitialState */ 765 NULL /* LPCTSTR lpName */ 766 ); 767 if (pMon->hEvent) 768 { 769 pMon->hThread = CreateThread(NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */, 770 0 /* SIZE_T dwStackSize */, 771 vboxRrRunnerThread, 772 pMon, 773 0 /* DWORD dwCreationFlags */, 774 &pMon->idThread); 775 if (pMon->hThread) 776 { 777 DWORD dwResult = WaitForSingleObject(pMon->hEvent, INFINITE); 778 if (dwResult == WAIT_OBJECT_0) 779 return S_OK; 780 else 781 { 782 Log(("WaitForSingleObject failed!")); 783 hr = E_FAIL; 784 } 785 } 786 else 787 { 788 DWORD winErr = GetLastError(); 789 Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr)); 790 hr = HRESULT_FROM_WIN32(winErr); 791 Assert(hr != S_OK); 792 } 793 CloseHandle(pMon->hEvent); 794 } 795 else 796 { 797 DWORD winErr = GetLastError(); 798 Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr)); 799 hr = HRESULT_FROM_WIN32(winErr); 800 Assert(hr != S_OK); 801 } 802 803 DeleteCriticalSection(&pMon->CritSect); 804 805 return hr; 806 } 807 808 VOID VBoxRrTerm() 809 { 810 HRESULT hr; 811 PVBOXRR pMon = &g_VBoxRr; 812 if (!pMon->hThread) 813 return; 814 815 BOOL bResult = PostThreadMessage(pMon->idThread, WM_VBOXRR_INIT_QUIT, 0, 0); 816 DWORD winErr; 817 if (bResult 818 || (winErr = GetLastError()) == ERROR_INVALID_THREAD_ID) /* <- could be that the thread is terminated */ 819 { 820 DWORD dwErr = WaitForSingleObject(pMon->hThread, INFINITE); 821 if (dwErr == WAIT_OBJECT_0) 822 { 823 hr = S_OK; 824 } 825 else 826 { 827 winErr = GetLastError(); 828 hr = HRESULT_FROM_WIN32(winErr); 829 } 830 } 831 else 832 { 833 hr = HRESULT_FROM_WIN32(winErr); 834 } 835 836 DeleteCriticalSection(&pMon->CritSect); 837 838 CloseHandle(pMon->hThread); 839 pMon->hThread = 0; 840 CloseHandle(pMon->hEvent); 841 pMon->hThread = 0; 842 } 843 /**/ 844 420 845 typedef struct VBOXDISPIF_WDDM_INTERNAL 421 846 { … … 538 963 return NO_ERROR; 539 964 540 DWORD winEr;541 965 LONG status = DISP_CHANGE_SUCCESSFUL; 542 966 … … 566 990 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL); 567 991 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", tmpStatus, GetLastError ())); 568 569 992 if (tmpStatus != DISP_CHANGE_SUCCESSFUL) 570 993 { … … 579 1002 { 580 1003 if (status == DISP_CHANGE_SUCCESSFUL) 581 {582 1004 return NO_ERROR; 583 } 584 tmpStatus = status; 585 } 586 587 winEr = ERROR_GEN_FAILURE; 588 return winEr; 1005 } 1006 else 1007 { 1008 if (status == DISP_CHANGE_SUCCESSFUL) 1009 status = tmpStatus; 1010 } 1011 1012 return status == DISP_CHANGE_FAILED ? ERROR_RETRY : ERROR_GEN_FAILURE; 589 1013 } 590 1014 … … 593 1017 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 594 1018 g_VBoxDispIfWddm.pIf = pIf; 595 return ERROR_SUCCESS; 1019 HRESULT hr = VBoxRrInit(); 1020 if (SUCCEEDED(hr)) 1021 { 1022 return ERROR_SUCCESS; 1023 } 1024 return ERROR_GEN_FAILURE; 596 1025 } 597 1026 598 1027 static void vboxDispIfWddmTerm(PCVBOXDISPIF pIf) 599 1028 { 1029 VBoxRrTerm(); 600 1030 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 601 1031 } … … 652 1082 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfReninitModesWDDMOp, &OpData); 653 1083 return err; 1084 } 1085 1086 DWORD vboxDispIfCancelPendingResizeWDDM(PCVBOXDISPIF const pIf) 1087 { 1088 VBoxRrRetryStop(); 1089 return NO_ERROR; 654 1090 } 655 1091 … … 735 1171 UINT i = 0; 736 1172 1173 VBoxRrRetryStop(); 1174 737 1175 for (; i < cDevModes; i++) 738 1176 { … … 833 1271 834 1272 Assert(winEr == NO_ERROR); 1273 } 1274 1275 if (winEr == ERROR_RETRY) 1276 { 1277 VBoxRrRetrySchedule(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1278 /* just pretend everything is fine so far */ 1279 winEr = NO_ERROR; 835 1280 } 836 1281 … … 857 1302 } 858 1303 1304 DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf) 1305 { 1306 switch (pIf->enmMode) 1307 { 1308 case VBOXDISPIF_MODE_XPDM_NT4: 1309 return NO_ERROR; 1310 case VBOXDISPIF_MODE_XPDM: 1311 return NO_ERROR; 1312 #ifdef VBOX_WITH_WDDM 1313 case VBOXDISPIF_MODE_WDDM: 1314 return vboxDispIfCancelPendingResizeWDDM(pIf); 1315 #endif 1316 default: 1317 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1318 return ERROR_INVALID_PARAMETER; 1319 } 1320 } 1321 859 1322 DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 860 1323 { -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h
r44528 r44550 86 86 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel); 87 87 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 88 DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf); 88 89 //DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r44528 r44550 376 376 ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); 377 377 DisplayDevice.cb = sizeof(DisplayDevice); 378 379 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf); 378 380 379 381 /* Find out how many display devices the system has */
Note:
See TracChangeset
for help on using the changeset viewer.