| 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_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 
|  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_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 
|  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_->OnCaptureResult(Result::SUCCESS, 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_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 
|  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_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 
|  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_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 
|  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_->OnCaptureResult(Result::SUCCESS, 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 |