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

Side by Side Diff: remoting/host/event_executor_win.cc

Issue 10381115: [Chromoting] The Windows IT2Me host gets any new text items it finds on the clipboard. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move ClipboardWin to the UI thread, and tidy up. Created 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/event_executor.h" 5 #include "remoting/host/event_executor.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/message_loop_proxy.h"
12 #include "remoting/host/capturer.h" 13 #include "remoting/host/capturer.h"
13 #include "remoting/host/clipboard.h" 14 #include "remoting/host/clipboard.h"
14 #include "remoting/proto/event.pb.h" 15 #include "remoting/proto/event.pb.h"
15 #include "ui/base/keycodes/keyboard_codes.h" 16 #include "ui/base/keycodes/keyboard_codes.h"
16 17
17 namespace remoting { 18 namespace remoting {
18 19
19 namespace { 20 namespace {
20 21
21 using protocol::ClipboardEvent; 22 using protocol::ClipboardEvent;
22 using protocol::KeyEvent; 23 using protocol::KeyEvent;
23 using protocol::MouseEvent; 24 using protocol::MouseEvent;
24 25
25 // USB to XKB keycode map table. 26 // USB to XKB keycode map table.
26 #define USB_KEYMAP(usb, xkb, win, mac) {usb, win} 27 #define USB_KEYMAP(usb, xkb, win, mac) {usb, win}
27 #include "remoting/host/usb_keycode_map.h" 28 #include "remoting/host/usb_keycode_map.h"
28 #undef USB_KEYMAP 29 #undef USB_KEYMAP
29 30
30 // A class to generate events on Windows. 31 // A class to generate events on Windows.
31 class EventExecutorWin : public EventExecutor { 32 class EventExecutorWin : public EventExecutor {
32 public: 33 public:
33 EventExecutorWin(MessageLoop* message_loop, Capturer* capturer); 34 EventExecutorWin(MessageLoop* message_loop,
35 base::MessageLoopProxy* ui_loop,
36 Capturer* capturer);
34 virtual ~EventExecutorWin() {} 37 virtual ~EventExecutorWin() {}
35 38
36 // ClipboardStub interface. 39 // ClipboardStub interface.
37 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; 40 virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE;
38 41
39 // InputStub interface. 42 // InputStub interface.
40 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; 43 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE;
41 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; 44 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE;
42 45
43 // EventExecutor interface. 46 // EventExecutor interface.
44 virtual void OnSessionStarted() OVERRIDE; 47 virtual void OnSessionStarted() OVERRIDE;
45 virtual void OnSessionFinished() OVERRIDE; 48 virtual void OnSessionFinished() OVERRIDE;
46 49
47 private: 50 private:
48 HKL GetForegroundKeyboardLayout(); 51 HKL GetForegroundKeyboardLayout();
52 void HandleClipboard(const ClipboardEvent& event);
49 void HandleKey(const KeyEvent& event); 53 void HandleKey(const KeyEvent& event);
50 void HandleMouse(const MouseEvent& event); 54 void HandleMouse(const MouseEvent& event);
51 void HandleSessionStarted(); 55 void HandleSessionStarted();
52 void HandleSessionFinished(); 56 void HandleSessionFinished();
53 57
54 MessageLoop* message_loop_; 58 MessageLoop* message_loop_;
59 base::MessageLoopProxy* ui_loop_;
55 Capturer* capturer_; 60 Capturer* capturer_;
56 scoped_ptr<Clipboard> clipboard_; 61 scoped_ptr<Clipboard> clipboard_;
57 62
58 DISALLOW_COPY_AND_ASSIGN(EventExecutorWin); 63 DISALLOW_COPY_AND_ASSIGN(EventExecutorWin);
59 }; 64 };
60 65
61 EventExecutorWin::EventExecutorWin(MessageLoop* message_loop, 66 EventExecutorWin::EventExecutorWin(MessageLoop* message_loop,
67 base::MessageLoopProxy* ui_loop,
62 Capturer* capturer) 68 Capturer* capturer)
63 : message_loop_(message_loop), 69 : message_loop_(message_loop),
70 ui_loop_(ui_loop),
64 capturer_(capturer), 71 capturer_(capturer),
65 clipboard_(Clipboard::Create()) { 72 clipboard_(Clipboard::Create()) {
66 } 73 }
67 74
68 void EventExecutorWin::InjectClipboardEvent(const ClipboardEvent& event) { 75 void EventExecutorWin::InjectClipboardEvent(const ClipboardEvent& event) {
69 if (MessageLoop::current() != message_loop_) { 76 ui_loop_->PostTask(
Wez 2012/05/15 23:46:19 You could test if (!ui_loop_->BelongsToCurrentThre
simonmorris 2012/05/16 00:41:33 Done. (I liked the consistency of having a separat
70 message_loop_->PostTask( 77 FROM_HERE,
71 FROM_HERE, 78 base::Bind(&EventExecutorWin::HandleClipboard,
72 base::Bind(&EventExecutorWin::InjectClipboardEvent, 79 base::Unretained(this),
Wez 2012/05/15 23:46:19 Doesn't this mean we risk a crash if a clipboard e
simonmorris 2012/05/16 00:41:33 No more than with InjectKeyEvent() and InjectMouse
73 base::Unretained(this), 80 event));
74 event));
75 return;
76 }
77
78 clipboard_->InjectClipboardEvent(event);
79 } 81 }
80 82
81 void EventExecutorWin::InjectKeyEvent(const KeyEvent& event) { 83 void EventExecutorWin::InjectKeyEvent(const KeyEvent& event) {
82 if (MessageLoop::current() != message_loop_) { 84 if (MessageLoop::current() != message_loop_) {
83 message_loop_->PostTask( 85 message_loop_->PostTask(
84 FROM_HERE, 86 FROM_HERE,
85 base::Bind(&EventExecutorWin::InjectKeyEvent, base::Unretained(this), 87 base::Bind(&EventExecutorWin::InjectKeyEvent, base::Unretained(this),
86 event)); 88 event));
87 return; 89 return;
88 } 90 }
89 91
90 HandleKey(event); 92 HandleKey(event);
91 } 93 }
92 94
93 void EventExecutorWin::InjectMouseEvent(const MouseEvent& event) { 95 void EventExecutorWin::InjectMouseEvent(const MouseEvent& event) {
94 if (MessageLoop::current() != message_loop_) { 96 if (MessageLoop::current() != message_loop_) {
95 message_loop_->PostTask( 97 message_loop_->PostTask(
96 FROM_HERE, 98 FROM_HERE,
97 base::Bind(&EventExecutorWin::InjectMouseEvent, base::Unretained(this), 99 base::Bind(&EventExecutorWin::InjectMouseEvent, base::Unretained(this),
98 event)); 100 event));
99 return; 101 return;
100 } 102 }
101 103
102 HandleMouse(event); 104 HandleMouse(event);
103 } 105 }
104 106
105 void EventExecutorWin::OnSessionStarted() { 107 void EventExecutorWin::OnSessionStarted() {
106 if (MessageLoop::current() != message_loop_) { 108 ui_loop_->PostTask(
Wez 2012/05/15 23:46:19 As above, with an if (BelongsToCurrentThread()) te
simonmorris 2012/05/16 00:41:33 Done.
107 message_loop_->PostTask( 109 FROM_HERE,
108 FROM_HERE, 110 base::Bind(&EventExecutorWin::HandleSessionStarted,
109 base::Bind(&EventExecutorWin::OnSessionStarted, 111 base::Unretained(this)));
110 base::Unretained(this)));
111 return;
112 }
113
114 HandleSessionStarted();
115 } 112 }
116 113
117 void EventExecutorWin::OnSessionFinished() { 114 void EventExecutorWin::OnSessionFinished() {
118 if (MessageLoop::current() != message_loop_) { 115 ui_loop_->PostTask(
119 message_loop_->PostTask( 116 FROM_HERE,
120 FROM_HERE, 117 base::Bind(&EventExecutorWin::HandleSessionFinished,
121 base::Bind(&EventExecutorWin::OnSessionFinished, 118 base::Unretained(this)));
122 base::Unretained(this)));
123 return;
124 }
125
126 HandleSessionFinished();
127 } 119 }
128 120
129 HKL EventExecutorWin::GetForegroundKeyboardLayout() { 121 HKL EventExecutorWin::GetForegroundKeyboardLayout() {
130 HKL layout = 0; 122 HKL layout = 0;
131 123
132 // Can return NULL if a window is losing focus. 124 // Can return NULL if a window is losing focus.
133 HWND foreground = GetForegroundWindow(); 125 HWND foreground = GetForegroundWindow();
134 if (foreground) { 126 if (foreground) {
135 // Can return 0 if the window no longer exists. 127 // Can return 0 if the window no longer exists.
136 DWORD thread_id = GetWindowThreadProcessId(foreground, 0); 128 DWORD thread_id = GetWindowThreadProcessId(foreground, 0);
137 if (thread_id) { 129 if (thread_id) {
138 // Can return 0 if the thread no longer exists, or if we're 130 // Can return 0 if the thread no longer exists, or if we're
139 // running on Windows Vista and the window is a command-prompt. 131 // running on Windows Vista and the window is a command-prompt.
140 layout = GetKeyboardLayout(thread_id); 132 layout = GetKeyboardLayout(thread_id);
141 } 133 }
142 } 134 }
143 135
144 // If we couldn't determine a layout then use the system default. 136 // If we couldn't determine a layout then use the system default.
145 if (!layout) { 137 if (!layout) {
146 SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, &layout, 0); 138 SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, &layout, 0);
147 } 139 }
148 140
149 return layout; 141 return layout;
150 } 142 }
151 143
144 void EventExecutorWin::HandleClipboard(const ClipboardEvent& event) {
145 clipboard_->InjectClipboardEvent(event);
146 }
147
152 void EventExecutorWin::HandleKey(const KeyEvent& event) { 148 void EventExecutorWin::HandleKey(const KeyEvent& event) {
153 // HostEventDispatcher should filter events missing the pressed field. 149 // HostEventDispatcher should filter events missing the pressed field.
154 DCHECK(event.has_pressed()); 150 DCHECK(event.has_pressed());
155 151
156 // Reset the system idle suspend timeout. 152 // Reset the system idle suspend timeout.
157 SetThreadExecutionState(ES_SYSTEM_REQUIRED); 153 SetThreadExecutionState(ES_SYSTEM_REQUIRED);
158 154
159 // The mapping between scancodes and VKEY values depends on the foreground 155 // The mapping between scancodes and VKEY values depends on the foreground
160 // window's current keyboard layout. 156 // window's current keyboard layout.
161 HKL layout = GetForegroundKeyboardLayout(); 157 HKL layout = GetForegroundKeyboardLayout();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 void EventExecutorWin::HandleSessionStarted() { 277 void EventExecutorWin::HandleSessionStarted() {
282 clipboard_->Start(); 278 clipboard_->Start();
283 } 279 }
284 280
285 void EventExecutorWin::HandleSessionFinished() { 281 void EventExecutorWin::HandleSessionFinished() {
286 clipboard_->Stop(); 282 clipboard_->Stop();
287 } 283 }
288 284
289 } // namespace 285 } // namespace
290 286
291 scoped_ptr<EventExecutor> EventExecutor::Create( 287 scoped_ptr<EventExecutor> EventExecutor::Create(MessageLoop* message_loop,
292 MessageLoop* message_loop, Capturer* capturer) { 288 base::MessageLoopProxy* ui_loop,
289 Capturer* capturer) {
293 return scoped_ptr<EventExecutor>( 290 return scoped_ptr<EventExecutor>(
294 new EventExecutorWin(message_loop, capturer)); 291 new EventExecutorWin(message_loop, ui_loop, capturer));
295 } 292 }
296 293
297 } // namespace remoting 294 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698