| 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_; | 98 Callback* callback_ = nullptr; |
| 99 | 99 |
| 100 // HWND and HDC for the currently selected window or NULL if window is not | 100 // HWND and HDC for the currently selected window or nullptr if window is not |
| 101 // selected. | 101 // selected. |
| 102 HWND window_; | 102 HWND window_ = nullptr; |
| 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 : callback_(NULL), | 116 WindowCapturerWin::~WindowCapturerWin() {} |
| 117 window_(NULL) { | |
| 118 } | |
| 119 | |
| 120 WindowCapturerWin::~WindowCapturerWin() { | |
| 121 } | |
| 122 | 117 |
| 123 bool WindowCapturerWin::GetWindowList(WindowList* windows) { | 118 bool WindowCapturerWin::GetWindowList(WindowList* windows) { |
| 124 WindowList result; | 119 WindowList result; |
| 125 LPARAM param = reinterpret_cast<LPARAM>(&result); | 120 LPARAM param = reinterpret_cast<LPARAM>(&result); |
| 126 if (!EnumWindows(&WindowsEnumerationHandler, param)) | 121 if (!EnumWindows(&WindowsEnumerationHandler, param)) |
| 127 return false; | 122 return false; |
| 128 windows->swap(result); | 123 windows->swap(result); |
| 129 | 124 |
| 130 std::map<HWND, DesktopSize> new_map; | 125 std::map<HWND, DesktopSize> new_map; |
| 131 for (const auto& item : *windows) { | 126 for (const auto& item : *windows) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 161 void WindowCapturerWin::Start(Callback* callback) { | 156 void WindowCapturerWin::Start(Callback* callback) { |
| 162 assert(!callback_); | 157 assert(!callback_); |
| 163 assert(callback); | 158 assert(callback); |
| 164 | 159 |
| 165 callback_ = callback; | 160 callback_ = callback; |
| 166 } | 161 } |
| 167 | 162 |
| 168 void WindowCapturerWin::Capture(const DesktopRegion& region) { | 163 void WindowCapturerWin::Capture(const DesktopRegion& region) { |
| 169 if (!window_) { | 164 if (!window_) { |
| 170 LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError(); | 165 LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError(); |
| 171 callback_->OnCaptureCompleted(NULL); | 166 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 172 return; | 167 return; |
| 173 } | 168 } |
| 174 | 169 |
| 175 // Stop capturing if the window has been closed. | 170 // Stop capturing if the window has been closed. |
| 176 if (!IsWindow(window_)) { | 171 if (!IsWindow(window_)) { |
| 177 callback_->OnCaptureCompleted(NULL); | 172 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 178 return; | 173 return; |
| 179 } | 174 } |
| 180 | 175 |
| 181 // Return a 1x1 black frame if the window is minimized or invisible, to match | 176 // Return a 1x1 black frame if the window is minimized or invisible, to match |
| 182 // behavior on mace. Window can be temporarily invisible during the | 177 // behavior on mace. Window can be temporarily invisible during the |
| 183 // transition of full screen mode on/off. | 178 // transition of full screen mode on/off. |
| 184 if (IsIconic(window_) || !IsWindowVisible(window_)) { | 179 if (IsIconic(window_) || !IsWindowVisible(window_)) { |
| 185 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1)); | 180 std::unique_ptr<DesktopFrame> frame = |
| 181 new BasicDesktopFrame(DesktopSize(1, 1)); |
| 186 memset(frame->data(), 0, frame->stride() * frame->size().height()); | 182 memset(frame->data(), 0, frame->stride() * frame->size().height()); |
| 187 | 183 |
| 188 previous_size_ = frame->size(); | 184 previous_size_ = frame->size(); |
| 189 window_size_map_[window_] = previous_size_; | 185 window_size_map_[window_] = previous_size_; |
| 190 callback_->OnCaptureCompleted(frame); | 186 callback_->OnCaptureCompleted(std::move(frame)); |
| 191 return; | 187 return; |
| 192 } | 188 } |
| 193 | 189 |
| 194 DesktopRect original_rect; | 190 DesktopRect original_rect; |
| 195 DesktopRect cropped_rect; | 191 DesktopRect cropped_rect; |
| 196 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { | 192 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { |
| 197 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); | 193 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); |
| 198 callback_->OnCaptureCompleted(NULL); | 194 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 199 return; | 195 return; |
| 200 } | 196 } |
| 201 | 197 |
| 202 HDC window_dc = GetWindowDC(window_); | 198 HDC window_dc = GetWindowDC(window_); |
| 203 if (!window_dc) { | 199 if (!window_dc) { |
| 204 LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError(); | 200 LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError(); |
| 205 callback_->OnCaptureCompleted(NULL); | 201 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 206 return; | 202 return; |
| 207 } | 203 } |
| 208 | 204 |
| 209 std::unique_ptr<DesktopFrameWin> frame( | 205 std::unique_ptr<DesktopFrameWin> frame( |
| 210 DesktopFrameWin::Create(cropped_rect.size(), NULL, window_dc)); | 206 DesktopFrameWin::Create(cropped_rect.size(), nullptr, window_dc)); |
| 211 if (!frame.get()) { | 207 if (!frame.get()) { |
| 212 ReleaseDC(window_, window_dc); | 208 ReleaseDC(window_, window_dc); |
| 213 callback_->OnCaptureCompleted(NULL); | 209 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 214 return; | 210 return; |
| 215 } | 211 } |
| 216 | 212 |
| 217 HDC mem_dc = CreateCompatibleDC(window_dc); | 213 HDC mem_dc = CreateCompatibleDC(window_dc); |
| 218 HGDIOBJ previous_object = SelectObject(mem_dc, frame->bitmap()); | 214 HGDIOBJ previous_object = SelectObject(mem_dc, frame->bitmap()); |
| 219 BOOL result = FALSE; | 215 BOOL result = FALSE; |
| 220 | 216 |
| 221 // When desktop composition (Aero) is enabled each window is rendered to a | 217 // When desktop composition (Aero) is enabled each window is rendered to a |
| 222 // private buffer allowing BitBlt() to get the window content even if the | 218 // private buffer allowing BitBlt() to get the window content even if the |
| 223 // window is occluded. PrintWindow() is slower but lets rendering the window | 219 // window is occluded. PrintWindow() is slower but lets rendering the window |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 window_size_map_[window_] = previous_size_; | 252 window_size_map_[window_] = previous_size_; |
| 257 | 253 |
| 258 frame->mutable_updated_region()->SetRect( | 254 frame->mutable_updated_region()->SetRect( |
| 259 DesktopRect::MakeSize(frame->size())); | 255 DesktopRect::MakeSize(frame->size())); |
| 260 | 256 |
| 261 if (!result) { | 257 if (!result) { |
| 262 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; | 258 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; |
| 263 frame.reset(); | 259 frame.reset(); |
| 264 } | 260 } |
| 265 | 261 |
| 266 callback_->OnCaptureCompleted(frame.release()); | 262 callback_->OnCaptureCompleted(std::move(frame)); |
| 267 } | 263 } |
| 268 | 264 |
| 269 } // namespace | 265 } // namespace |
| 270 | 266 |
| 271 // static | 267 // static |
| 272 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { | 268 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { |
| 273 return new WindowCapturerWin(); | 269 return new WindowCapturerWin(); |
| 274 } | 270 } |
| 275 | 271 |
| 276 } // namespace webrtc | 272 } // namespace webrtc |
| OLD | NEW |