| 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 | 
| 11 #include "webrtc/modules/desktop_capture/window_capturer.h" | 11 #include "webrtc/modules/desktop_capture/window_capturer.h" | 
| 12 | 12 | 
| 13 #include <assert.h> | 13 #include <assert.h> | 
| 14 | 14 | 
| 15 #include "webrtc/base/scoped_ptr.h" | 15 #include "webrtc/base/scoped_ptr.h" | 
| 16 #include "webrtc/base/win32.h" | 16 #include "webrtc/base/win32.h" | 
| 17 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" | 17 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" | 
| 18 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h" | 18 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h" | 
| 19 #include "webrtc/system_wrappers/interface/logging.h" | 19 #include "webrtc/system_wrappers/interface/logging.h" | 
| 20 | 20 | 
| 21 namespace webrtc { | 21 namespace webrtc { | 
| 22 | 22 | 
| 23 namespace { | 23 namespace { | 
| 24 | 24 | 
| 25 typedef HRESULT (WINAPI *DwmIsCompositionEnabledFunc)(BOOL* enabled); |  | 
| 26 |  | 
| 27 BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { | 25 BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { | 
| 28   WindowCapturer::WindowList* list = | 26   WindowCapturer::WindowList* list = | 
| 29       reinterpret_cast<WindowCapturer::WindowList*>(param); | 27       reinterpret_cast<WindowCapturer::WindowList*>(param); | 
| 30 | 28 | 
| 31   // Skip windows that are invisible, minimized, have no title, or are owned, | 29   // Skip windows that are invisible, minimized, have no title, or are owned, | 
| 32   // unless they have the app window style set. | 30   // unless they have the app window style set. | 
| 33   int len = GetWindowTextLength(hwnd); | 31   int len = GetWindowTextLength(hwnd); | 
| 34   HWND owner = GetWindow(hwnd, GW_OWNER); | 32   HWND owner = GetWindow(hwnd, GW_OWNER); | 
| 35   LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); | 33   LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); | 
| 36   if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || | 34   if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 74   // WindowCapturer interface. | 72   // WindowCapturer interface. | 
| 75   bool GetWindowList(WindowList* windows) override; | 73   bool GetWindowList(WindowList* windows) override; | 
| 76   bool SelectWindow(WindowId id) override; | 74   bool SelectWindow(WindowId id) override; | 
| 77   bool BringSelectedWindowToFront() override; | 75   bool BringSelectedWindowToFront() override; | 
| 78 | 76 | 
| 79   // DesktopCapturer interface. | 77   // DesktopCapturer interface. | 
| 80   void Start(Callback* callback) override; | 78   void Start(Callback* callback) override; | 
| 81   void Capture(const DesktopRegion& region) override; | 79   void Capture(const DesktopRegion& region) override; | 
| 82 | 80 | 
| 83  private: | 81  private: | 
| 84   bool IsAeroEnabled(); |  | 
| 85 |  | 
| 86   Callback* callback_; | 82   Callback* callback_; | 
| 87 | 83 | 
| 88   // HWND and HDC for the currently selected window or NULL if window is not | 84   // HWND and HDC for the currently selected window or NULL if window is not | 
| 89   // selected. | 85   // selected. | 
| 90   HWND window_; | 86   HWND window_; | 
| 91 | 87 | 
| 92   // dwmapi.dll is used to determine if desktop compositing is enabled. | 88   DesktopSize previous_size_; | 
| 93   HMODULE dwmapi_library_; |  | 
| 94   DwmIsCompositionEnabledFunc is_composition_enabled_func_; |  | 
| 95 | 89 | 
| 96   DesktopSize previous_size_; | 90   AeroChecker aero_checker_; | 
| 97 | 91 | 
| 98   DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); | 92   DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); | 
| 99 }; | 93 }; | 
| 100 | 94 | 
| 101 WindowCapturerWin::WindowCapturerWin() | 95 WindowCapturerWin::WindowCapturerWin() | 
| 102     : callback_(NULL), | 96     : callback_(NULL), | 
| 103       window_(NULL) { | 97       window_(NULL) { | 
| 104   // Try to load dwmapi.dll dynamically since it is not available on XP. |  | 
| 105   dwmapi_library_ = LoadLibrary(L"dwmapi.dll"); |  | 
| 106   if (dwmapi_library_) { |  | 
| 107     is_composition_enabled_func_ = |  | 
| 108         reinterpret_cast<DwmIsCompositionEnabledFunc>( |  | 
| 109             GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled")); |  | 
| 110     assert(is_composition_enabled_func_); |  | 
| 111   } else { |  | 
| 112     is_composition_enabled_func_ = NULL; |  | 
| 113   } |  | 
| 114 } | 98 } | 
| 115 | 99 | 
| 116 WindowCapturerWin::~WindowCapturerWin() { | 100 WindowCapturerWin::~WindowCapturerWin() { | 
| 117   if (dwmapi_library_) |  | 
| 118     FreeLibrary(dwmapi_library_); |  | 
| 119 } |  | 
| 120 |  | 
| 121 bool WindowCapturerWin::IsAeroEnabled() { |  | 
| 122   BOOL result = FALSE; |  | 
| 123   if (is_composition_enabled_func_) |  | 
| 124     is_composition_enabled_func_(&result); |  | 
| 125   return result != FALSE; |  | 
| 126 } | 101 } | 
| 127 | 102 | 
| 128 bool WindowCapturerWin::GetWindowList(WindowList* windows) { | 103 bool WindowCapturerWin::GetWindowList(WindowList* windows) { | 
| 129   WindowList result; | 104   WindowList result; | 
| 130   LPARAM param = reinterpret_cast<LPARAM>(&result); | 105   LPARAM param = reinterpret_cast<LPARAM>(&result); | 
| 131   if (!EnumWindows(&WindowsEnumerationHandler, param)) | 106   if (!EnumWindows(&WindowsEnumerationHandler, param)) | 
| 132     return false; | 107     return false; | 
| 133   windows->swap(result); | 108   windows->swap(result); | 
| 134   return true; | 109   return true; | 
| 135 } | 110 } | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 221   // window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may | 196   // window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may | 
| 222   // render occluding windows on top of the desired window. | 197   // render occluding windows on top of the desired window. | 
| 223   // | 198   // | 
| 224   // When composition is enabled the DC returned by GetWindowDC() doesn't always | 199   // When composition is enabled the DC returned by GetWindowDC() doesn't always | 
| 225   // have window frame rendered correctly. Windows renders it only once and then | 200   // have window frame rendered correctly. Windows renders it only once and then | 
| 226   // caches the result between captures. We hack it around by calling | 201   // caches the result between captures. We hack it around by calling | 
| 227   // PrintWindow() whenever window size changes, including the first time of | 202   // PrintWindow() whenever window size changes, including the first time of | 
| 228   // capturing - it somehow affects what we get from BitBlt() on the subsequent | 203   // capturing - it somehow affects what we get from BitBlt() on the subsequent | 
| 229   // captures. | 204   // captures. | 
| 230 | 205 | 
| 231   if (!IsAeroEnabled() || !previous_size_.equals(frame->size())) { | 206   if (!aero_checker_.IsAeroEnabled() || !previous_size_.equals(frame->size())) { | 
| 232     result = PrintWindow(window_, mem_dc, 0); | 207     result = PrintWindow(window_, mem_dc, 0); | 
| 233   } | 208   } | 
| 234 | 209 | 
| 235   // Aero is enabled or PrintWindow() failed, use BitBlt. | 210   // Aero is enabled or PrintWindow() failed, use BitBlt. | 
| 236   if (!result) { | 211   if (!result) { | 
| 237     result = BitBlt(mem_dc, 0, 0, frame->size().width(), frame->size().height(), | 212     result = BitBlt(mem_dc, 0, 0, frame->size().width(), frame->size().height(), | 
| 238                     window_dc, | 213                     window_dc, | 
| 239                     cropped_rect.left() - original_rect.left(), | 214                     cropped_rect.left() - original_rect.left(), | 
| 240                     cropped_rect.top() - original_rect.top(), | 215                     cropped_rect.top() - original_rect.top(), | 
| 241                     SRCCOPY); | 216                     SRCCOPY); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 259 } | 234 } | 
| 260 | 235 | 
| 261 }  // namespace | 236 }  // namespace | 
| 262 | 237 | 
| 263 // static | 238 // static | 
| 264 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { | 239 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { | 
| 265   return new WindowCapturerWin(); | 240   return new WindowCapturerWin(); | 
| 266 } | 241 } | 
| 267 | 242 | 
| 268 }  // namespace webrtc | 243 }  // namespace webrtc | 
| OLD | NEW | 
|---|