| 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 |