summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp')
-rw-r--r--src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp388
1 files changed, 311 insertions, 77 deletions
diff --git a/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp b/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
index b0c19261..a3473600 100644
--- a/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
+++ b/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -62,7 +62,7 @@ int VBoxDisplayInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStart
OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
GetVersionEx (&OSinfo);
- HMODULE hUser = GetModuleHandle("USER32");
+ HMODULE hUser = GetModuleHandle("user32.dll");
gCtx.pEnv = pEnv;
@@ -89,7 +89,8 @@ int VBoxDisplayInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStart
{
Log(("VBoxTray: VBoxDisplayInit: WDDM driver is installed, switching display driver if to WDDM mode\n"));
/* this is hacky, but the most easiest way */
- DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), VBOXDISPIF_MODE_WDDM, NULL /* old mode, we don't care about it */);
+ VBOXDISPIF_MODE enmMode = (OSinfo.dwMajorVersion > 6 || OSinfo.dwMinorVersion > 0) ? VBOXDISPIF_MODE_WDDM_W7 : VBOXDISPIF_MODE_WDDM;
+ DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */);
if (err == NO_ERROR)
Log(("VBoxTray: VBoxDisplayInit: DispIf switched to WDDM mode successfully\n"));
else
@@ -212,19 +213,108 @@ static bool isVBoxDisplayDriverActive(VBOXDISPLAYCONTEXT *pCtx)
#endif
}
-/* Returns TRUE to try again. */
-static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel,
- VBOXDISPLAYCONTEXT *pCtx)
+DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,
+ DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup)
{
- BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0);
+ DISPLAY_DEVICE displayDeviceTmp;
+ DISPLAY_DEVICE displayDevice;
+ DEVMODE deviceMode;
+ DWORD dwStatus = DISP_CHANGE_SUCCESSFUL;
+ DWORD iter ;
- if (!gCtx.fAnyX)
- Width &= 0xFFF8;
+ deviceMode = paDeviceModes[Id];
+ displayDevice = paDisplayDevices[Id];
+
+ for (iter = 0; iter < totalDispNum; iter++)
+ {
+ if (iter != 0 && iter != Id && !(paDisplayDevices[iter].StateFlags & DISPLAY_DEVICE_ACTIVE))
+ {
+ LogRel(("VBoxTray:Initially disabling the monitor with id = %d . Total Monitor=%d\n", iter, totalDispNum));
+ DEVMODE deviceModeTmp;
+ ZeroMemory(&deviceModeTmp, sizeof(DEVMODE));
+ deviceModeTmp.dmSize = sizeof(DEVMODE);
+ deviceModeTmp.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
+ | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
+ displayDeviceTmp = paDisplayDevices[iter];
+ gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
+ (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
+ }
+ }
+
+ if (fExtDispSup) /* Extended Display Support possible*/
+ {
+ if (fEnabled)
+ {
+ /* Special case for enabling the secondary monitor. */
+ if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
+ {
+ LogRel(("VBoxTray: Secondary Monitor with ID=%d and name=%s Not Enabled. Enabling it.\n", Id, displayDevice.DeviceName));
+ deviceMode.dmPosition.x = paDeviceModes[0].dmPelsWidth;
+ deviceMode.dmPosition.y = 0;
+ deviceMode.dmBitsPerPel = 32;
+ OSVERSIONINFO OSinfo;
+ OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
+ GetVersionEx (&OSinfo);
+
+ if (OSinfo.dwMajorVersion < 6)
+ /* dont any more flags here as, only DM_POISITON is used to enable the secondary display */
+ deviceMode.dmFields = DM_POSITION;
+ else /* for win 7 and above */
+ /* for vista and above DM_BITSPERPEL is necessary */
+ deviceMode.dmFields = DM_BITSPERPEL | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION;
+
+ dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,&deviceMode, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
+ /* A second call to ChangeDisplaySettings updates the monitor.*/
+ gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
+ }
+ else /* secondary monitor already enabled. Request to change the resolution or position. */
+ {
+ if (aWidth !=0 && aHeight != 0)
+ {
+ LogRel(("VBoxTray: Display : %s , Change Height: %d & Width: %d\n", displayDevice.DeviceName, aWidth, aHeight));
+ deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
+ | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
+ deviceMode.dmPelsWidth = aWidth;
+ deviceMode.dmPelsHeight = aHeight;
+ deviceMode.dmBitsPerPel = aBitsPerPixel;
+ }
+ if (aPosX != 0 || aPosY != 0)
+ {
+ LogRel(("VBoxTray: Display: %s PosX: %d, PosY: %d\n", displayDevice.DeviceName, aPosX, aPosY));
+ deviceMode.dmFields |= DM_POSITION;
+ deviceMode.dmPosition.x = aPosX;
+ deviceMode.dmPosition.y = aPosY;
+ }
+ dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
+ &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
+ /* A second call to ChangeDisplaySettings updates the monitor. */
+ gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
+ }
+ }
+ else /* Request is there to disable the monitor with ID = Id*/
+ {
+ LogRel(("VBoxTray: Disable the Display: %d\n", displayDevice.DeviceName));
+
+ DEVMODE deviceModeTmp;
+ ZeroMemory(&deviceModeTmp, sizeof(DEVMODE));
+ deviceModeTmp.dmSize = sizeof(DEVMODE);
+ deviceModeTmp.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
+ | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
+ displayDeviceTmp = paDisplayDevices[Id];
+ dwStatus = gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
+ (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
+ gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
+ }
+ }
+ return dwStatus;
+}
+DWORD VBoxGetDisplayConfigCount()
+{
DISPLAY_DEVICE DisplayDevice;
- ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
- DisplayDevice.cb = sizeof(DisplayDevice);
+ ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
+ DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
/* Find out how many display devices the system has */
DWORD NumDevices = 0;
@@ -250,26 +340,21 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
i++;
}
- Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ()));
-
- if (NumDevices == 0 || Id >= NumDevices)
- {
- Log(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ()));
- return FALSE;
- }
-
- DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices);
- DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices);
- RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices);
+ return NumDevices;
+}
+DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes)
+{
/* Fetch information about current devices and modes. */
DWORD DevNum = 0;
DWORD DevPrimaryNum = 0;
+ DISPLAY_DEVICE DisplayDevice;
+
ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
- i = 0;
+ DWORD i = 0;
while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
{
Log(("VBoxTray: ResizeDisplayDevice: [%d(%d)] %s\n", i, DevNum, DisplayDevice.DeviceName));
@@ -293,8 +378,8 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
{
if (DevNum >= NumDevices)
{
- Log(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum));
- return FALSE;
+ WARN(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum));
+ return ERROR_BUFFER_OVERFLOW;
}
paDisplayDevices[DevNum] = DisplayDevice;
@@ -309,7 +394,6 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
ENUM_REGISTRY_SETTINGS, &paDeviceModes[DevNum]))
{
Log(("VBoxTray: ResizeDisplayDevice: EnumDisplaySettings error %d\n", GetLastError ()));
- return FALSE;
}
if ( paDeviceModes[DevNum].dmPelsWidth == 0
@@ -328,21 +412,10 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
* Do not return here, ignore the error and set the display info to 0x0x0.
*/
Log(("VBoxTray: ResizeDisplayDevice: EnumDisplaySettings(ENUM_CURRENT_SETTINGS) error %d\n", GetLastError ()));
- ZeroMemory(&paDeviceModes[DevNum], sizeof(DEVMODE));
}
}
- Log(("VBoxTray: ResizeDisplayDevice: %dx%dx%d at %d,%d\n",
- paDeviceModes[DevNum].dmPelsWidth,
- paDeviceModes[DevNum].dmPelsHeight,
- paDeviceModes[DevNum].dmBitsPerPel,
- paDeviceModes[DevNum].dmPosition.x,
- paDeviceModes[DevNum].dmPosition.y));
-
- paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x;
- paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y;
- paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth;
- paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight;
+
DevNum++;
}
@@ -351,32 +424,146 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
i++;
}
+ *pNumDevices = DevNum;
+
+ return NO_ERROR;
+}
+
+/* Returns TRUE to try again. */
+static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel,
+ BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY,
+ VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup)
+{
+ BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */
+ BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 &&
+ dwNewPosX == 0 && dwNewPosY == 0);
+ DWORD dmFields = 0;
+
+ Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \
+ fEnabled = %d, fExtDisSup = %d\n",
+ Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));
+
+ if (!gCtx.fAnyX)
+ Width &= 0xFFF8;
+
+ VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);
+
+ DWORD NumDevices = VBoxGetDisplayConfigCount();
+
+ if (NumDevices == 0 || Id >= NumDevices)
+ {
+ WARN(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ()));
+ return FALSE;
+ }
+
+ Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ()));
+
+ DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices);
+ DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices);
+ RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices);
+ DWORD DevNum = 0;
+ DWORD DevPrimaryNum = 0;
+ DWORD dwStatus = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);
+ if (dwStatus != NO_ERROR)
+ {
+ WARN(("VBoxTray: ResizeDisplayDevice: VBoxGetDisplayConfig failed, %d\n", dwStatus));
+ return dwStatus;
+ }
+
+ if (NumDevices != DevNum)
+ WARN(("VBoxTray: ResizeDisplayDevice: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum));
+
+ DWORD i = 0;
+
+ for (i = 0; i < DevNum; ++i)
+ {
+ if (fExtDispSup)
+ {
+ LogRel(("VBoxTray: Extended Display Support.\n"));
+ Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n",
+ paDeviceModes[Id].dmPelsWidth,
+ paDeviceModes[Id].dmPelsHeight,
+ paDeviceModes[Id].dmBitsPerPel,
+ paDeviceModes[Id].dmPosition.x,
+ paDeviceModes[Id].dmPosition.y,
+ Id, DevNum, fEnabled));
+ }
+ else
+ {
+ LogRel(("VBoxTray: NO Ext Display Support \n"));
+ }
+
+ paRects[i].left = paDeviceModes[i].dmPosition.x;
+ paRects[i].top = paDeviceModes[i].dmPosition.y;
+ paRects[i].right = paDeviceModes[i].dmPosition.x + paDeviceModes[i].dmPelsWidth;
+ paRects[i].bottom = paDeviceModes[i].dmPosition.y + paDeviceModes[i].dmPelsHeight;
+ }
+
+ /* Keep a record if the display with ID is already active or not. */
+ if (paDisplayDevices[Id].StateFlags & DISPLAY_DEVICE_ACTIVE)
+ {
+ LogRel(("VBoxTray: Display with ID=%d already enabled\n", Id));
+ fDispAlreadyEnabled = TRUE;
+ }
+
/* Width, height equal to 0 means that this value must be not changed.
* Update input parameters if necessary.
* Note: BitsPerPixel is taken into account later, when new rectangles
* are assigned to displays.
*/
if (Width == 0)
- {
Width = paRects[Id].right - paRects[Id].left;
- }
+ else
+ dmFields |= DM_PELSWIDTH;
if (Height == 0)
- {
Height = paRects[Id].bottom - paRects[Id].top;
+ else
+ dmFields |= DM_PELSHEIGHT;
+
+ if (BitsPerPixel == 0)
+ BitsPerPixel = paDeviceModes[Id].dmBitsPerPel;
+ else
+ dmFields |= DM_BITSPERPEL;
+
+ if (!dwNewPosX && !dwNewPosY)
+ {
+ /* @fixme: zero position is a valid state, so another values should be used as a special case !!! */
+ dwNewPosX = paRects[Id].left;
+ dwNewPosY = paRects[Id].top;
}
+ else
+ dmFields |= DM_POSITION;
- /* Check whether a mode reset or a change is requested. */
- if ( !fModeReset
+ /* Check whether a mode reset or a change is requested.
+ * Rectangle position is recalculated only if fEnabled is 1.
+ * For non extended supported modes (old Host VMs), fEnabled
+ * is always 1.
+ */
+ /* Handled the case where previouseresolution of secondary monitor
+ * was for eg. 1024*768*32 and monitor was in disabled state.
+ * User gives the command
+ * setvideomode 1024 768 32 1 yes.
+ * Now in this case the resolution request is same as previous one but
+ * monitor is going from disabled to enabled state so the below condition
+ * shour return false
+ * The below condition will only return true , if no mode reset has
+ * been requested AND fEnabled is 1 and fDispAlreadyEnabled is also 1 AND
+ * all rect conditions are true. Thus in this case nothing has to be done.
+ */
+ if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled)
+ && paRects[Id].left == dwNewPosX
+ && paRects[Id].top == dwNewPosY
&& paRects[Id].right - paRects[Id].left == Width
&& paRects[Id].bottom - paRects[Id].top == Height
&& paDeviceModes[Id].dmBitsPerPel == BitsPerPixel)
{
- Log(("VBoxTray: ResizeDisplayDevice: Already at desired resolution\n"));
+ LogRel(("VBoxTray: Already at desired resolution. No Change.\n"));
return FALSE;
}
- hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height);
+ hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id,
+ fEnabled ? Width : 0, fEnabled ? Height : 0, dwNewPosX, dwNewPosY);
#ifdef Log
for (i = 0; i < NumDevices; i++)
{
@@ -399,35 +586,38 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
paDeviceModes[i].dmPelsWidth = paRects[i].right - paRects[i].left;
paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top;
+ if (i == Id)
+ paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
+
+ paDeviceModes[i].dmFields |= dmFields;
+
/* On Vista one must specify DM_BITSPERPEL.
* Note that the current mode dmBitsPerPel is already in the DEVMODE structure.
*/
- paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL;
-
- if ( i == Id
- && BitsPerPixel != 0)
+ if (!(paDeviceModes[i].dmFields & DM_BITSPERPEL))
{
- /* Change dmBitsPerPel if requested. */
- paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
+ WARN(("VBoxTray: (WDDM) no DM_BITSPERPEL\n"));
+ paDeviceModes[i].dmFields |= DM_BITSPERPEL;
+ paDeviceModes[i].dmBitsPerPel = 32;
}
- Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n",
+ Log(("VBoxTray: (WDDM) ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n",
gCtx.pfnChangeDisplaySettingsEx,
paDeviceModes[i].dmPelsWidth,
paDeviceModes[i].dmPelsHeight,
paDeviceModes[i].dmBitsPerPel,
paDeviceModes[i].dmPosition.x,
paDeviceModes[i].dmPosition.y));
-
}
- DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, paDisplayDevices, paDeviceModes, NumDevices);
+ Log(("VBoxTray: (WDDM) Request to resize the displa\n"));
+ DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, fEnabled, fExtDispSup, paDisplayDevices, paDeviceModes, DevNum);
if (err == NO_ERROR || err != ERROR_RETRY)
{
if (err == NO_ERROR)
Log(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n"));
else
- Log(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err));
+ WARN(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err));
return FALSE;
}
@@ -467,8 +657,8 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
}
- Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n",
- gCtx.pfnChangeDisplaySettingsEx,
+ Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx Current MonitorId=%d: %dx%dx%d at %d,%d\n",
+ i,
paDeviceModes[i].dmPelsWidth,
paDeviceModes[i].dmPelsHeight,
paDeviceModes[i].dmBitsPerPel,
@@ -480,15 +670,18 @@ static BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsP
Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", status, GetLastError ()));
}
- /* A second call to ChangeDisplaySettings updates the monitor. */
- LONG status = gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
- Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettings update status %d\n", status));
- if (status == DISP_CHANGE_SUCCESSFUL || status == DISP_CHANGE_BADMODE)
+ Log(("VBoxTray: Enable And Resize Device. Id = %d, Width=%d Height=%d, \
+ dwNewPosX = %d, dwNewPosY = %d fEnabled=%d & fExtDispSupport = %d \n",
+ Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));
+ dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel,
+ dwNewPosX, dwNewPosY, fEnabled, fExtDispSup);
+ if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE)
{
- /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */
+ /* Successfully set new video mode or our driver can not set
+ * the requested mode. Stop trying.
+ */
return FALSE;
}
-
/* Retry the request. */
return TRUE;
}
@@ -515,15 +708,13 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
return 0;
}
- int rc = VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
- if (RT_FAILURE(rc))
- {
- LogRel(("VBoxTray: VBoxDisplayThread: Failed to set the graphics capability with rc=%Rrc, thread exiting\n", rc));
- return 0;
- }
+ PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0);
+
+ VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf);
do
{
+ BOOL fExtDispSup = TRUE;
/* Wait for a display change event. */
VBoxGuestWaitEventInfo waitEvent;
waitEvent.u32TimeoutIn = 1000;
@@ -552,20 +743,44 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST)
{
Log(("VBoxTray: VBoxDisplayThread: going to get display change information\n"));
+ BOOL fDisplayChangeQueried;
+
/* We got at least one event. Read the requested resolution
* and try to set it until success. New events will not be seen
* but a new resolution will be read in this poll loop.
*/
- VMMDevDisplayChangeRequest2 displayChangeRequest = {0};
- displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequest2);
+ /* Try if extended mode display information is available from the host. */
+ VMMDevDisplayChangeRequestEx displayChangeRequest = {0};
+ fExtDispSup = TRUE;
+ displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequestEx);
displayChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
- displayChangeRequest.header.requestType = VMMDevReq_GetDisplayChangeRequest2;
+ displayChangeRequest.header.requestType = VMMDevReq_GetDisplayChangeRequestEx;
displayChangeRequest.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
- BOOL fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevDisplayChangeRequest2)), &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest2),
+ fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevDisplayChangeRequestEx)), &displayChangeRequest, sizeof(VMMDevDisplayChangeRequestEx),
+ &displayChangeRequest, sizeof(VMMDevDisplayChangeRequestEx), &cbReturned, NULL);
+
+ if (!fDisplayChangeQueried)
+ {
+ Log(("VBoxTray: Extended Display Not Supported. Trying VMMDevDisplayChangeRequest2\n"));
+ fExtDispSup = FALSE; /* Extended display Change request is not supported */
+
+ displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequest2);
+ displayChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ displayChangeRequest.header.requestType = VMMDevReq_GetDisplayChangeRequest2;
+ displayChangeRequest.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
+ fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevDisplayChangeRequest2)), &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest2),
&displayChangeRequest, sizeof(VMMDevDisplayChangeRequest2), &cbReturned, NULL);
+ displayChangeRequest.cxOrigin = 0;
+ displayChangeRequest.cyOrigin = 0;
+ displayChangeRequest.fChangeOrigin = 0;
+ displayChangeRequest.fEnabled = 1; /* Always Enabled for old VMs on Host.*/
+ }
+
if (!fDisplayChangeQueried)
{
+ Log(("VBoxTray: Extended Display Not Supported. Trying VMMDevDisplayChangeRequest\n"));
+ fExtDispSup = FALSE; /*Extended display Change request is not supported */
/* Try the old version of the request for old VBox hosts. */
displayChangeRequest.header.size = sizeof(VMMDevDisplayChangeRequest);
displayChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
@@ -574,6 +789,10 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
fDisplayChangeQueried = DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevDisplayChangeRequest)), &displayChangeRequest, sizeof(VMMDevDisplayChangeRequest),
&displayChangeRequest, sizeof(VMMDevDisplayChangeRequest), &cbReturned, NULL);
displayChangeRequest.display = 0;
+ displayChangeRequest.cxOrigin = 0;
+ displayChangeRequest.cyOrigin = 0;
+ displayChangeRequest.fChangeOrigin = 0;
+ displayChangeRequest.fEnabled = 1; /* Always Enabled for old VMs on Host.*/
}
if (fDisplayChangeQueried)
@@ -602,17 +821,31 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
if (pCtx->pfnChangeDisplaySettingsEx != 0)
{
Log(("VBoxTray: VBoxDisplayThread: Detected W2K or later\n"));
-
/* W2K or later. */
+ Log(("DisplayChangeReqEx parameters aDisplay=%d x xRes=%d x yRes=%d x bpp=%d x SecondayMonEnb=%d x NewOriginX=%d x NewOriginY=%d x ChangeOrigin=%d\n",
+ displayChangeRequest.display,
+ displayChangeRequest.xres,
+ displayChangeRequest.yres,
+ displayChangeRequest.bpp,
+ displayChangeRequest.fEnabled,
+ displayChangeRequest.cxOrigin,
+ displayChangeRequest.cyOrigin,
+ displayChangeRequest.fChangeOrigin));
if (!ResizeDisplayDevice(displayChangeRequest.display,
displayChangeRequest.xres,
displayChangeRequest.yres,
displayChangeRequest.bpp,
- pCtx
+ displayChangeRequest.fEnabled,
+ displayChangeRequest.cxOrigin,
+ displayChangeRequest.cyOrigin,
+ pCtx,
+ fExtDispSup
))
{
+ Log(("ResizeDipspalyDevice return 0\n"));
break;
}
+
}
else
{
@@ -727,7 +960,8 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
}
if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED)
hlpReloadCursor();
- } else
+ }
+ else
{
Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
/* sleep a bit to not eat too much CPU in case the above call always fails */
@@ -746,7 +980,7 @@ unsigned __stdcall VBoxDisplayThread(void *pInstance)
maskInfo.u32NotMask = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED;
if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
Log(("VBoxTray: VBoxDisplayThread: DeviceIOControl(CtlMask - not) failed\n"));
- VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
+ PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_UNSUPPORTED, 0, 0);
Log(("VBoxTray: VBoxDisplayThread: finished display change request thread\n"));
return 0;