1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ScreenHelperWin.h"
9 #include "mozilla/Logging.h"
13 static mozilla::LazyLogModule
sScreenLog("WidgetScreen");
18 BOOL CALLBACK
CollectMonitors(HMONITOR aMon
, HDC
, LPRECT
, LPARAM ioParam
) {
19 auto screens
= reinterpret_cast<nsTArray
<RefPtr
<Screen
>>*>(ioParam
);
22 info
.cbSize
= sizeof(MONITORINFOEX
);
23 success
= ::GetMonitorInfoW(aMon
, &info
);
25 MOZ_LOG(sScreenLog
, LogLevel::Error
, ("GetMonitorInfoW failed"));
26 return TRUE
; // continue the enumeration
29 double scale
= WinUtils::LogToPhysFactor(aMon
);
30 DesktopToLayoutDeviceScale contentsScaleFactor
;
31 if (WinUtils::IsPerMonitorDPIAware()) {
32 contentsScaleFactor
.scale
= 1.0;
34 contentsScaleFactor
.scale
= scale
;
36 CSSToLayoutDeviceScale
defaultCssScaleFactor(scale
);
37 LayoutDeviceIntRect
rect(info
.rcMonitor
.left
, info
.rcMonitor
.top
,
38 info
.rcMonitor
.right
- info
.rcMonitor
.left
,
39 info
.rcMonitor
.bottom
- info
.rcMonitor
.top
);
40 LayoutDeviceIntRect
availRect(info
.rcWork
.left
, info
.rcWork
.top
,
41 info
.rcWork
.right
- info
.rcWork
.left
,
42 info
.rcWork
.bottom
- info
.rcWork
.top
);
44 HDC hDC
= CreateDC(nullptr, info
.szDevice
, nullptr, nullptr);
46 MOZ_LOG(sScreenLog
, LogLevel::Error
, ("CollectMonitors CreateDC failed"));
49 uint32_t pixelDepth
= ::GetDeviceCaps(hDC
, BITSPIXEL
);
51 if (pixelDepth
== 32) {
52 // If a device uses 32 bits per pixel, it's still only using 8 bits
53 // per color component, which is what our callers want to know.
54 // (Some devices report 32 and some devices report 24.)
58 float dpi
= WinUtils::MonitorDPI(aMon
);
59 MOZ_LOG(sScreenLog
, LogLevel::Debug
,
60 ("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect
.X(),
61 rect
.Y(), rect
.Width(), rect
.Height(), availRect
.X(), availRect
.Y(),
62 availRect
.Width(), availRect
.Height(), pixelDepth
,
63 contentsScaleFactor
.scale
, defaultCssScaleFactor
.scale
, dpi
));
64 auto screen
= new Screen(rect
, availRect
, pixelDepth
, pixelDepth
,
65 contentsScaleFactor
, defaultCssScaleFactor
, dpi
);
66 if (info
.dwFlags
& MONITORINFOF_PRIMARY
) {
67 // The primary monitor must be the first element of the screen list.
68 screens
->InsertElementAt(0, std::move(screen
));
70 screens
->AppendElement(std::move(screen
));
75 void ScreenHelperWin::RefreshScreens() {
76 MOZ_LOG(sScreenLog
, LogLevel::Debug
, ("Refreshing screens"));
78 AutoTArray
<RefPtr
<Screen
>, 4> screens
;
79 BOOL result
= ::EnumDisplayMonitors(
80 nullptr, nullptr, (MONITORENUMPROC
)CollectMonitors
, (LPARAM
)&screens
);
82 NS_WARNING("Unable to EnumDisplayMonitors");
84 ScreenManager
& screenManager
= ScreenManager::GetSingleton();
85 screenManager
.Refresh(std::move(screens
));
89 } // namespace mozilla