VirtualBox

Ignore:
Timestamp:
Feb 12, 2013 10:54:41 AM (12 years ago)
Author:
vboxsync
Message:

WINNT/VBoxTray/VBoxDisplay: Added multi-monitor support for XP XPDM .
Fixed the issue related to enumeration of pseudo monitors . Only actual secondary monitors should be considered in the enumeration process and pseudo monitors should be excluded.
Fixed the issue related to virtual secondary monitor getting disabled on resizing.
Code optimization done to prevent repeated enumeration of secondary monitors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp

    r44578 r44648  
    213213}
    214214
    215 static DWORD EnableAndResizeDispDev(ULONG Id, DWORD aWidth, DWORD aHeight,
    216                                     DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY,
    217                                     BOOL fEnabled, BOOL fExtDispSup,
    218                                     VBOXDISPLAYCONTEXT *pCtx)
     215static DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, ULONG Id, DWORD aWidth, DWORD aHeight,
     216                                    DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup, VBOXDISPLAYCONTEXT *pCtx)
    219217{
    220218    DISPLAY_DEVICE displayDeviceTmp;
    221219    DISPLAY_DEVICE displayDevice;
    222     DEVMODE devModePrimary;
    223220    DEVMODE deviceMode;
    224     DWORD DispNum = 0;
    225221    DWORD dwStatus = DISP_CHANGE_SUCCESSFUL;
    226 
    227     ZeroMemory(&displayDeviceTmp, sizeof(DISPLAY_DEVICE));
    228     displayDeviceTmp.cb = sizeof(DISPLAY_DEVICE);
    229 
    230     Log(("EnableDisplayDevice Id=%d, width=%d height=%d \
    231          PosX = %d PosY = %d fEnabled = %d & fExtDisSup = %d \n",
    232          Id, aWidth, aHeight, aPosX, aPosY, fEnabled, fExtDispSup));
    233 
    234     /* Disable all the devices leaving the device with ID == Id and
    235      * primary device.
    236      */
    237     while (EnumDisplayDevices(NULL, DispNum, &displayDeviceTmp, 0))
    238     {
    239         /* Displays which are configured but not enabled, update their
    240          * registry entries for parameters width , height, posX and
    241          * posY as 0. This is done so that they are not enabled when
    242          * ChangeDisplaySettings(NULL) is called .
    243          * Dont disable the primary monitor or the monitor whose resolution
    244          * needs to be changed i.e the monitor with ID = Id.
    245          */
    246         if (DispNum != 0 && DispNum != Id)
    247         {
     222    DWORD iter ;
     223
     224    deviceMode = paDeviceModes[Id];
     225    displayDevice = paDisplayDevices[Id];
     226
     227    for (iter = 0; iter < totalDispNum; iter++)
     228    {
     229        if (iter != 0 && iter != Id && !(paDisplayDevices[iter].StateFlags & DISPLAY_DEVICE_ACTIVE))
     230        {
     231            LogRel(("VBoxTray:Initially disabling the monitor with id = %d . Total Monitor=%d\n", iter, totalDispNum));
    248232            DEVMODE deviceModeTmp;
    249233            ZeroMemory(&deviceModeTmp, sizeof(DEVMODE));
     
    251235            deviceModeTmp.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
    252236                                     | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
     237            displayDeviceTmp = paDisplayDevices[iter];
    253238            gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
    254239                                           (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
    255240        }
    256         DispNum++;
    257     }
    258 
    259     ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
    260     displayDevice.cb = sizeof(DISPLAY_DEVICE);
    261     DispNum = 0;
    262     while (EnumDisplayDevices(NULL, DispNum, &displayDevice, 0))
    263     {
    264         ZeroMemory(&deviceMode, sizeof(DEVMODE));
    265         deviceMode.dmSize = sizeof(DEVMODE);
    266         if (!EnumDisplaySettings((LPSTR)displayDevice.DeviceName,
    267              ENUM_REGISTRY_SETTINGS, &deviceMode))
    268         {
    269             LogRel(("VBoxTray: ENUM_REGISTRY_SETTINGS Failed \n"));
    270             return DISP_CHANGE_FAILED; // Store default failed
    271         }
    272         /* Save info about primary display */
    273         if(DispNum == 0)
    274             devModePrimary = deviceMode;
    275 
    276         if (DispNum == Id)
    277         {
    278             if (fExtDispSup) /* Extended Display Support possible*/
    279             {
    280                 if (fEnabled)
    281                 {
    282                     /* Special case for enabling the secondary monitor. */
    283                     if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
    284                     {
    285                         LogRel(("VBoxTray: Secondary Monitor with ID=%d Not Enabled. Enabling it.\n", DispNum));
    286                         deviceMode.dmPosition.x = devModePrimary.dmPelsWidth;
    287                         deviceMode.dmPosition.y = 0;
    288                         /* dont any more flags here as, only DM_POISITON is used to enable the secondary display */
    289                         deviceMode.dmFields = DM_POSITION;
    290                         gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
    291                                                                   &deviceMode, NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
    292                         /* A second call to ChangeDisplaySettings updates the monitor.*/
    293                         gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    294                         /* shouln't retry in case of enabling or disabling the display device. */
    295                         dwStatus = DISP_CHANGE_SUCCESSFUL;
    296                     }
    297                     else /* secondary monitor already enabled. Request to change the resolution or position. */
    298                     {
    299                         if (aWidth !=0 && aHeight != 0)
    300                         {
    301                             LogRel(("VBoxTray: Display ID: %d , Change Height: %d & Width: %d\n", Id, aWidth, aHeight));
    302                             deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
    303                                                   | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
    304                             deviceMode.dmPelsWidth = aWidth;
    305                             deviceMode.dmPelsHeight = aHeight;
    306                             deviceMode.dmBitsPerPel = aBitsPerPixel;
    307                         }
    308                         if (aPosX != 0 || aPosY != 0)
    309                         {
    310                             LogRel(("VBoxTray: Display ID: %d PosX: %d, PosY: %d\n",
    311                                     Id, aPosX, aPosY));
    312                             deviceMode.dmFields |=  DM_POSITION;
    313                             deviceMode.dmPosition.x = aPosX;
    314                             deviceMode.dmPosition.y = aPosY;
    315                         }
    316                         dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
    317                                                                    &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
    318                          /* A second call to ChangeDisplaySettings updates the monitor. */
    319                         gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    320                     }
    321                 }
    322                 else /* Request is there to disable the monitor with ID = Id*/
    323                 {
    324                     LogRel(("VBoxTray: Disable the Display ID: %d\n", Id));
    325                     ZeroMemory(&deviceMode, sizeof(DEVMODE));
    326                     deviceMode.dmSize = sizeof(DEVMODE);
    327                     deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
    328                                           | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
    329                     dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
    330                                                                &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
    331                     /* A second call to ChangeDisplaySettings updates the monitor. */
    332                     gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    333                 }
    334                 break;
    335             }
    336             else/* Extended display support not possible. Just change the res.*/
     241    }
     242
     243    if (fExtDispSup) /* Extended Display Support possible*/
     244    {
     245        if (fEnabled)
     246        {
     247            /* Special case for enabling the secondary monitor. */
     248            if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
     249            {
     250                LogRel(("VBoxTray: Secondary Monitor with ID=%d and name=%s Not Enabled. Enabling it.\n", Id, displayDevice.DeviceName));
     251                deviceMode.dmPosition.x = paDeviceModes[0].dmPelsWidth;
     252                deviceMode.dmPosition.y = 0;
     253                deviceMode.dmBitsPerPel = 32;
     254                OSVERSIONINFO OSinfo;
     255                OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
     256                GetVersionEx (&OSinfo);
     257
     258                if (OSinfo.dwMajorVersion < 6)
     259                    /* dont any more flags here as, only DM_POISITON is used to enable the secondary display */
     260                    deviceMode.dmFields = DM_POSITION;
     261                else /* for win 7 and above */
     262                    /* for vista and aboce DM_BITSPERPELis necessary */
     263                    deviceMode.dmFields =   DM_BITSPERPEL | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY  | DM_POSITION;
     264
     265                dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,&deviceMode, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
     266                /* A second call to ChangeDisplaySettings updates the monitor.*/
     267                gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     268            }
     269            else /* secondary monitor already enabled. Request to change the resolution or position. */
    337270            {
    338271                if (aWidth !=0 && aHeight != 0)
    339272                {
    340                     LogRel(("VBoxTray: No Extended Display Support. Just Change Resolution. \
    341                             Display ID = %d, Width = %d, Height = %d\n",Id, aWidth, aHeight));
    342                     deviceMode.dmFields |=  DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL ;
     273                    LogRel(("VBoxTray: Display : %s , Change Height: %d & Width: %d\n", displayDevice.DeviceName, aWidth, aHeight));
     274                    deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
     275                                          | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
    343276                    deviceMode.dmPelsWidth = aWidth;
    344277                    deviceMode.dmPelsHeight = aHeight;
    345278                    deviceMode.dmBitsPerPel = aBitsPerPixel;
    346                     dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
    347                                                                 &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
    348                     /* A second call to ChangeDisplaySettings updates the monitor. */
    349                     gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    350279                }
    351             }
    352             break;
    353         }
    354         ZeroMemory(&displayDevice, sizeof(displayDevice));
    355         displayDevice.cb = sizeof(displayDevice);
    356         DispNum++;
     280                if (aPosX != 0 || aPosY != 0)
     281                {
     282                    LogRel(("VBoxTray: Display: %s PosX: %d, PosY: %d\n", displayDevice.DeviceName, aPosX, aPosY));
     283                    deviceMode.dmFields |=  DM_POSITION;
     284                    deviceMode.dmPosition.x = aPosX;
     285                    deviceMode.dmPosition.y = aPosY;
     286                }
     287                dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
     288                                                   &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
     289                /* A second call to ChangeDisplaySettings updates the monitor. */
     290                gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     291            }
     292        }
     293        else /* Request is there to disable the monitor with ID = Id*/
     294        {
     295            LogRel(("VBoxTray: Disable the Display: %d\n", displayDevice.DeviceName));
     296
     297            DEVMODE deviceModeTmp;
     298            ZeroMemory(&deviceModeTmp, sizeof(DEVMODE));
     299            deviceModeTmp.dmSize = sizeof(DEVMODE);
     300            deviceModeTmp.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
     301                                     | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
     302            displayDeviceTmp = paDisplayDevices[Id];
     303            dwStatus = gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
     304                                           (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
     305            gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     306        }
    357307    }
    358308    return dwStatus;
     
    666616              {
    667617                  /* use traditional approach of ChangeDisplaySettingEx to enable/disable secondary monitor for Vista WDDM mode.*/
    668                   dwStatus = EnableAndResizeDispDev(Id, Width, Height, BitsPerPixel,
    669                                       dwNewPosX, dwNewPosY,fEnabled,
    670                                       fExtDispSup, pCtx);
     618                  dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum,  Id, Width, Height, BitsPerPixel,
     619                                                    dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx);
    671620                  if (dwStatus != DISP_CHANGE_SUCCESSFUL )
    672621                  {
     
    745694         dwNewPosX = %d, dwNewPosY = %d fEnabled=%d & fExtDispSupport = %d \n",
    746695         Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));
    747     dwStatus = EnableAndResizeDispDev(Id, Width, Height, BitsPerPixel,
    748                                       dwNewPosX, dwNewPosY,fEnabled,
    749                                       fExtDispSup, pCtx);
     696    dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel,
     697                                      dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx);
    750698    if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE)
    751699    {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette