Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc

Issue 1959863002: CURSORINFO.flags should be checked before capturing its bitmap (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Send an empty bitmap if cursor is suppressed, send a default arrow if cursor is hidden. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h" 11 #include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <string.h>
14 15
15 #include <memory> 16 #include <memory>
16 17
17 #include "webrtc/modules/desktop_capture/desktop_frame.h" 18 #include "webrtc/modules/desktop_capture/desktop_frame.h"
19 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
18 #include "webrtc/modules/desktop_capture/mouse_cursor.h" 20 #include "webrtc/modules/desktop_capture/mouse_cursor.h"
19 #include "webrtc/modules/desktop_capture/win/cursor.h" 21 #include "webrtc/modules/desktop_capture/win/cursor.h"
20 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h" 22 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
21 #include "webrtc/system_wrappers/include/logging.h" 23 #include "webrtc/system_wrappers/include/logging.h"
22 24
23 namespace webrtc { 25 namespace webrtc {
24 26
27 namespace {
28
29 bool Equal(const CURSORINFO& left, const CURSORINFO& right) {
Sergey Ulanov 2016/05/12 23:23:33 Rename this to IsSameCursorShape(). This function
Hzj_jie 2016/05/13 01:05:28 Done.
30 if (left.flags == right.flags) {
Sergey Ulanov 2016/05/12 23:23:33 You can express the whole function with a single r
Hzj_jie 2016/05/13 01:05:28 Done.
31 // If the cursors are not showing, we do not care the hCursor handle.
32 return left.flags != CURSOR_SHOWING ||
33 left.hCursor == right.hCursor;
34 }
35 return false;
36 }
37
38 } // namespace
39
25 class MouseCursorMonitorWin : public MouseCursorMonitor { 40 class MouseCursorMonitorWin : public MouseCursorMonitor {
26 public: 41 public:
27 explicit MouseCursorMonitorWin(HWND window); 42 explicit MouseCursorMonitorWin(HWND window);
28 explicit MouseCursorMonitorWin(ScreenId screen); 43 explicit MouseCursorMonitorWin(ScreenId screen);
29 virtual ~MouseCursorMonitorWin(); 44 virtual ~MouseCursorMonitorWin();
30 45
31 void Init(Callback* callback, Mode mode) override; 46 void Init(Callback* callback, Mode mode) override;
32 void Capture() override; 47 void Capture() override;
33 48
34 private: 49 private:
35 // Get the rect of the currently selected screen, relative to the primary 50 // Get the rect of the currently selected screen, relative to the primary
36 // display's top-left. If the screen is disabled or disconnected, or any error 51 // display's top-left. If the screen is disabled or disconnected, or any error
37 // happens, an empty rect is returned. 52 // happens, an empty rect is returned.
38 DesktopRect GetScreenRect(); 53 DesktopRect GetScreenRect();
39 54
40 HWND window_; 55 HWND window_;
41 ScreenId screen_; 56 ScreenId screen_;
42 57
43 Callback* callback_; 58 Callback* callback_;
44 Mode mode_; 59 Mode mode_;
45 60
46 HDC desktop_dc_; 61 HDC desktop_dc_;
47 62
48 HCURSOR last_cursor_; 63 // The last CURSORINFO (converted to MouseCursor) we have sent to the client.
64 CURSORINFO last_cursor_;
49 }; 65 };
50 66
51 MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window) 67 MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window)
52 : window_(window), 68 : window_(window),
53 screen_(kInvalidScreenId), 69 screen_(kInvalidScreenId),
54 callback_(NULL), 70 callback_(NULL),
55 mode_(SHAPE_AND_POSITION), 71 mode_(SHAPE_AND_POSITION),
56 desktop_dc_(NULL), 72 desktop_dc_(NULL) {
57 last_cursor_(NULL) { 73 memset(&last_cursor_, 0, sizeof(CURSORINFO));
58 } 74 }
59 75
60 MouseCursorMonitorWin::MouseCursorMonitorWin(ScreenId screen) 76 MouseCursorMonitorWin::MouseCursorMonitorWin(ScreenId screen)
61 : window_(NULL), 77 : window_(NULL),
62 screen_(screen), 78 screen_(screen),
63 callback_(NULL), 79 callback_(NULL),
64 mode_(SHAPE_AND_POSITION), 80 mode_(SHAPE_AND_POSITION),
65 desktop_dc_(NULL), 81 desktop_dc_(NULL) {
66 last_cursor_(NULL) {
67 assert(screen >= kFullDesktopScreenId); 82 assert(screen >= kFullDesktopScreenId);
83 memset(&last_cursor_, 0, sizeof(CURSORINFO));
68 } 84 }
69 85
70 MouseCursorMonitorWin::~MouseCursorMonitorWin() { 86 MouseCursorMonitorWin::~MouseCursorMonitorWin() {
71 if (desktop_dc_) 87 if (desktop_dc_)
72 ReleaseDC(NULL, desktop_dc_); 88 ReleaseDC(NULL, desktop_dc_);
73 } 89 }
74 90
75 void MouseCursorMonitorWin::Init(Callback* callback, Mode mode) { 91 void MouseCursorMonitorWin::Init(Callback* callback, Mode mode) {
76 assert(!callback_); 92 assert(!callback_);
77 assert(callback); 93 assert(callback);
78 94
79 callback_ = callback; 95 callback_ = callback;
80 mode_ = mode; 96 mode_ = mode;
81 97
82 desktop_dc_ = GetDC(NULL); 98 desktop_dc_ = GetDC(NULL);
83 } 99 }
84 100
85 void MouseCursorMonitorWin::Capture() { 101 void MouseCursorMonitorWin::Capture() {
86 assert(callback_); 102 assert(callback_);
87 103
88 CURSORINFO cursor_info; 104 CURSORINFO cursor_info;
89 cursor_info.cbSize = sizeof(CURSORINFO); 105 cursor_info.cbSize = sizeof(CURSORINFO);
90 if (!GetCursorInfo(&cursor_info)) { 106 if (!GetCursorInfo(&cursor_info)) {
91 LOG_F(LS_ERROR) << "Unable to get cursor info. Error = " << GetLastError(); 107 LOG_F(LS_ERROR) << "Unable to get cursor info. Error = " << GetLastError();
92 return; 108 return;
93 } 109 }
94 110
95 if (last_cursor_ != cursor_info.hCursor) { 111 if (!Equal(cursor_info, last_cursor_)) {
96 last_cursor_ = cursor_info.hCursor; 112 if (cursor_info.flags == CURSOR_SUPPRESSED) {
97 // Note that |cursor_info.hCursor| does not need to be freed. 113 // The cursor is intentionally hidden now, send an empty bitmap.
98 std::unique_ptr<MouseCursor> cursor( 114 last_cursor_ = cursor_info;
99 CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor)); 115 callback_->OnMouseCursor(new MouseCursor(
100 if (cursor.get()) 116 new BasicDesktopFrame(DesktopSize()), DesktopVector()));
101 callback_->OnMouseCursor(cursor.release()); 117 } else {
118 // Note that |cursor_info.hCursor| does not need to be freed.
Sergey Ulanov 2016/05/12 23:23:33 move this comment below, where we call CreateMouse
Hzj_jie 2016/05/13 01:05:28 According to MSDN http://shortn/_FXmsigcgUC (You m
Sergey Ulanov 2016/05/13 21:32:40 Please don't use shortn links in code reviews - th
119 if (cursor_info.flags == 0) {
120 // Host machine does not have a hardware mouse attached, we will send a
121 // default one instead.
122 // Note, Windows automatically caches cursor resource, so we do not need
123 // to cache the result of LoadCursor.
124 cursor_info.hCursor = LoadCursor(nullptr, IDC_ARROW);
Sergey Ulanov 2016/05/12 23:23:33 I think you also need to CloseHandle() for the han
Hzj_jie 2016/05/13 01:05:28 Done.
125 }
126 std::unique_ptr<MouseCursor> cursor(
127 CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor));
128 if (cursor) {
129 last_cursor_ = cursor_info;
130 callback_->OnMouseCursor(cursor.release());
131 }
132 }
102 } 133 }
103 134
104 if (mode_ != SHAPE_AND_POSITION) 135 if (mode_ != SHAPE_AND_POSITION)
105 return; 136 return;
106 137
107 DesktopVector position(cursor_info.ptScreenPos.x, cursor_info.ptScreenPos.y); 138 DesktopVector position(cursor_info.ptScreenPos.x, cursor_info.ptScreenPos.y);
108 bool inside = cursor_info.flags == CURSOR_SHOWING; 139 bool inside = cursor_info.flags == CURSOR_SHOWING;
109 140
110 if (window_) { 141 if (window_) {
111 DesktopRect original_rect; 142 DesktopRect original_rect;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 return new MouseCursorMonitorWin(reinterpret_cast<HWND>(window)); 197 return new MouseCursorMonitorWin(reinterpret_cast<HWND>(window));
167 } 198 }
168 199
169 MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( 200 MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
170 const DesktopCaptureOptions& options, 201 const DesktopCaptureOptions& options,
171 ScreenId screen) { 202 ScreenId screen) {
172 return new MouseCursorMonitorWin(screen); 203 return new MouseCursorMonitorWin(screen);
173 } 204 }
174 205
175 } // namespace webrtc 206 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698