OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 // WindowCapturer interface. | 88 // WindowCapturer interface. |
89 bool GetWindowList(WindowList* windows) override; | 89 bool GetWindowList(WindowList* windows) override; |
90 bool SelectWindow(WindowId id) override; | 90 bool SelectWindow(WindowId id) override; |
91 bool BringSelectedWindowToFront() override; | 91 bool BringSelectedWindowToFront() override; |
92 | 92 |
93 // DesktopCapturer interface. | 93 // DesktopCapturer interface. |
94 void Start(Callback* callback) override; | 94 void Start(Callback* callback) override; |
95 void Capture(const DesktopRegion& region) override; | 95 void Capture(const DesktopRegion& region) override; |
96 | 96 |
97 private: | 97 private: |
98 Callback* callback_ = nullptr; | 98 Callback* callback_; |
99 | 99 |
100 // HWND and HDC for the currently selected window or nullptr if window is not | 100 // HWND and HDC for the currently selected window or NULL if window is not |
101 // selected. | 101 // selected. |
102 HWND window_ = nullptr; | 102 HWND window_; |
103 | 103 |
104 DesktopSize previous_size_; | 104 DesktopSize previous_size_; |
105 | 105 |
106 AeroChecker aero_checker_; | 106 AeroChecker aero_checker_; |
107 | 107 |
108 // This map is used to avoid flickering for the case when SelectWindow() calls | 108 // This map is used to avoid flickering for the case when SelectWindow() calls |
109 // are interleaved with Capture() calls. | 109 // are interleaved with Capture() calls. |
110 std::map<HWND, DesktopSize> window_size_map_; | 110 std::map<HWND, DesktopSize> window_size_map_; |
111 | 111 |
112 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); | 112 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); |
113 }; | 113 }; |
114 | 114 |
115 WindowCapturerWin::WindowCapturerWin() {} | 115 WindowCapturerWin::WindowCapturerWin() |
116 WindowCapturerWin::~WindowCapturerWin() {} | 116 : callback_(NULL), |
| 117 window_(NULL) { |
| 118 } |
| 119 |
| 120 WindowCapturerWin::~WindowCapturerWin() { |
| 121 } |
117 | 122 |
118 bool WindowCapturerWin::GetWindowList(WindowList* windows) { | 123 bool WindowCapturerWin::GetWindowList(WindowList* windows) { |
119 WindowList result; | 124 WindowList result; |
120 LPARAM param = reinterpret_cast<LPARAM>(&result); | 125 LPARAM param = reinterpret_cast<LPARAM>(&result); |
121 if (!EnumWindows(&WindowsEnumerationHandler, param)) | 126 if (!EnumWindows(&WindowsEnumerationHandler, param)) |
122 return false; | 127 return false; |
123 windows->swap(result); | 128 windows->swap(result); |
124 | 129 |
125 std::map<HWND, DesktopSize> new_map; | 130 std::map<HWND, DesktopSize> new_map; |
126 for (const auto& item : *windows) { | 131 for (const auto& item : *windows) { |
(...skipping 29 matching lines...) Expand all Loading... |
156 void WindowCapturerWin::Start(Callback* callback) { | 161 void WindowCapturerWin::Start(Callback* callback) { |
157 assert(!callback_); | 162 assert(!callback_); |
158 assert(callback); | 163 assert(callback); |
159 | 164 |
160 callback_ = callback; | 165 callback_ = callback; |
161 } | 166 } |
162 | 167 |
163 void WindowCapturerWin::Capture(const DesktopRegion& region) { | 168 void WindowCapturerWin::Capture(const DesktopRegion& region) { |
164 if (!window_) { | 169 if (!window_) { |
165 LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError(); | 170 LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError(); |
166 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 171 callback_->OnCaptureCompleted(NULL); |
167 return; | 172 return; |
168 } | 173 } |
169 | 174 |
170 // Stop capturing if the window has been closed. | 175 // Stop capturing if the window has been closed. |
171 if (!IsWindow(window_)) { | 176 if (!IsWindow(window_)) { |
172 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 177 callback_->OnCaptureCompleted(NULL); |
173 return; | 178 return; |
174 } | 179 } |
175 | 180 |
176 // Return a 1x1 black frame if the window is minimized or invisible, to match | 181 // Return a 1x1 black frame if the window is minimized or invisible, to match |
177 // behavior on mace. Window can be temporarily invisible during the | 182 // behavior on mace. Window can be temporarily invisible during the |
178 // transition of full screen mode on/off. | 183 // transition of full screen mode on/off. |
179 if (IsIconic(window_) || !IsWindowVisible(window_)) { | 184 if (IsIconic(window_) || !IsWindowVisible(window_)) { |
180 std::unique_ptr<DesktopFrame> frame( | 185 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1)); |
181 new BasicDesktopFrame(DesktopSize(1, 1))); | |
182 memset(frame->data(), 0, frame->stride() * frame->size().height()); | 186 memset(frame->data(), 0, frame->stride() * frame->size().height()); |
183 | 187 |
184 previous_size_ = frame->size(); | 188 previous_size_ = frame->size(); |
185 window_size_map_[window_] = previous_size_; | 189 window_size_map_[window_] = previous_size_; |
186 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | 190 callback_->OnCaptureCompleted(frame); |
187 return; | 191 return; |
188 } | 192 } |
189 | 193 |
190 DesktopRect original_rect; | 194 DesktopRect original_rect; |
191 DesktopRect cropped_rect; | 195 DesktopRect cropped_rect; |
192 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { | 196 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { |
193 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); | 197 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); |
194 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 198 callback_->OnCaptureCompleted(NULL); |
195 return; | 199 return; |
196 } | 200 } |
197 | 201 |
198 HDC window_dc = GetWindowDC(window_); | 202 HDC window_dc = GetWindowDC(window_); |
199 if (!window_dc) { | 203 if (!window_dc) { |
200 LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError(); | 204 LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError(); |
201 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 205 callback_->OnCaptureCompleted(NULL); |
202 return; | 206 return; |
203 } | 207 } |
204 | 208 |
205 std::unique_ptr<DesktopFrameWin> frame( | 209 std::unique_ptr<DesktopFrameWin> frame( |
206 DesktopFrameWin::Create(cropped_rect.size(), nullptr, window_dc)); | 210 DesktopFrameWin::Create(cropped_rect.size(), NULL, window_dc)); |
207 if (!frame.get()) { | 211 if (!frame.get()) { |
208 ReleaseDC(window_, window_dc); | 212 ReleaseDC(window_, window_dc); |
209 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 213 callback_->OnCaptureCompleted(NULL); |
210 return; | 214 return; |
211 } | 215 } |
212 | 216 |
213 HDC mem_dc = CreateCompatibleDC(window_dc); | 217 HDC mem_dc = CreateCompatibleDC(window_dc); |
214 HGDIOBJ previous_object = SelectObject(mem_dc, frame->bitmap()); | 218 HGDIOBJ previous_object = SelectObject(mem_dc, frame->bitmap()); |
215 BOOL result = FALSE; | 219 BOOL result = FALSE; |
216 | 220 |
217 // When desktop composition (Aero) is enabled each window is rendered to a | 221 // When desktop composition (Aero) is enabled each window is rendered to a |
218 // private buffer allowing BitBlt() to get the window content even if the | 222 // private buffer allowing BitBlt() to get the window content even if the |
219 // window is occluded. PrintWindow() is slower but lets rendering the window | 223 // window is occluded. PrintWindow() is slower but lets rendering the window |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 window_size_map_[window_] = previous_size_; | 256 window_size_map_[window_] = previous_size_; |
253 | 257 |
254 frame->mutable_updated_region()->SetRect( | 258 frame->mutable_updated_region()->SetRect( |
255 DesktopRect::MakeSize(frame->size())); | 259 DesktopRect::MakeSize(frame->size())); |
256 | 260 |
257 if (!result) { | 261 if (!result) { |
258 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; | 262 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; |
259 frame.reset(); | 263 frame.reset(); |
260 } | 264 } |
261 | 265 |
262 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | 266 callback_->OnCaptureCompleted(frame.release()); |
263 } | 267 } |
264 | 268 |
265 } // namespace | 269 } // namespace |
266 | 270 |
267 // static | 271 // static |
268 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { | 272 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { |
269 return new WindowCapturerWin(); | 273 return new WindowCapturerWin(); |
270 } | 274 } |
271 | 275 |
272 } // namespace webrtc | 276 } // namespace webrtc |
OLD | NEW |