X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=win32ss%2Fuser%2Fntuser%2Fdisplay.c;h=8ef37c9c4b95c048e54cbc685ce39c19dfde1434;hp=350f49717ff7a96ac500c89774f65df39fe67441;hb=fb4a6e38c7c6e3db13fb07222d813ca979d17b18;hpb=1e1a59fb221290185a3c33f2fa75ba42a650faf4 diff --git a/win32ss/user/ntuser/display.c b/win32ss/user/ntuser/display.c index 350f49717ff..8ef37c9c4b9 100644 --- a/win32ss/user/ntuser/display.c +++ b/win32ss/user/ntuser/display.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Video initialization and display settings - * FILE: subsystems/win32/win32k/ntuser/display.c + * FILE: win32ss/user/ntuser/display.c * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */ @@ -10,6 +10,7 @@ DBG_DEFAULT_CHANNEL(UserDisplay); BOOL gbBaseVideo = 0; +static PPROCESSINFO gpFullscreen = NULL; static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO"; @@ -75,8 +76,8 @@ InitDisplayDriver( DEVMODEW dmDefault; DWORD dwVga; - ERR("InitDisplayDriver(%S, %S);\n", - pwszDeviceName, pwszRegKey); + TRACE("InitDisplayDriver(%S, %S);\n", + pwszDeviceName, pwszRegKey); /* Open the driver's registry key */ Status = RegOpenKey(pwszRegKey, &hkey); @@ -152,7 +153,7 @@ InitDisplayDriver( NTSTATUS NTAPI -InitVideo() +InitVideo(VOID) { ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0; WCHAR awcDeviceName[20]; @@ -168,7 +169,7 @@ InitVideo() Status = RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control", &hkey); if (NT_SUCCESS(Status)) { - cbValue = 256; + cbValue = sizeof(awcBuffer); Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer, &cbValue); if (NT_SUCCESS(Status)) { @@ -187,17 +188,17 @@ InitVideo() Status = RegOpenKey(KEY_VIDEO, &hkey); if (!NT_SUCCESS(Status)) { - ERR("Could not open device registry key!\n"); + ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key:0x%lx\n", Status); return Status; } /* Read the name of the VGA adapter */ - cbValue = 20; + cbValue = sizeof(awcDeviceName); Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue); if (NT_SUCCESS(Status)) { - iVGACompatible = _wtoi(&awcDeviceName[13]); - ERR("VGA adapter = %ld\n", iVGACompatible); + iVGACompatible = _wtoi(&awcDeviceName[sizeof("\\Device\\Video")-1]); + ERR("VGA adapter = %lu\n", iVGACompatible); } /* Get the maximum mumber of adapters */ @@ -206,7 +207,7 @@ InitVideo() ERR("Could not read MaxObjectNumber, defaulting to 0.\n"); } - TRACE("Found %ld devices\n", ulMaxObjectNumber + 1); + TRACE("Found %lu devices\n", ulMaxObjectNumber + 1); /* Loop through all adapters */ for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++) @@ -350,8 +351,8 @@ NtUserEnumDisplayDevices( DISPLAY_DEVICEW dispdev; NTSTATUS Status; - TRACE("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n", - pustrDevice, iDevNum); + TRACE("Enter NtUserEnumDisplayDevices(%wZ, %lu)\n", + pustrDevice, iDevNum); dispdev.cb = sizeof(dispdev); @@ -442,7 +443,7 @@ UserEnumCurrentDisplaySettings( { /* No device found */ ERR("No PDEV found!\n"); - return STATUS_UNSUCCESSFUL; + return STATUS_INVALID_PARAMETER_1; } *ppdm = ppdev->pdmwDev; @@ -462,22 +463,27 @@ UserEnumDisplaySettings( PGRAPHICS_DEVICE pGraphicsDevice; PDEVMODEENTRY pdmentry; ULONG i, iFoundMode; + PPDEVOBJ ppdev; - TRACE("Enter UserEnumDisplaySettings('%wZ', %ld)\n", - pustrDevice, iModeNum); + TRACE("Enter UserEnumDisplaySettings('%wZ', %lu)\n", + pustrDevice, iModeNum); /* Ask GDI for the GRAPHICS_DEVICE */ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0); + ppdev = EngpGetPDEV(pustrDevice); - if (!pGraphicsDevice) + if (!pGraphicsDevice || !ppdev) { /* No device found */ ERR("No device found!\n"); - return STATUS_UNSUCCESSFUL; + return STATUS_INVALID_PARAMETER_1; } - if (iModeNum >= pGraphicsDevice->cDevModes) - return STATUS_NO_MORE_ENTRIES; + /* let's politely ask the driver for an updated mode list, + just in case there's something new in there (vbox) */ + + PDEVOBJ_vRefreshModeList(ppdev); + PDEVOBJ_vRelease(ppdev); iFoundMode = 0; for (i = 0; i < pGraphicsDevice->cDevModes; i++) @@ -503,7 +509,7 @@ UserEnumDisplaySettings( } /* Nothing was found */ - return STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER_2; } NTSTATUS @@ -568,8 +574,28 @@ NtUserEnumDisplaySettings( ULONG cbSize, cbExtra; DEVMODEW dmReg, *pdm; - TRACE("Enter NtUserEnumDisplaySettings(%wZ, %ld, %p, 0x%lx)\n", - pustrDevice, iModeNum, lpDevMode, dwFlags); + TRACE("Enter NtUserEnumDisplaySettings(%wZ, %lu, %p, 0x%lx)\n", + pustrDevice, iModeNum, lpDevMode, dwFlags); + + _SEH2_TRY + { + ProbeForRead(lpDevMode, sizeof(DEVMODEW), sizeof(UCHAR)); + + cbSize = lpDevMode->dmSize; + cbExtra = lpDevMode->dmDriverExtra; + + ProbeForWrite(lpDevMode, cbSize + cbExtra, sizeof(UCHAR)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + if (lpDevMode->dmSize != sizeof(DEVMODEW)) + { + return STATUS_BUFFER_TOO_SMALL; + } if (pustrDevice) { @@ -579,20 +605,24 @@ NtUserEnumDisplaySettings( _SEH2_TRY { /* Probe the UNICODE_STRING and the buffer */ - ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); - ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); + ProbeForReadUnicodeString(pustrDevice); + + if (!pustrDevice->Length || !pustrDevice->Buffer) + ExRaiseStatus(STATUS_NO_MEMORY); + + ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, sizeof(UCHAR)); /* Copy the string */ RtlCopyUnicodeString(&ustrDevice, pustrDevice); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + _SEH2_YIELD(return STATUS_INVALID_PARAMETER_1); } - _SEH2_END + _SEH2_END; pustrDevice = &ustrDevice; - } + } /* Acquire global USER lock */ UserEnterShared(); @@ -602,6 +632,7 @@ NtUserEnumDisplaySettings( /* Get the registry settings */ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg); pdm = &dmReg; + pdm->dmSize = sizeof(DEVMODEW); } else if (iModeNum == ENUM_CURRENT_SETTINGS) { @@ -623,11 +654,6 @@ NtUserEnumDisplaySettings( /* Copy some information back */ _SEH2_TRY { - ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1); - cbSize = lpDevMode->dmSize; - cbExtra = lpDevMode->dmDriverExtra; - - ProbeForWrite(lpDevMode, cbSize + cbExtra, 1); /* Output what we got */ RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize)); @@ -648,13 +674,21 @@ NtUserEnumDisplaySettings( return Status; } +VOID +UserUpdateFullscreen( + DWORD flags) +{ + if (flags & CDS_FULLSCREEN) + gpFullscreen = gptiCurrent->ppi; + else + gpFullscreen = NULL; +} LONG APIENTRY UserChangeDisplaySettings( PUNICODE_STRING pustrDevice, LPDEVMODEW pdm, - HWND hwnd, DWORD flags, LPVOID lParam) { @@ -663,6 +697,7 @@ UserChangeDisplaySettings( HKEY hkey; NTSTATUS Status; PPDEVOBJ ppdev; + WORD OrigBC; //PDESKTOP pdesk; /* If no DEVMODE is given, use registry settings */ @@ -677,9 +712,16 @@ UserChangeDisplaySettings( } } else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields)) - return DISP_CHANGE_BADMODE; /* This is what winXP SP3 returns */ + { + return DISP_CHANGE_BADMODE; /* This is what WinXP SP3 returns */ + } else + { dm = *pdm; + } + + /* Save original bit count */ + OrigBC = gpsi->BitCount; /* Check params */ if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT)) @@ -697,13 +739,13 @@ UserChangeDisplaySettings( } /* Fixup values */ - if(dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL)) + if (dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL)) { dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel; dm.dmFields |= DM_BITSPERPEL; } - if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0)) + if ((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0)) dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency; /* Look for the requested DEVMODE */ @@ -741,18 +783,12 @@ UserChangeDisplaySettings( } } - /* Check if DEVMODE matches the current mode */ - if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET)) - { - ERR("DEVMODE matches, nothing to do\n"); - goto leave; - } - /* Shall we apply the settings? */ if (!(flags & CDS_NORESET)) { ULONG ulResult; PVOID pvOldCursor; + TEXTMETRICW tmw; /* Remove mouse pointer */ pvOldCursor = UserSetCursor(NULL, TRUE); @@ -761,7 +797,8 @@ UserChangeDisplaySettings( ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm); /* Restore mouse pointer, no hooks called */ - UserSetCursor(pvOldCursor, TRUE); + pvOldCursor = UserSetCursor(pvOldCursor, TRUE); + ASSERT(pvOldCursor == NULL); /* Check for failure */ if (!ulResult) @@ -773,14 +810,29 @@ UserChangeDisplaySettings( goto leave; } + UserUpdateFullscreen(flags); + /* Update the system metrics */ InitMetrics(); - //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps); - /* Set new size of the monitor */ UserUpdateMonitorSize((HDEV)ppdev); + /* Update the SERVERINFO */ + gpsi->dmLogPixels = ppdev->gdiinfo.ulLogPixelsY; + gpsi->Planes = ppdev->gdiinfo.cPlanes; + gpsi->BitsPixel = ppdev->gdiinfo.cBitsPixel; + gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel; + if (ppdev->gdiinfo.flRaster & RC_PALETTE) + { + gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY; + } + else + gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY; + // Font is realized and this dc was previously set to internal DC_ATTR. + gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar); + gpsi->tmSysFont = tmw; + /* Remove all cursor clipping */ UserClipCursor(NULL); @@ -788,13 +840,21 @@ UserChangeDisplaySettings( //IntHideDesktop(pdesk); /* Send WM_DISPLAYCHANGE to all toplevel windows */ - co_IntSendMessageTimeout(HWND_BROADCAST, - WM_DISPLAYCHANGE, - (WPARAM)ppdev->gdiinfo.cBitsPixel, - (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulVertRes << 16)), - SMTO_NORMAL, - 100, - &ulResult); + UserSendNotifyMessage(HWND_BROADCAST, + WM_DISPLAYCHANGE, + gpsi->BitCount, + MAKELONG(gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN])); + + ERR("BitCount New %d Orig %d ChkNew %d\n",gpsi->BitCount,OrigBC,ppdev->gdiinfo.cBitsPixel); + + /* Not full screen and different bit count, send messages */ + if (!(flags & CDS_FULLSCREEN) && + gpsi->BitCount != OrigBC) + { + ERR("Detect settings changed.\n"); + UserSendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0); + UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); + } //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes); @@ -808,12 +868,23 @@ leave: return lResult; } +VOID +UserDisplayNotifyShutdown( + PPROCESSINFO ppiCurrent) +{ + if (ppiCurrent == gpFullscreen) + { + UserChangeDisplaySettings(NULL, NULL, 0, NULL); + if (gpFullscreen) + ERR("Failed to restore display mode!\n"); + } +} + LONG APIENTRY NtUserChangeDisplaySettings( PUNICODE_STRING pustrDevice, LPDEVMODEW lpDevMode, - HWND hwnd, DWORD dwflags, LPVOID lParam) { @@ -823,8 +894,7 @@ NtUserChangeDisplaySettings( LONG lRet; /* Check arguments */ - if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) || - (hwnd != NULL)) + if ((dwflags != CDS_VIDEOPARAMETERS) && (lParam != NULL)) { EngSetLastError(ERROR_INVALID_PARAMETER); return DISP_CHANGE_BADPARAM; @@ -903,7 +973,7 @@ NtUserChangeDisplaySettings( UserEnterExclusive(); /* Call internal function */ - lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL); + lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, dwflags, NULL); /* Release lock */ UserLeave();