We are still using cropping window capturer even the window is out of the screen. See the bug for details. Bug: webrtc:8134 Change-Id: I5161b1a17a3a1f8244697eea5eb78975be6908f9 Reviewed-on: https://chromium-review.googlesource.com/627338 Commit-Queue: Zijie He <zijiehe@chromium.org> Reviewed-by: Jamie Walch <jamiewalch@chromium.org> Cr-Commit-Position: refs/heads/master@{#19474}
140 lines
4.5 KiB
C++
140 lines
4.5 KiB
C++
/*
|
|
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
|
|
|
|
#include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h"
|
|
#include "webrtc/rtc_base/checks.h"
|
|
#include "webrtc/rtc_base/win32.h"
|
|
|
|
namespace webrtc {
|
|
|
|
bool GetWindowRect(HWND window, DesktopRect* result) {
|
|
RECT rect;
|
|
if (!::GetWindowRect(window, &rect)) {
|
|
return false;
|
|
}
|
|
*result = DesktopRect::MakeLTRB(
|
|
rect.left, rect.top, rect.right, rect.bottom);
|
|
return true;
|
|
}
|
|
|
|
bool GetCroppedWindowRect(HWND window,
|
|
DesktopRect* cropped_rect,
|
|
DesktopRect* original_rect) {
|
|
DesktopRect window_rect;
|
|
if (!GetWindowRect(window, &window_rect)) {
|
|
return false;
|
|
}
|
|
|
|
if (original_rect) {
|
|
*original_rect = window_rect;
|
|
}
|
|
*cropped_rect = window_rect;
|
|
|
|
WINDOWPLACEMENT window_placement;
|
|
window_placement.length = sizeof(window_placement);
|
|
if (!::GetWindowPlacement(window, &window_placement)) {
|
|
return false;
|
|
}
|
|
|
|
// After Windows8, transparent borders will be added by OS at
|
|
// left/bottom/right sides of a window. If the cropped window
|
|
// doesn't remove these borders, the background will be exposed a bit.
|
|
//
|
|
// On Windows 8.1. or upper, rtc::IsWindows8OrLater(), which uses
|
|
// GetVersionEx() may not correctly return the windows version. See
|
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
|
|
// So we always prefer to check |window_placement|.showCmd.
|
|
if (rtc::IsWindows8OrLater() ||
|
|
window_placement.showCmd == SW_SHOWMAXIMIZED) {
|
|
const int width = GetSystemMetrics(SM_CXSIZEFRAME);
|
|
const int height = GetSystemMetrics(SM_CYSIZEFRAME);
|
|
cropped_rect->Extend(-width, 0, -width, -height);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GetWindowContentRect(HWND window, DesktopRect* result) {
|
|
if (!GetWindowRect(window, result)) {
|
|
return false;
|
|
}
|
|
|
|
RECT rect;
|
|
if (!::GetClientRect(window, &rect)) {
|
|
return false;
|
|
}
|
|
|
|
const int width = rect.right - rect.left;
|
|
// The GetClientRect() is not expected to return a larger area than
|
|
// GetWindowRect().
|
|
if (width > 0 && width < result->width()) {
|
|
// - GetClientRect() always set the left / top of RECT to 0. So we need to
|
|
// estimate the border width from GetClientRect() and GetWindowRect().
|
|
// - Border width of a window varies according to the window type.
|
|
// - GetClientRect() excludes the title bar, which should be considered as
|
|
// part of the content and included in the captured frame. So we always
|
|
// estimate the border width according to the window width.
|
|
// - We assume a window has same border width in each side.
|
|
// So we shrink half of the width difference from all four sides.
|
|
const int shrink = ((width - result->width()) / 2);
|
|
// When |shrink| is negative, DesktopRect::Extend() shrinks itself.
|
|
result->Extend(shrink, 0, shrink, 0);
|
|
// Usually this should not happen, just in case we have received a strange
|
|
// window, which has only left and right borders.
|
|
if (result->height() > shrink * 2) {
|
|
result->Extend(0, shrink, 0, shrink);
|
|
}
|
|
RTC_DCHECK(!result->is_empty());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int GetWindowRegionTypeWithBoundary(HWND window, DesktopRect* result) {
|
|
win::ScopedGDIObject<HRGN, win::DeleteObjectTraits<HRGN>>
|
|
scoped_hrgn(CreateRectRgn(0, 0, 0, 0));
|
|
const int region_type = GetWindowRgn(window, scoped_hrgn.Get());
|
|
|
|
if (region_type == SIMPLEREGION) {
|
|
RECT rect;
|
|
GetRgnBox(scoped_hrgn.Get(), &rect);
|
|
*result = DesktopRect::MakeLTRB(
|
|
rect.left, rect.top, rect.right, rect.bottom);
|
|
}
|
|
return region_type;
|
|
}
|
|
|
|
AeroChecker::AeroChecker() : dwmapi_library_(nullptr), func_(nullptr) {
|
|
// Try to load dwmapi.dll dynamically since it is not available on XP.
|
|
dwmapi_library_ = LoadLibrary(L"dwmapi.dll");
|
|
if (dwmapi_library_) {
|
|
func_ = reinterpret_cast<DwmIsCompositionEnabledFunc>(
|
|
GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled"));
|
|
}
|
|
}
|
|
|
|
AeroChecker::~AeroChecker() {
|
|
if (dwmapi_library_) {
|
|
FreeLibrary(dwmapi_library_);
|
|
}
|
|
}
|
|
|
|
bool AeroChecker::IsAeroEnabled() {
|
|
BOOL result = FALSE;
|
|
if (func_) {
|
|
func_(&result);
|
|
}
|
|
return result != FALSE;
|
|
}
|
|
|
|
} // namespace webrtc
|