blob: 82f7d2447fb71c45ede20dbadbb62967527a157c [file] [log] [blame]
sergeyu@chromium.orgaf54d4b2013-10-16 02:42:38 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
12
sergeyu@chromium.org2873c4c2013-10-17 19:47:18 +000013#include "webrtc/modules/desktop_capture/desktop_frame.h"
14#include "webrtc/modules/desktop_capture/mouse_cursor.h"
15#include "webrtc/modules/desktop_capture/win/cursor.h"
16#include "webrtc/system_wrappers/interface/logging.h"
sergeyu@chromium.orgaf54d4b2013-10-16 02:42:38 +000017
18namespace webrtc {
19
sergeyu@chromium.org2873c4c2013-10-17 19:47:18 +000020class MouseCursorMonitorWin : public MouseCursorMonitor {
21 public:
22 explicit MouseCursorMonitorWin(HWND window);
23 virtual ~MouseCursorMonitorWin();
24
25 virtual void Init(Callback* callback, Mode mode) OVERRIDE;
26 virtual void Capture() OVERRIDE;
27
28 private:
29 HWND window_;
30
31 Callback* callback_;
32 Mode mode_;
33
34 HDC desktop_dc_;
35
36 HCURSOR last_cursor_;
37};
38
39MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window)
40 : window_(window),
41 callback_(NULL),
42 mode_(SHAPE_AND_POSITION),
43 desktop_dc_(NULL),
44 last_cursor_(NULL) {
45}
46
47MouseCursorMonitorWin::~MouseCursorMonitorWin() {
48 if (desktop_dc_)
49 ReleaseDC(NULL, desktop_dc_);
50}
51
52void MouseCursorMonitorWin::Init(Callback* callback, Mode mode) {
53 assert(!callback_);
54 assert(callback);
55
56 callback_ = callback;
57 mode_ = mode;
58
59 desktop_dc_ = GetDC(NULL);
60}
61
62void MouseCursorMonitorWin::Capture() {
63 assert(callback_);
64
65 CURSORINFO cursor_info;
66 cursor_info.cbSize = sizeof(CURSORINFO);
67 if (!GetCursorInfo(&cursor_info)) {
68 LOG_F(LS_ERROR) << "Unable to get cursor info. Error = " << GetLastError();
69 return;
70 }
71
72 if (last_cursor_ != cursor_info.hCursor) {
73 last_cursor_ = cursor_info.hCursor;
74 // Note that |cursor_info.hCursor| does not need to be freed.
75 scoped_ptr<MouseCursor> cursor(
76 CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor));
77 if (cursor.get())
78 callback_->OnMouseCursor(cursor.release());
79 }
80
81 if (mode_ != SHAPE_AND_POSITION)
82 return;
83
84 DesktopVector position(cursor_info.ptScreenPos.x, cursor_info.ptScreenPos.y);
85 bool inside = cursor_info.flags == CURSOR_SHOWING;
86
87 if (window_) {
88 RECT rect;
89 if (!GetWindowRect(window_, &rect)) {
90 position.set(0, 0);
91 inside = false;
92 } else {
93 position = position.subtract(DesktopVector(rect.left, rect.top));
94 if (inside)
95 inside = (window_ == WindowFromPoint(cursor_info.ptScreenPos));
96 }
97 }
98
99 callback_->OnMouseCursorPosition(inside ? INSIDE : OUTSIDE, position);
100}
101
sergeyu@chromium.orgaf54d4b2013-10-16 02:42:38 +0000102MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
103 const DesktopCaptureOptions& options, WindowId window) {
sergeyu@chromium.org2873c4c2013-10-17 19:47:18 +0000104 return new MouseCursorMonitorWin(reinterpret_cast<HWND>(window));
sergeyu@chromium.orgaf54d4b2013-10-16 02:42:38 +0000105}
106
107MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
108 const DesktopCaptureOptions& options) {
sergeyu@chromium.org2873c4c2013-10-17 19:47:18 +0000109 return new MouseCursorMonitorWin(NULL);
sergeyu@chromium.orgaf54d4b2013-10-16 02:42:38 +0000110}
111
112} // namespace webrtc