This source file includes following definitions.
- RefreshDesktopShape
- desktop_shape
- EnumWindowsCallback
- Create
#include "remoting/host/desktop_shape_tracker.h"
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_gdi_object.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
namespace remoting {
namespace {
struct EnumDesktopShapeData {
EnumDesktopShapeData()
: window_region(CreateRectRgn(0, 0, 0, 0)),
desktop_region(CreateRectRgn(0, 0, 0, 0)) {
}
base::win::ScopedRegion window_region;
base::win::ScopedRegion desktop_region;
};
class DesktopShapeTrackerWin : public DesktopShapeTracker {
public:
DesktopShapeTrackerWin();
virtual ~DesktopShapeTrackerWin();
virtual void RefreshDesktopShape();
virtual const webrtc::DesktopRegion& desktop_shape();
private:
static BOOL CALLBACK EnumWindowsCallback(HWND window, LPARAM lparam);
webrtc::DesktopRegion desktop_shape_;
base::win::ScopedRegion old_desktop_region_;
DISALLOW_COPY_AND_ASSIGN(DesktopShapeTrackerWin);
};
DesktopShapeTrackerWin::DesktopShapeTrackerWin()
: old_desktop_region_(CreateRectRgn(0, 0, 0, 0)) {
}
DesktopShapeTrackerWin::~DesktopShapeTrackerWin() {
}
void DesktopShapeTrackerWin::RefreshDesktopShape() {
scoped_ptr<EnumDesktopShapeData> shape_data(new EnumDesktopShapeData);
if (!EnumWindows(EnumWindowsCallback, (LPARAM)shape_data.get())) {
LOG_GETLASTERROR(ERROR) << "Failed to enumerate windows";
desktop_shape_.Clear();
return;
}
if (!EqualRgn(shape_data->desktop_region, old_desktop_region_)) {
old_desktop_region_.Set(shape_data->desktop_region.release());
DWORD bytes_size = GetRegionData(old_desktop_region_, 0, NULL);
CHECK(bytes_size != 0);
std::vector<char> buffer(bytes_size);
LPRGNDATA region_data = reinterpret_cast<LPRGNDATA>(buffer.data());
DWORD result = GetRegionData(old_desktop_region_, bytes_size, region_data);
CHECK(result == bytes_size);
const LPRECT rects = reinterpret_cast<LPRECT>(®ion_data->Buffer[0]);
desktop_shape_.Clear();
for (size_t i = 0; i < region_data->rdh.nCount; ++i) {
desktop_shape_.AddRect(webrtc::DesktopRect::MakeLTRB(
rects[i].left, rects[i].top, rects[i].right, rects[i].bottom));
}
}
}
const webrtc::DesktopRegion& DesktopShapeTrackerWin::desktop_shape() {
return desktop_shape_;
}
BOOL DesktopShapeTrackerWin::EnumWindowsCallback(HWND window, LPARAM lparam) {
EnumDesktopShapeData* data = reinterpret_cast<EnumDesktopShapeData*>(lparam);
HRGN desktop_region = data->desktop_region.Get();
HRGN window_region = data->window_region.Get();
if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
return TRUE;
RECT window_rect;
if (!GetWindowRect(window, &window_rect))
return TRUE;
if (GetWindowRgn(window, window_region) != ERROR) {
OffsetRgn(window_region, window_rect.left, window_rect.top);
} else {
SetRectRgn(window_region, window_rect.left, window_rect.top,
window_rect.right, window_rect.bottom);
}
CombineRgn(desktop_region, desktop_region, window_region, RGN_OR);
return TRUE;
}
}
scoped_ptr<DesktopShapeTracker> DesktopShapeTracker::Create(
webrtc::DesktopCaptureOptions options) {
return scoped_ptr<DesktopShapeTracker>(new DesktopShapeTrackerWin());
}
}