1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/desktop_capture/win/screen_capture_utils.h"
12
13 #include <windows.h>
14
15 #include <string>
16 #include <vector>
17
18 #include "modules/desktop_capture/desktop_capturer.h"
19 #include "rtc_base/checks.h"
20 #include "rtc_base/string_utils.h"
21 #include "rtc_base/win32.h"
22
23 namespace webrtc {
24
GetScreenList(DesktopCapturer::SourceList * screens,std::vector<std::string> * device_names)25 bool GetScreenList(DesktopCapturer::SourceList* screens,
26 std::vector<std::string>* device_names /* = nullptr */) {
27 RTC_DCHECK_EQ(screens->size(), 0U);
28 if (device_names) {
29 RTC_DCHECK_EQ(device_names->size(), 0U);
30 }
31
32 BOOL enum_result = TRUE;
33 for (int device_index = 0;; ++device_index) {
34 DISPLAY_DEVICEW device;
35 device.cb = sizeof(device);
36 enum_result = EnumDisplayDevicesW(NULL, device_index, &device, 0);
37
38 // |enum_result| is 0 if we have enumerated all devices.
39 if (!enum_result)
40 break;
41
42 // We only care about active displays.
43 if (!(device.StateFlags & DISPLAY_DEVICE_ACTIVE))
44 continue;
45
46 screens->push_back({device_index, std::string()});
47 if (device_names) {
48 device_names->push_back(rtc::ToUtf8(device.DeviceName));
49 }
50 }
51 return true;
52 }
53
IsScreenValid(DesktopCapturer::SourceId screen,std::wstring * device_key)54 bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key) {
55 if (screen == kFullDesktopScreenId) {
56 *device_key = L"";
57 return true;
58 }
59
60 DISPLAY_DEVICEW device;
61 device.cb = sizeof(device);
62 BOOL enum_result = EnumDisplayDevicesW(NULL, screen, &device, 0);
63 if (enum_result)
64 *device_key = device.DeviceKey;
65
66 return !!enum_result;
67 }
68
GetFullscreenRect()69 DesktopRect GetFullscreenRect() {
70 return DesktopRect::MakeXYWH(GetSystemMetrics(SM_XVIRTUALSCREEN),
71 GetSystemMetrics(SM_YVIRTUALSCREEN),
72 GetSystemMetrics(SM_CXVIRTUALSCREEN),
73 GetSystemMetrics(SM_CYVIRTUALSCREEN));
74 }
75
GetScreenRect(DesktopCapturer::SourceId screen,const std::wstring & device_key)76 DesktopRect GetScreenRect(DesktopCapturer::SourceId screen,
77 const std::wstring& device_key) {
78 if (screen == kFullDesktopScreenId) {
79 return GetFullscreenRect();
80 }
81
82 DISPLAY_DEVICEW device;
83 device.cb = sizeof(device);
84 BOOL result = EnumDisplayDevicesW(NULL, screen, &device, 0);
85 if (!result)
86 return DesktopRect();
87
88 // Verifies the device index still maps to the same display device, to make
89 // sure we are capturing the same device when devices are added or removed.
90 // DeviceKey is documented as reserved, but it actually contains the registry
91 // key for the device and is unique for each monitor, while DeviceID is not.
92 if (device_key != device.DeviceKey)
93 return DesktopRect();
94
95 DEVMODEW device_mode;
96 device_mode.dmSize = sizeof(device_mode);
97 device_mode.dmDriverExtra = 0;
98 result = EnumDisplaySettingsExW(device.DeviceName, ENUM_CURRENT_SETTINGS,
99 &device_mode, 0);
100 if (!result)
101 return DesktopRect();
102
103 return DesktopRect::MakeXYWH(
104 device_mode.dmPosition.x, device_mode.dmPosition.y,
105 device_mode.dmPelsWidth, device_mode.dmPelsHeight);
106 }
107
108 } // namespace webrtc
109