Changeset 48070 in vbox for trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
- Timestamp:
- Aug 26, 2013 6:13:22 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r48030 r48070 90 90 Log(("VBoxTray: VBoxDisplayInit: WDDM driver is installed, switching display driver if to WDDM mode\n")); 91 91 /* this is hacky, but the most easiest way */ 92 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), VBOXDISPIF_MODE_WDDM, NULL /* old mode, we don't care about it */); 92 VBOXDISPIF_MODE enmMode = (OSinfo.dwMajorVersion > 6 || OSinfo.dwMinorVersion > 0) ? VBOXDISPIF_MODE_WDDM_W7 : VBOXDISPIF_MODE_WDDM; 93 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */); 93 94 if (err == NO_ERROR) 94 95 Log(("VBoxTray: VBoxDisplayInit: DispIf switched to WDDM mode successfully\n")); … … 213 214 } 214 215 215 staticDWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,216 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup , VBOXDISPLAYCONTEXT *pCtx)216 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight, 217 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup) 217 218 { 218 219 DISPLAY_DEVICE displayDeviceTmp; … … 307 308 } 308 309 return dwStatus; 309 } 310 311 /* Returns TRUE to try again. */ 312 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 313 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 314 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 310 } 311 312 DWORD VBoxGetDisplayConfigCount() 315 313 { 316 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */317 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 &&318 dwNewPosX == 0 && dwNewPosY == 0);319 BOOL fChangePosRequest = false; /* change in position requested */320 321 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \322 fEnabled = %d, fExtDisSup = %d\n",323 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));324 325 if (!gCtx.fAnyX)326 Width &= 0xFFF8;327 328 314 DISPLAY_DEVICE DisplayDevice; 329 DWORD dwStatus;330 315 331 316 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 332 317 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 333 334 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);335 318 336 319 /* Find out how many display devices the system has */ … … 358 341 } 359 342 360 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 361 362 if (NumDevices == 0 || Id >= NumDevices) 363 { 364 Log(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 365 return FALSE; 366 } 367 368 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 369 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 370 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 371 343 return NumDevices; 344 } 345 346 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes) 347 { 372 348 /* Fetch information about current devices and modes. */ 373 349 DWORD DevNum = 0; 374 350 DWORD DevPrimaryNum = 0; 375 351 352 DISPLAY_DEVICE DisplayDevice; 353 376 354 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 377 355 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 378 356 379 i = 0;357 DWORD i = 0; 380 358 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0)) 381 359 { … … 401 379 if (DevNum >= NumDevices) 402 380 { 403 Log(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum));404 return FALSE;381 WARN(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum)); 382 return ERROR_BUFFER_OVERFLOW; 405 383 } 406 384 … … 438 416 } 439 417 440 if (fExtDispSup) 441 { 442 LogRel(("VBoxTray: Extended Display Support.\n")); 443 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 444 paDeviceModes[Id].dmPelsWidth, 445 paDeviceModes[Id].dmPelsHeight, 446 paDeviceModes[Id].dmBitsPerPel, 447 paDeviceModes[Id].dmPosition.x, 448 paDeviceModes[Id].dmPosition.y, 449 Id, DevNum, fEnabled)); 450 if ((DevNum == Id && fEnabled == 1)) 451 { 452 /* Calculation of new position for enabled 453 * secondary monitor . 454 */ 455 /* Used when a secondary monitor just needs to be enabled, without any 456 * change in its position 457 */ 458 if (dwNewPosX != 0) 459 { 460 LogRel(("VBoxTray: Setting Rectangle position x=%d*y=%d\n", dwNewPosX, dwNewPosY)); 461 paDeviceModes[DevNum].dmPosition.x = dwNewPosX; 462 paDeviceModes[DevNum].dmPosition.y = dwNewPosY; 463 fChangePosRequest = true; 464 } 465 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 466 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 467 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 468 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 469 } 470 else 471 { 472 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 473 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 474 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 475 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 476 } 477 } 478 else 479 { 480 LogRel(("VBoxTray: NO Ext Display Support \n")); 481 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 482 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 483 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 484 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 485 } 418 486 419 DevNum++; 487 420 } … … 491 424 i++; 492 425 } 426 427 *pNumDevices = DevNum; 428 429 return NO_ERROR; 430 } 431 432 /* Returns TRUE to try again. */ 433 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 434 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 435 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 436 { 437 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */ 438 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 && 439 dwNewPosX == 0 && dwNewPosY == 0); 440 DWORD dmFields = 0; 441 442 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \ 443 fEnabled = %d, fExtDisSup = %d\n", 444 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 445 446 if (!gCtx.fAnyX) 447 Width &= 0xFFF8; 448 449 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf); 450 451 DWORD NumDevices = VBoxGetDisplayConfigCount(); 452 453 if (NumDevices == 0 || Id >= NumDevices) 454 { 455 WARN(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 456 return FALSE; 457 } 458 459 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 460 461 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 462 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 463 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 464 DWORD DevNum = 0; 465 DWORD DevPrimaryNum = 0; 466 DWORD dwStatus = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 467 if (dwStatus != NO_ERROR) 468 { 469 WARN(("VBoxTray: ResizeDisplayDevice: VBoxGetDisplayConfig failed, %d\n", dwStatus)); 470 return dwStatus; 471 } 472 473 if (NumDevices != DevNum) 474 WARN(("VBoxTray: ResizeDisplayDevice: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum)); 475 476 DWORD i = 0; 477 478 for (i = 0; i < DevNum; ++i) 479 { 480 if (fExtDispSup) 481 { 482 LogRel(("VBoxTray: Extended Display Support.\n")); 483 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 484 paDeviceModes[Id].dmPelsWidth, 485 paDeviceModes[Id].dmPelsHeight, 486 paDeviceModes[Id].dmBitsPerPel, 487 paDeviceModes[Id].dmPosition.x, 488 paDeviceModes[Id].dmPosition.y, 489 Id, DevNum, fEnabled)); 490 } 491 else 492 { 493 LogRel(("VBoxTray: NO Ext Display Support \n")); 494 } 495 496 paRects[i].left = paDeviceModes[i].dmPosition.x; 497 paRects[i].top = paDeviceModes[i].dmPosition.y; 498 paRects[i].right = paDeviceModes[i].dmPosition.x + paDeviceModes[i].dmPelsWidth; 499 paRects[i].bottom = paDeviceModes[i].dmPosition.y + paDeviceModes[i].dmPelsHeight; 500 } 501 493 502 /* Keep a record if the display with ID is already active or not. */ 494 503 if (paDisplayDevices[Id].StateFlags & DISPLAY_DEVICE_ACTIVE) … … 504 513 */ 505 514 if (Width == 0) 506 {507 515 Width = paRects[Id].right - paRects[Id].left; 508 } 516 else 517 dmFields |= DM_PELSWIDTH; 509 518 510 519 if (Height == 0) 511 {512 520 Height = paRects[Id].bottom - paRects[Id].top; 513 } 521 else 522 dmFields |= DM_PELSHEIGHT; 523 524 if (BitsPerPixel == 0) 525 BitsPerPixel = paDeviceModes[Id].dmBitsPerPel; 526 else 527 dmFields |= DM_BITSPERPEL; 528 529 if (!dwNewPosX && !dwNewPosY) 530 { 531 /* @fixme: zero position is a valid state, so another values should be used as a special case !!! */ 532 dwNewPosX = paRects[Id].left; 533 dwNewPosY = paRects[Id].top; 534 } 535 else 536 dmFields |= DM_POSITION; 514 537 515 538 /* Check whether a mode reset or a change is requested. … … 529 552 * all rect conditions are true. Thus in this case nothing has to be done. 530 553 */ 531 if ( !fModeReset && fEnabled && fDispAlreadyEnabled && !fChangePosRequest 554 if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled) 555 && paRects[Id].left == dwNewPosX 556 && paRects[Id].top == dwNewPosY 532 557 && paRects[Id].right - paRects[Id].left == Width 533 558 && paRects[Id].bottom - paRects[Id].top == Height … … 538 563 } 539 564 540 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height); 565 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, 566 fEnabled ? Width : 0, fEnabled ? Height : 0, dwNewPosX, dwNewPosY); 541 567 #ifdef Log 542 568 for (i = 0; i < NumDevices; i++) … … 561 587 paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top; 562 588 589 if (i == Id) 590 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 591 592 paDeviceModes[i].dmFields |= dmFields; 593 563 594 /* On Vista one must specify DM_BITSPERPEL. 564 595 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure. 565 596 */ 566 paDeviceModes[i].dmFields = DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL; 567 568 if (i == Id && BitsPerPixel != 0) 597 if (!(paDeviceModes[i].dmFields & DM_BITSPERPEL)) 569 598 { 570 LogRel(("VBoxTray: (WDDM)Changing resolution and position. \n")); 571 /* Change dmBitsPerPel if requested. */ 572 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 573 paDeviceModes[i].dmPelsWidth = Width; 574 paDeviceModes[i].dmPelsHeight = Height; 575 if (dwNewPosX != 0 || dwNewPosY != 0) 576 { 577 paDeviceModes[Id].dmPosition.x = dwNewPosX; 578 paDeviceModes[Id].dmPosition.y = dwNewPosY; 579 } 580 else 581 { 582 paDeviceModes[i].dmFields |= DM_POSITION; 583 paDeviceModes[Id].dmPosition.x = 0; 584 paDeviceModes[Id].dmPosition.y = 0; 585 } 599 WARN(("VBoxTray: (WDDM) no DM_BITSPERPEL\n")); 600 paDeviceModes[i].dmFields |= DM_BITSPERPEL; 601 paDeviceModes[i].dmBitsPerPel = 32; 586 602 } 587 603 … … 593 609 paDeviceModes[i].dmPosition.x, 594 610 paDeviceModes[i].dmPosition.y)); 595 596 } 597 /* Reques to enable /disable the secondary Display Device. Won't take the resize request now.*/ 598 if (!fDispAlreadyEnabled && fEnabled || fDispAlreadyEnabled && !fEnabled) 599 { 600 OSVERSIONINFO OSinfo; 601 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 602 GetVersionEx (&OSinfo); 603 604 /* for win 7 and above */ 605 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 606 { 607 LogRel(("VBoxTray: (WDDM) Request to enable/disable %d display device\n", fEnabled)); 608 DWORD dwStatus = vboxDispIfWddmEnableDisplay(&pCtx->pEnv->dispIf, Id, RT_BOOL(fEnabled)); 609 if(dwStatus != ERROR_SUCCESS) 610 { 611 /* Not going to retry for enabling or disabling of the secondary display device.*/ 612 LogRel(("VBoxTray: (WDDM) Failed to enable the Display Device \n")); 613 } 614 } 615 else /* case: vista in wddm mode. SetDisplayConfig APIs etc is not avilable in this mode. */ 616 { 617 /* use traditional approach of ChangeDisplaySettingEx to enable/disable secondary monitor for Vista WDDM mode.*/ 618 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 619 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx); 620 if (dwStatus != DISP_CHANGE_SUCCESSFUL ) 621 { 622 /* Successfully set new video mode or our driver can not set 623 * the requested mode. Stop trying. 624 */ 625 LogRel(("VBoxTray: (WDDM) Failed to enable/disable the Display Device \n")); 626 } 627 } 628 return FALSE; /* for enable disable not retrying */ 629 } 630 else 631 { 632 /* Resize request. Secondary display device should be in an enabled state. */ 633 LogRel(("VBoxTray: (WDDM) Request to resize the display \n")); 634 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, paDisplayDevices, paDeviceModes, NumDevices); 635 if (err == NO_ERROR || err != ERROR_RETRY) 636 { 637 if (err == NO_ERROR) 638 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 639 else 640 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 641 return FALSE; 642 } 643 } 611 } 612 613 Log(("VBoxTray: (WDDM) Request to resize the displa\n")); 614 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, fEnabled, fExtDispSup, paDisplayDevices, paDeviceModes, DevNum); 615 if (err == NO_ERROR || err != ERROR_RETRY) 616 { 617 if (err == NO_ERROR) 618 Log(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 619 else 620 WARN(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 621 return FALSE; 622 } 623 644 624 Log(("VBoxTray: ResizeDisplayDevice: (WDDM) RETRY requested\n")); 645 625 return TRUE; … … 695 675 Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 696 676 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 697 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup , pCtx);677 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup); 698 678 if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE) 699 679 { … … 730 710 731 711 PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0); 712 713 VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf); 732 714 733 715 do … … 979 961 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED) 980 962 hlpReloadCursor(); 981 } else 963 } 964 else 982 965 { 983 966 Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
Note:
See TracChangeset
for help on using the changeset viewer.