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
);
60 hal::ScreenOrientation orientation
;
62 WinUtils::GetDisplayOrientation(info
.szDevice
, orientation
, angle
);
64 MOZ_LOG(sScreenLog
, LogLevel::Debug
,
65 ("New screen [%s (%s) %d %f %f %f %d %d]", ToString(rect
).c_str(),
66 ToString(availRect
).c_str(), pixelDepth
, contentsScaleFactor
.scale
,
67 defaultCssScaleFactor
.scale
, dpi
, orientation
, angle
));
69 new Screen(rect
, availRect
, pixelDepth
, pixelDepth
, contentsScaleFactor
,
70 defaultCssScaleFactor
, dpi
, orientation
, angle
);
71 if (info
.dwFlags
& MONITORINFOF_PRIMARY
) {
72 // The primary monitor must be the first element of the screen list.
73 screens
->InsertElementAt(0, std::move(screen
));
75 screens
->AppendElement(std::move(screen
));
80 void ScreenHelperWin::RefreshScreens() {
81 MOZ_LOG(sScreenLog
, LogLevel::Debug
, ("Refreshing screens"));
83 AutoTArray
<RefPtr
<Screen
>, 4> screens
;
84 BOOL result
= ::EnumDisplayMonitors(
85 nullptr, nullptr, (MONITORENUMPROC
)CollectMonitors
, (LPARAM
)&screens
);
87 NS_WARNING("Unable to EnumDisplayMonitors");
89 ScreenManager::Refresh(std::move(screens
));
93 } // namespace mozilla