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

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

Issue 10894050: Remove support for Windows-style keycodes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Linux EventExecutor typo. Created 8 years, 3 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
« no previous file with comments | « remoting/host/client_session_unittest.cc ('k') | remoting/host/event_executor_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <set> 7 #include <set>
8 8
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 #include <X11/XF86keysym.h>
11 #include <X11/keysym.h>
12 #include <X11/extensions/XTest.h> 10 #include <X11/extensions/XTest.h>
13 11
14 #include "base/basictypes.h" 12 #include "base/basictypes.h"
15 #include "base/bind.h" 13 #include "base/bind.h"
16 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
17 #include "base/location.h" 15 #include "base/location.h"
18 #include "base/logging.h" 16 #include "base/logging.h"
19 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
20 #include "remoting/proto/internal.pb.h" 18 #include "remoting/proto/internal.pb.h"
21 #include "third_party/skia/include/core/SkPoint.h" 19 #include "third_party/skia/include/core/SkPoint.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 return (dx > 0 ? 6 : 7); 95 return (dx > 0 ? 6 : 7);
98 } 96 }
99 97
100 98
101 int VerticalScrollWheelToX11ButtonNumber(int dy) { 99 int VerticalScrollWheelToX11ButtonNumber(int dy) {
102 // Positive y-values are wheel scroll-up events (button 4), negative y-values 100 // Positive y-values are wheel scroll-up events (button 4), negative y-values
103 // are wheel scroll-down events (button 5). 101 // are wheel scroll-down events (button 5).
104 return (dy > 0 ? 4 : 5); 102 return (dy > 0 ? 4 : 5);
105 } 103 }
106 104
107 // Hard-coded mapping from Virtual Key codes to X11 KeySyms.
108 // This mapping is only valid if both client and host are using a
109 // US English keyboard layout.
110 // Because we're passing VK codes on the wire, with no Scancode,
111 // "extended" flag, etc, things like distinguishing left & right
112 // Shift keys doesn't work.
113 //
114 // TODO(wez): Replace this with something more closely tied to what
115 // WebInputEventFactory does on Linux/GTK, and which respects the
116 // host's keyboard layout (see http://crbug.com/74550 ).
117 const int kUsVkeyToKeysym[256] = {
118 // 0x00 - 0x07
119 -1, -1, -1, XK_Cancel,
120 // 0x04 - 0x07
121 -1, -1, -1, -1,
122 // 0x08 - 0x0B
123 XK_BackSpace, XK_Tab, -1, -1,
124 // 0x0C - 0x0F
125 XK_Clear, XK_Return, -1, -1,
126
127 // 0x10 - 0x13
128 XK_Shift_L, XK_Control_L, XK_Alt_L, XK_Pause,
129 // 0x14 - 0x17
130 XK_Caps_Lock, XK_Kana_Shift, -1, XK_Hangul_Jeonja,
131 // 0x18 - 0x1B
132 XK_Hangul_End, XK_Kanji, -1, XK_Escape,
133 // 0x1C - 0x1F
134 XK_Henkan, XK_Muhenkan, /* VKEY_ACCEPT */ -1, XK_Mode_switch,
135
136 // 0x20 - 0x23
137 XK_space, XK_Prior, XK_Next, XK_End,
138 // 0x24 - 0x27
139 XK_Home, XK_Left, XK_Up, XK_Right,
140 // 0x28 - 0x2B
141 XK_Down, XK_Select, /* VK_PRINT */ -1, XK_Execute,
142 // 0x2C - 0x2F
143 XK_Print, XK_Insert, XK_Delete, XK_Help,
144
145 // 0x30 - 0x33
146 XK_0, XK_1, XK_2, XK_3,
147 // 0x34 - 0x37
148 XK_4, XK_5, XK_6, XK_7,
149 // 0x38 - 0x3B
150 XK_8, XK_9, -1, -1,
151 // 0x3C - 0x3F
152 -1, -1, -1, -1,
153
154 // 0x40 - 0x43
155 -1, XK_A, XK_B, XK_C,
156 // 0x44 - 0x47
157 XK_D, XK_E, XK_F, XK_G,
158 // 0x48 - 0x4B
159 XK_H, XK_I, XK_J, XK_K,
160 // 0x4C - 0x4F
161 XK_L, XK_M, XK_N, XK_O,
162
163 // 0x50 - 0x53
164 XK_P, XK_Q, XK_R, XK_S,
165 // 0x54 - 0x57
166 XK_T, XK_U, XK_V, XK_W,
167 // 0x58 - 0x5B
168 XK_X, XK_Y, XK_Z, XK_Super_L,
169 // 0x5C - 0x5F
170 XK_Super_R, XK_Menu, -1, /* VKEY_SLEEP */ -1,
171
172 // 0x60 - 0x63
173 XK_KP_0, XK_KP_1, XK_KP_2, XK_KP_3,
174 // 0x64 - 0x67
175 XK_KP_4, XK_KP_5, XK_KP_6, XK_KP_7,
176 // 0x68 - 0x6B
177 XK_KP_8, XK_KP_9, XK_KP_Multiply, XK_KP_Add,
178 // 0x6C - 0x6F
179 XK_KP_Separator, XK_KP_Subtract, XK_KP_Decimal, XK_KP_Divide,
180
181 // 0x70 - 0x73
182 XK_F1, XK_F2, XK_F3, XK_F4,
183 // 0x74 - 0x77
184 XK_F5, XK_F6, XK_F7, XK_F8,
185 // 0x78 - 0x7B
186 XK_F9, XK_F10, XK_F11, XK_F12,
187 // 0x7C - 0x7F
188 XK_F13, XK_F14, XK_F15, XK_F16,
189
190 // 0x80 - 0x83
191 XK_F17, XK_F18, XK_F19, XK_F20,
192 // 0x84 - 0x87
193 XK_F21, XK_F22, XK_F23, XK_F24,
194 // 0x88 - 0x8B
195 -1, -1, -1, -1,
196 // 0x8C - 0x8F
197 -1, -1, -1, -1,
198
199 // 0x90 - 0x93
200 XK_Num_Lock, XK_Scroll_Lock, -1, -1,
201 // 0x94 - 0x97
202 -1, -1, -1, -1,
203 // 0x98 - 0x9B
204 -1, -1, -1, -1,
205 // 0x9C - 0x9F
206 -1, -1, -1, -1,
207
208 // 0xA0 - 0xA3
209 XK_Shift_L, XK_Shift_R, XK_Control_L, XK_Control_R,
210 // 0xA4 - 0xA7
211 XK_Meta_L, XK_Meta_R, XF86XK_Back, XF86XK_Forward,
212 // 0xA8 - 0xAB
213 XF86XK_Refresh, XF86XK_Stop, XF86XK_Search, XF86XK_Favorites,
214 // 0xAC - 0xAF
215 XF86XK_HomePage, XF86XK_AudioMute, XF86XK_AudioLowerVolume,
216 XF86XK_AudioRaiseVolume,
217
218 // 0xB0 - 0xB3
219 XF86XK_AudioNext, XF86XK_AudioPrev, XF86XK_AudioStop, XF86XK_AudioPause,
220 // 0xB4 - 0xB7
221 XF86XK_Mail, XF86XK_AudioMedia, XF86XK_Launch0, XF86XK_Launch1,
222 // 0xB8 - 0xBB
223 -1, -1, XK_semicolon, XK_plus,
224 // 0xBC - 0xBF
225 XK_comma, XK_minus, XK_period, XK_slash,
226
227 // 0xC0 - 0xC3
228 XK_grave, -1, -1, -1,
229 // 0xC4 - 0xC7
230 -1, -1, -1, -1,
231 // 0xC8 - 0xCB
232 -1, -1, -1, -1,
233 // 0xCC - 0xCF
234 -1, -1, -1, -1,
235
236 // 0xD0 - 0xD3
237 -1, -1, -1, -1,
238 // 0xD4 - 0xD7
239 -1, -1, -1, -1,
240 // 0xD8 - 0xDB
241 -1, -1, -1, XK_bracketleft,
242 // 0xDC - 0xDF
243 XK_backslash, XK_bracketright, XK_apostrophe,
244 /* VKEY_OEM_8 */ -1,
245
246 // 0xE0 - 0xE3
247 -1, -1, /* VKEY_OEM_102 */ -1, -1,
248 // 0xE4 - 0xE7
249 -1, /* VKEY_PROCESSKEY */ -1, -1, /* VKEY_PACKET */ -1,
250 // 0xE8 - 0xEB
251 -1, -1, -1, -1,
252 // 0xEC - 0xEF
253 -1, -1, -1, -1,
254
255 // 0xF0 - 0xF3
256 -1, -1, -1, -1,
257 // 0xF4 - 0xF7
258 -1, -1, /* VKEY_ATTN */ -1, /* VKEY_CRSEL */ -1,
259 // 0xF8 - 0xFB
260 /* VKEY_EXSEL */ -1, /* VKEY_EREOF */ -1, /* VKEY_PLAY */ -1,
261 /* VKEY_ZOOM */ -1,
262 // 0xFC - 0xFF
263 /* VKEY_NONAME */ -1, /* VKEY_PA1 */ -1, /* VKEY_OEM_CLEAR */ -1, -1
264 };
265
266 int ChromotocolKeycodeToX11Keysym(int32_t keycode) {
267 if (keycode < 0 || keycode > 255)
268 return kInvalidKeycode;
269
270 return kUsVkeyToKeysym[keycode];
271 }
272
273 EventExecutorLinux::EventExecutorLinux( 105 EventExecutorLinux::EventExecutorLinux(
274 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 106 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
275 : task_runner_(task_runner), 107 : task_runner_(task_runner),
276 latest_mouse_position_(SkIPoint::Make(-1, -1)), 108 latest_mouse_position_(SkIPoint::Make(-1, -1)),
277 display_(XOpenDisplay(NULL)), 109 display_(XOpenDisplay(NULL)),
278 root_window_(BadValue) { 110 root_window_(BadValue) {
279 } 111 }
280 112
281 EventExecutorLinux::~EventExecutorLinux() { 113 EventExecutorLinux::~EventExecutorLinux() {
282 CHECK(pressed_keys_.empty()); 114 CHECK(pressed_keys_.empty());
(...skipping 20 matching lines...) Expand all
303 return true; 135 return true;
304 } 136 }
305 137
306 void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { 138 void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) {
307 // TODO(simonmorris): Implement clipboard injection. 139 // TODO(simonmorris): Implement clipboard injection.
308 } 140 }
309 141
310 void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { 142 void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) {
311 // HostEventDispatcher should filter events missing the pressed field. 143 // HostEventDispatcher should filter events missing the pressed field.
312 DCHECK(event.has_pressed()); 144 DCHECK(event.has_pressed());
145 DCHECK(event.has_usb_keycode());
313 146
314 if (!task_runner_->BelongsToCurrentThread()) { 147 if (!task_runner_->BelongsToCurrentThread()) {
315 task_runner_->PostTask( 148 task_runner_->PostTask(
316 FROM_HERE, 149 FROM_HERE,
317 base::Bind(&EventExecutorLinux::InjectKeyEvent, base::Unretained(this), 150 base::Bind(&EventExecutorLinux::InjectKeyEvent, base::Unretained(this),
318 event)); 151 event));
319 return; 152 return;
320 } 153 }
321 154
322 int keycode = kInvalidKeycode; 155 int keycode = UsbKeycodeToNativeKeycode(event.usb_keycode());
323 if (event.has_usb_keycode()) { 156 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode()
324 keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); 157 << " to keycode: " << keycode << std::dec;
325 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode()
326 << " to keycode: " << keycode << std::dec;
327 } else if (event.has_keycode()) {
328 // Fall back to keysym translation.
329 // TODO(garykac) Remove this once we switch entirely over to USB keycodes.
330 int keysym = ChromotocolKeycodeToX11Keysym(event.keycode());
331 keycode = XKeysymToKeycode(display_, keysym);
332 VLOG(3) << "Converting VKEY: " << std::hex << event.keycode()
333 << " to keysym: " << keysym
334 << " to keycode: " << keycode << std::dec;
335 }
336 158
337 // Ignore events with no VK- or USB-keycode, or which can't be mapped. 159 // Ignore events which can't be mapped.
338 if (keycode == kInvalidKeycode) 160 if (keycode == kInvalidKeycode)
339 return; 161 return;
340 162
341 if (event.pressed()) { 163 if (event.pressed()) {
342 if (pressed_keys_.find(keycode) != pressed_keys_.end()) { 164 if (pressed_keys_.find(keycode) != pressed_keys_.end()) {
343 // Key is already held down, so lift the key up to ensure this repeated 165 // Key is already held down, so lift the key up to ensure this repeated
344 // press takes effect. 166 // press takes effect.
345 XTestFakeKeyEvent(display_, keycode, False, CurrentTime); 167 XTestFakeKeyEvent(display_, keycode, False, CurrentTime);
346 } else { 168 } else {
347 // Key is not currently held down, so disable auto-repeat for this 169 // Key is not currently held down, so disable auto-repeat for this
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 276 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
455 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { 277 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
456 scoped_ptr<EventExecutorLinux> executor( 278 scoped_ptr<EventExecutorLinux> executor(
457 new EventExecutorLinux(main_task_runner)); 279 new EventExecutorLinux(main_task_runner));
458 if (!executor->Init()) 280 if (!executor->Init())
459 return scoped_ptr<EventExecutor>(NULL); 281 return scoped_ptr<EventExecutor>(NULL);
460 return executor.PassAs<EventExecutor>(); 282 return executor.PassAs<EventExecutor>();
461 } 283 }
462 284
463 } // namespace remoting 285 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/client_session_unittest.cc ('k') | remoting/host/event_executor_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698