sergeyu@chromium.org | af54d4b | 2013-10-16 02:42:38 +0000 | [diff] [blame] | 1 | /* |
| 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.org | 2873c4c | 2013-10-17 19:47:18 +0000 | [diff] [blame^] | 13 | #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.org | af54d4b | 2013-10-16 02:42:38 +0000 | [diff] [blame] | 17 | |
| 18 | namespace webrtc { |
| 19 | |
sergeyu@chromium.org | 2873c4c | 2013-10-17 19:47:18 +0000 | [diff] [blame^] | 20 | class 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 | |
| 39 | MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window) |
| 40 | : window_(window), |
| 41 | callback_(NULL), |
| 42 | mode_(SHAPE_AND_POSITION), |
| 43 | desktop_dc_(NULL), |
| 44 | last_cursor_(NULL) { |
| 45 | } |
| 46 | |
| 47 | MouseCursorMonitorWin::~MouseCursorMonitorWin() { |
| 48 | if (desktop_dc_) |
| 49 | ReleaseDC(NULL, desktop_dc_); |
| 50 | } |
| 51 | |
| 52 | void 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 | |
| 62 | void 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.org | af54d4b | 2013-10-16 02:42:38 +0000 | [diff] [blame] | 102 | MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( |
| 103 | const DesktopCaptureOptions& options, WindowId window) { |
sergeyu@chromium.org | 2873c4c | 2013-10-17 19:47:18 +0000 | [diff] [blame^] | 104 | return new MouseCursorMonitorWin(reinterpret_cast<HWND>(window)); |
sergeyu@chromium.org | af54d4b | 2013-10-16 02:42:38 +0000 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( |
| 108 | const DesktopCaptureOptions& options) { |
sergeyu@chromium.org | 2873c4c | 2013-10-17 19:47:18 +0000 | [diff] [blame^] | 109 | return new MouseCursorMonitorWin(NULL); |
sergeyu@chromium.org | af54d4b | 2013-10-16 02:42:38 +0000 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | } // namespace webrtc |