Flutter Windows Embedder
display_manager.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "display_manager.h"
6 
7 #include <windows.h>
8 
11 
12 namespace flutter {
13 
14 namespace {
15 
16 // Data structure to pass to the display enumeration callback.
17 struct MonitorEnumState {
18  const DisplayManagerWin32* display_manager;
19  std::vector<FlutterEngineDisplay>* displays;
20 };
21 
22 } // namespace
23 
25  : engine_(engine), win32_(engine->windows_proc_table()) {}
26 
28 
29 std::optional<FlutterEngineDisplay> DisplayManagerWin32::FromMonitor(
30  HMONITOR monitor) const {
31  MONITORINFOEXW monitor_info = {};
32  monitor_info.cbSize = sizeof(monitor_info);
33  if (win32_->GetMonitorInfoW(monitor, &monitor_info) == 0) {
34  return std::nullopt;
35  }
36 
37  DEVMODEW dev_mode = {};
38  dev_mode.dmSize = sizeof(dev_mode);
39  if (!win32_->EnumDisplaySettingsW(monitor_info.szDevice,
40  ENUM_CURRENT_SETTINGS, &dev_mode)) {
41  return std::nullopt;
42  }
43 
44  UINT dpi = GetDpiForMonitor(monitor);
45 
46  FlutterEngineDisplay display = {};
47  display.struct_size = sizeof(FlutterEngineDisplay);
48  display.display_id = reinterpret_cast<FlutterEngineDisplayId>(monitor);
49  display.single_display = false;
50  display.refresh_rate = dev_mode.dmDisplayFrequency;
51  display.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
52  display.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
53  display.device_pixel_ratio =
54  static_cast<double>(dpi) / static_cast<double>(kDefaultDpi);
55  return display;
56 }
57 
58 BOOL CALLBACK DisplayManagerWin32::EnumMonitorCallback(HMONITOR monitor,
59  HDC hdc,
60  LPRECT rect,
61  LPARAM data) {
62  MonitorEnumState* state = reinterpret_cast<MonitorEnumState*>(data);
63  const DisplayManagerWin32* self = state->display_manager;
64  std::vector<FlutterEngineDisplay>* displays = state->displays;
65  const std::optional<FlutterEngineDisplay> display =
66  self->FromMonitor(monitor);
67  if (!display) {
68  // Return TRUE to continue enumeration and skip this monitor.
69  // Returning FALSE would stop the entire enumeration process,
70  // potentially missing other valid monitors.
71  return TRUE;
72  }
73  displays->push_back(*display);
74  return TRUE;
75 }
76 
78  auto displays = GetDisplays();
79  engine_->UpdateDisplay(displays);
80 }
81 
83  UINT message,
84  WPARAM wparam,
85  LPARAM lparam,
86  LRESULT* result) {
87  switch (message) {
88  case WM_DISPLAYCHANGE:
89  case WM_DPICHANGED:
91  break;
92  }
93  return false;
94 }
95 
96 std::optional<FlutterEngineDisplay> DisplayManagerWin32::FindById(
97  FlutterEngineDisplayId id) {
98  for (auto const& display : GetDisplays()) {
99  if (display.display_id == id) {
100  return display;
101  }
102  }
103 
104  return std::nullopt;
105 }
106 
107 std::vector<FlutterEngineDisplay> DisplayManagerWin32::GetDisplays() const {
108  std::vector<FlutterEngineDisplay> displays;
109  MonitorEnumState state = {this, &displays};
110  win32_->EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback,
111  reinterpret_cast<LPARAM>(&state));
112 
113  if (displays.size() == 1) {
114  displays[0].single_display = true;
115  }
116 
117  return displays;
118 }
119 
120 } // namespace flutter
std::optional< FlutterEngineDisplay > FindById(FlutterEngineDisplayId id)
bool HandleWindowMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
DisplayManagerWin32(FlutterWindowsEngine *engine)
std::vector< FlutterEngineDisplay > GetDisplays() const
void UpdateDisplay(const std::vector< FlutterEngineDisplay > &displays)
std::vector< FlutterEngineDisplay > * displays
const DisplayManagerWin32 * display_manager
Win32Message message
UINT GetDpiForMonitor(HMONITOR monitor)
Definition: dpi_utils.cc:132
constexpr UINT kDefaultDpi
Definition: dpi_utils.h:12