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

Side by Side Diff: remoting/client/plugin/normalizing_input_filter_cros.cc

Issue 1228333004: Move code that doesn't depend on PPAPI out of remoting/client/plugin (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/client/plugin/normalizing_input_filter_cros.h"
6
7 #include "base/logging.h"
8 #include "remoting/protocol/usb_key_codes.h"
9
10 namespace remoting {
11
12 namespace {
13
14 // Returns true for OSKey codes.
15 static bool IsOsKey(unsigned int code) {
16 return code == kUsbLeftOs || code == kUsbRightOs;
17 }
18
19 // Returns true for the left-hand Alt key.
20 static bool IsLeftAltKey(unsigned int code) {
21 return code == kUsbLeftAlt;
22 }
23
24 // Returns true for codes generated by EventRewriter::RewriteFunctionKeys().
25 static bool IsRewrittenFunctionKey(unsigned int code) {
26 const unsigned int kUsbFunctionKeyMin = 0x07003a;
27 const unsigned int kUsbFunctionKeyMax = 0x070045;
28 return code >= kUsbFunctionKeyMin && code <= kUsbFunctionKeyMax;
29 }
30
31 // Returns true for codes generated by EventRewriter::RewriteExtendedKeys().
32 static bool IsRewrittenExtendedKey(unsigned int code) {
33 const unsigned int kUsbExtendedKeyMin = 0x070049;
34 const unsigned int kUsbExtendedKeyMax = 0x07004e;
35 return code >= kUsbExtendedKeyMin && code <= kUsbExtendedKeyMax;
36 }
37
38 // Returns true for codes generated by EventRewriter::Rewrite().
39 static bool IsRewrittenKey(unsigned int code) {
40 return IsRewrittenExtendedKey(code) || IsRewrittenFunctionKey(code);
41 }
42
43 } // namespace
44
45 // The input filter tries to avoid sending keydown/keyup events for OSKey
46 // (aka Search, WinKey, Cmd, Super) when it is used to rewrite other key events.
47 // Rewriting via other combinations is not currently handled.
48 //
49 // OSKey events can be categorised as one of three kinds:
50 // - Modifying - Holding the key down while executing other input modifies the
51 // effect of that input, e.g. OSKey+L causes the workstation to lock, e.g.
52 // OSKey + mouse-move performs an extended selection.
53 // - Rewriting (ChromeOS only) - Holding the key down while pressing certain
54 // keys causes them to be treated as different keys, e.g. OSKey causes the
55 // Down key to behave as PageDown.
56 // - Normal - Press & release of the key trigger an action, e.g. showing the
57 // Start menu.
58 //
59 // The input filter has four states:
60 // 1. No OSKey has been pressed.
61 // - When an OSKey keydown is received, the event is deferred, and we move to
62 // State #2.
63 // 2. An OSKey is pressed, but may be Normal, Rewriting or Modifying.
64 // - If the OSKey keyup is received, the key is Normal, both events are sent
65 // and we return to State #1.
66 // - If a Rewritten event is received we move to State #3.
67 // - If a Modified event is received the OSKey keydown is sent and we enter
68 // State #4.
69 // 3. An OSKey is pressed, and is being used to Rewrite other key events.
70 // - If the OSKey keyup is received then it is suppressed, and we move to
71 // State #1.
72 // - If a Modified event is received the OSKey keydown is sent and we enter
73 // State #4.
74 // - If a Rewritten event is received then we stay in State #3.
75 // 4. An OSKey is pressed, and is Modifying.
76 // - If the OSKey keyup is received then we send it and we move to State #1.
77 // - All other key event pass through the filter unchanged.
78 //
79 // ChromeOS also maps Alt+LeftClick to RightClick (even for an external mouse).
80 // As with the OSKey remapping described above, this is fed into this filter
81 // as Alt followed by RightClick. However, because there are other ways to
82 // generate RightClick (two-finger tap, for example), rather than suppressing
83 // the Alt key as we do for the OSKey (which would allow Alt+LeftClick to be
84 // interpreted as interpreted as RightClick as per the ChromeOS idiom), the
85 // filter maps RightClick to LeftClick while LeftAlt is held, which allows
86 // Alt+LeftClick to be injected. The equivalent mapping using RightAlt is
87 // unchanged, allowing Alt+RightClick also to be injected, as long as the
88 // target application doesn't distinguish between left and right Alt keys.
89 //
90 // This file must be kept up-to-date with changes to
91 // chrome/browser/chromeos/events/event_rewriter.cc
92
93
94 NormalizingInputFilterCros::NormalizingInputFilterCros(
95 protocol::InputStub* input_stub)
96 : protocol::InputFilter(input_stub),
97 deferred_key_is_rewriting_(false),
98 modifying_key_(0),
99 left_alt_is_pressed_(false),
100 previous_mouse_x_(-1),
101 previous_mouse_y_(-1) {
102 }
103
104 NormalizingInputFilterCros::~NormalizingInputFilterCros() {}
105
106 void NormalizingInputFilterCros::InjectKeyEvent(
107 const protocol::KeyEvent& event) {
108 DCHECK(event.has_usb_keycode());
109 DCHECK(event.has_pressed());
110
111 if (event.pressed()) {
112 ProcessKeyDown(event);
113 } else {
114 ProcessKeyUp(event);
115 }
116 }
117
118 void NormalizingInputFilterCros::InjectMouseEvent(
119 const protocol::MouseEvent& event) {
120 // If there's a rewriting/modifier decision pending, assume that it's
121 // intended to be used as a modifying key for this mouse event and send it.
122 if (deferred_keydown_event_.has_usb_keycode()) {
123 // TODO(jamiewalch): Until crbug.com/489468 is fixed, a spurious mouse move
124 // event is generated in response to certain key combinations, so check that
125 // this is actually an "interesting" event.
126 if (event.has_button() ||
127 event.x() != previous_mouse_x_ ||
128 event.y() != previous_mouse_y_) {
129 SwitchRewritingKeyToModifying();
130 }
131 }
132 previous_mouse_x_ = event.x();
133 previous_mouse_y_ = event.y();
134
135 protocol::MouseEvent newEvent = event;
136 if (left_alt_is_pressed_ &&
137 event.has_button() &&
138 event.button() == protocol::MouseEvent::BUTTON_RIGHT) {
139 newEvent.set_button(protocol::MouseEvent::BUTTON_LEFT);
140 }
141 InputFilter::InjectMouseEvent(newEvent);
142 }
143
144 void NormalizingInputFilterCros::ProcessKeyDown(
145 const protocol::KeyEvent& event) {
146 // If |event| is |deferred_keydown_event_| repeat then assume that the user is
147 // holding the key down rather than using it to Rewrite.
148 if (deferred_keydown_event_.has_usb_keycode() &&
149 deferred_keydown_event_.usb_keycode() == event.usb_keycode()) {
150 SwitchRewritingKeyToModifying();
151 }
152
153 // If |event| is a |modifying_key_| repeat then let it pass through.
154 if (modifying_key_ == event.usb_keycode()) {
155 InputFilter::InjectKeyEvent(event);
156 return;
157 }
158
159 // If |event| is for an OSKey and we don't know whether it's a Normal,
160 // Rewriting or Modifying use, then hold the keydown event.
161 if (IsOsKey(event.usb_keycode())) {
162 deferred_keydown_event_ = event;
163 deferred_key_is_rewriting_ = false;
164 return;
165 }
166
167 // If |event| is for a Rewritten key then set a flag to prevent any deferred
168 // OSKey keydown from being sent when keyup is received for it. Otherwise,
169 // inject the deferred OSKey keydown, if any, and switch that key into
170 // Modifying mode.
171 if (IsRewrittenKey(event.usb_keycode())) {
172 // Note that there may not be a deferred OSKey event if there is a full
173 // PC keyboard connected, which can generate e.g. PageDown without
174 // rewriting.
175 deferred_key_is_rewriting_ = true;
176 } else {
177 if (deferred_keydown_event_.has_usb_keycode())
178 SwitchRewritingKeyToModifying();
179 }
180
181 if (IsLeftAltKey(event.usb_keycode()))
182 left_alt_is_pressed_ = true;
183
184 InputFilter::InjectKeyEvent(event);
185 }
186
187 void NormalizingInputFilterCros::ProcessKeyUp(const protocol::KeyEvent& event) {
188 if (deferred_keydown_event_.has_usb_keycode() &&
189 deferred_keydown_event_.usb_keycode() == event.usb_keycode()) {
190 if (deferred_key_is_rewriting_) {
191 // If we never sent the keydown then don't send a keyup.
192 deferred_keydown_event_ = protocol::KeyEvent();
193 return;
194 }
195
196 // If the OSKey hasn't Rewritten anything then treat as Modifying.
197 SwitchRewritingKeyToModifying();
198 }
199
200 if (modifying_key_ == event.usb_keycode())
201 modifying_key_ = 0;
202
203 if (IsLeftAltKey(event.usb_keycode()))
204 left_alt_is_pressed_ = false;
205
206 InputFilter::InjectKeyEvent(event);
207 }
208
209 void NormalizingInputFilterCros::SwitchRewritingKeyToModifying() {
210 DCHECK(deferred_keydown_event_.has_usb_keycode());
211 modifying_key_ = deferred_keydown_event_.usb_keycode();
212 InputFilter::InjectKeyEvent(deferred_keydown_event_);
213 deferred_keydown_event_ = protocol::KeyEvent();
214 }
215
216 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698