From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- widget/windows/ScreenHelperWin.cpp | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 widget/windows/ScreenHelperWin.cpp (limited to 'widget/windows/ScreenHelperWin.cpp') diff --git a/widget/windows/ScreenHelperWin.cpp b/widget/windows/ScreenHelperWin.cpp new file mode 100644 index 0000000000..ff455b6c8c --- /dev/null +++ b/widget/windows/ScreenHelperWin.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ScreenHelperWin.h" + +#include "mozilla/Logging.h" +#include "nsTArray.h" +#include "WinUtils.h" + +static mozilla::LazyLogModule sScreenLog("WidgetScreen"); + +namespace mozilla { +namespace widget { + +BOOL CALLBACK CollectMonitors(HMONITOR aMon, HDC, LPRECT, LPARAM ioParam) { + auto screens = reinterpret_cast>*>(ioParam); + BOOL success = FALSE; + MONITORINFOEX info; + info.cbSize = sizeof(MONITORINFOEX); + success = ::GetMonitorInfoW(aMon, &info); + if (!success) { + MOZ_LOG(sScreenLog, LogLevel::Error, ("GetMonitorInfoW failed")); + return TRUE; // continue the enumeration + } + + double scale = WinUtils::LogToPhysFactor(aMon); + DesktopToLayoutDeviceScale contentsScaleFactor; + if (WinUtils::IsPerMonitorDPIAware()) { + contentsScaleFactor.scale = 1.0; + } else { + contentsScaleFactor.scale = scale; + } + CSSToLayoutDeviceScale defaultCssScaleFactor(scale); + LayoutDeviceIntRect rect(info.rcMonitor.left, info.rcMonitor.top, + info.rcMonitor.right - info.rcMonitor.left, + info.rcMonitor.bottom - info.rcMonitor.top); + LayoutDeviceIntRect availRect(info.rcWork.left, info.rcWork.top, + info.rcWork.right - info.rcWork.left, + info.rcWork.bottom - info.rcWork.top); + + HDC hDC = CreateDC(nullptr, info.szDevice, nullptr, nullptr); + if (!hDC) { + MOZ_LOG(sScreenLog, LogLevel::Error, ("CollectMonitors CreateDC failed")); + return TRUE; + } + uint32_t pixelDepth = ::GetDeviceCaps(hDC, BITSPIXEL); + DeleteDC(hDC); + if (pixelDepth == 32) { + // If a device uses 32 bits per pixel, it's still only using 8 bits + // per color component, which is what our callers want to know. + // (Some devices report 32 and some devices report 24.) + pixelDepth = 24; + } + + float dpi = WinUtils::MonitorDPI(aMon); + MOZ_LOG(sScreenLog, LogLevel::Debug, + ("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect.X(), + rect.Y(), rect.Width(), rect.Height(), availRect.X(), availRect.Y(), + availRect.Width(), availRect.Height(), pixelDepth, + contentsScaleFactor.scale, defaultCssScaleFactor.scale, dpi)); + auto screen = new Screen(rect, availRect, pixelDepth, pixelDepth, + contentsScaleFactor, defaultCssScaleFactor, dpi); + if (info.dwFlags & MONITORINFOF_PRIMARY) { + // The primary monitor must be the first element of the screen list. + screens->InsertElementAt(0, std::move(screen)); + } else { + screens->AppendElement(std::move(screen)); + } + return TRUE; +} + +void ScreenHelperWin::RefreshScreens() { + MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing screens")); + + AutoTArray, 4> screens; + BOOL result = ::EnumDisplayMonitors( + nullptr, nullptr, (MONITORENUMPROC)CollectMonitors, (LPARAM)&screens); + if (!result) { + NS_WARNING("Unable to EnumDisplayMonitors"); + } + ScreenManager& screenManager = ScreenManager::GetSingleton(); + screenManager.Refresh(std::move(screens)); +} + +} // namespace widget +} // namespace mozilla -- cgit v1.2.3