blob: 82f7d2447fb71c45ede20dbadbb62967527a157c [file] [log] [blame]
/*
* Copyright (c) 2013 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/mouse_cursor_monitor.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
#include "webrtc/modules/desktop_capture/mouse_cursor.h"
#include "webrtc/modules/desktop_capture/win/cursor.h"
#include "webrtc/system_wrappers/interface/logging.h"
namespace webrtc {
class MouseCursorMonitorWin : public MouseCursorMonitor {
public:
explicit MouseCursorMonitorWin(HWND window);
virtual ~MouseCursorMonitorWin();
virtual void Init(Callback* callback, Mode mode) OVERRIDE;
virtual void Capture() OVERRIDE;
private:
HWND window_;
Callback* callback_;
Mode mode_;
HDC desktop_dc_;
HCURSOR last_cursor_;
};
MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window)
: window_(window),
callback_(NULL),
mode_(SHAPE_AND_POSITION),
desktop_dc_(NULL),
last_cursor_(NULL) {
}
MouseCursorMonitorWin::~MouseCursorMonitorWin() {
if (desktop_dc_)
ReleaseDC(NULL, desktop_dc_);
}
void MouseCursorMonitorWin::Init(Callback* callback, Mode mode) {
assert(!callback_);
assert(callback);
callback_ = callback;
mode_ = mode;
desktop_dc_ = GetDC(NULL);
}
void MouseCursorMonitorWin::Capture() {
assert(callback_);
CURSORINFO cursor_info;
cursor_info.cbSize = sizeof(CURSORINFO);
if (!GetCursorInfo(&cursor_info)) {
LOG_F(LS_ERROR) << "Unable to get cursor info. Error = " << GetLastError();
return;
}
if (last_cursor_ != cursor_info.hCursor) {
last_cursor_ = cursor_info.hCursor;
// Note that |cursor_info.hCursor| does not need to be freed.
scoped_ptr<MouseCursor> cursor(
CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor));
if (cursor.get())
callback_->OnMouseCursor(cursor.release());
}
if (mode_ != SHAPE_AND_POSITION)
return;
DesktopVector position(cursor_info.ptScreenPos.x, cursor_info.ptScreenPos.y);
bool inside = cursor_info.flags == CURSOR_SHOWING;
if (window_) {
RECT rect;
if (!GetWindowRect(window_, &rect)) {
position.set(0, 0);
inside = false;
} else {
position = position.subtract(DesktopVector(rect.left, rect.top));
if (inside)
inside = (window_ == WindowFromPoint(cursor_info.ptScreenPos));
}
}
callback_->OnMouseCursorPosition(inside ? INSIDE : OUTSIDE, position);
}
MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
const DesktopCaptureOptions& options, WindowId window) {
return new MouseCursorMonitorWin(reinterpret_cast<HWND>(window));
}
MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
const DesktopCaptureOptions& options) {
return new MouseCursorMonitorWin(NULL);
}
} // namespace webrtc