| OLD | NEW |
| 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 <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
| 8 #include <Carbon/Carbon.h> | 8 #include <Carbon/Carbon.h> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 // injection APIs. | 70 // injection APIs. |
| 71 // If the non-deprecated injection APIs were used instead, the equivalent of | 71 // If the non-deprecated injection APIs were used instead, the equivalent of |
| 72 // this line would not be needed, as OS X defaults to _not_ suppressing local | 72 // this line would not be needed, as OS X defaults to _not_ suppressing local |
| 73 // inputs in that case. | 73 // inputs in that case. |
| 74 #pragma clang diagnostic push | 74 #pragma clang diagnostic push |
| 75 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 75 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| 76 CGSetLocalEventsSuppressionInterval(0.0); | 76 CGSetLocalEventsSuppressionInterval(0.0); |
| 77 #pragma clang diagnostic pop | 77 #pragma clang diagnostic pop |
| 78 } | 78 } |
| 79 | 79 |
| 80 // Hard-coded mapping from Virtual Key codes to Mac KeySyms. | |
| 81 // This mapping is only valid if both client and host are using a | |
| 82 // US English keyboard layout. | |
| 83 // Because we're passing VK codes on the wire, with no Scancode, | |
| 84 // "extended" flag, etc, things like distinguishing left & right | |
| 85 // Shift keys doesn't work. | |
| 86 // | |
| 87 // TODO(wez): Replace this with something more closely tied to what | |
| 88 // WebInputEventFactory does on Linux/GTK, and which respects the | |
| 89 // host's keyboard layout. | |
| 90 // | |
| 91 // TODO(garykac): Remove this table once we switch to using USB | |
| 92 // keycodes. | |
| 93 const int kUsVkeyToKeysym[256] = { | |
| 94 // 0x00 - 0x07 | |
| 95 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 96 // 0x04 - 0x07 | |
| 97 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 98 // 0x08 - 0x0B | |
| 99 kVK_Delete, kVK_Tab, kInvalidKeycode, kInvalidKeycode, | |
| 100 // 0x0C - 0x0F | |
| 101 kInvalidKeycode, kVK_Return, kInvalidKeycode, kInvalidKeycode, | |
| 102 | |
| 103 // 0x10 - 0x13 | |
| 104 kVK_Shift, kVK_Control, kVK_Option, kInvalidKeycode, | |
| 105 // 0x14 - 0x17 | |
| 106 kVK_CapsLock, kVK_JIS_Kana, /* VKEY_HANGUL */ kInvalidKeycode, | |
| 107 /* VKEY_JUNJA */ kInvalidKeycode, | |
| 108 // 0x18 - 0x1B | |
| 109 /* VKEY_FINAL */ kInvalidKeycode, /* VKEY_Kanji */ kInvalidKeycode, | |
| 110 kInvalidKeycode, kVK_Escape, | |
| 111 // 0x1C - 0x1F | |
| 112 /* VKEY_CONVERT */ kInvalidKeycode, /* VKEY_NONCONVERT */ kInvalidKeycode, | |
| 113 /* VKEY_ACCEPT */ kInvalidKeycode, /* VKEY_MODECHANGE */ kInvalidKeycode, | |
| 114 | |
| 115 // 0x20 - 0x23 | |
| 116 kVK_Space, kVK_PageUp, kVK_PageDown, kVK_End, | |
| 117 // 0x24 - 0x27 | |
| 118 kVK_Home, kVK_LeftArrow, kVK_UpArrow, kVK_RightArrow, | |
| 119 // 0x28 - 0x2B | |
| 120 kVK_DownArrow, /* VKEY_SELECT */ kInvalidKeycode, | |
| 121 /* VKEY_PRINT */ kInvalidKeycode, /* VKEY_EXECUTE */ kInvalidKeycode, | |
| 122 // 0x2C - 0x2F | |
| 123 /* VKEY_SNAPSHOT */ kInvalidKeycode, /* XK_INSERT */ kInvalidKeycode, | |
| 124 kVK_ForwardDelete, kVK_Help, | |
| 125 | |
| 126 // 0x30 - 0x33 | |
| 127 kVK_ANSI_0, kVK_ANSI_1, kVK_ANSI_2, kVK_ANSI_3, | |
| 128 // 0x34 - 0x37 | |
| 129 kVK_ANSI_4, kVK_ANSI_5, kVK_ANSI_6, kVK_ANSI_7, | |
| 130 // 0x38 - 0x3B | |
| 131 kVK_ANSI_8, kVK_ANSI_9, kInvalidKeycode, kInvalidKeycode, | |
| 132 // 0x3C - 0x3F | |
| 133 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 134 | |
| 135 // 0x40 - 0x43 | |
| 136 kInvalidKeycode, kVK_ANSI_A, kVK_ANSI_B, kVK_ANSI_C, | |
| 137 // 0x44 - 0x47 | |
| 138 kVK_ANSI_D, kVK_ANSI_E, kVK_ANSI_F, kVK_ANSI_G, | |
| 139 // 0x48 - 0x4B | |
| 140 kVK_ANSI_H, kVK_ANSI_I, kVK_ANSI_J, kVK_ANSI_K, | |
| 141 // 0x4C - 0x4F | |
| 142 kVK_ANSI_L, kVK_ANSI_M, kVK_ANSI_N, kVK_ANSI_O, | |
| 143 | |
| 144 // 0x50 - 0x53 | |
| 145 kVK_ANSI_P, kVK_ANSI_Q, kVK_ANSI_R, kVK_ANSI_S, | |
| 146 // 0x54 - 0x57 | |
| 147 kVK_ANSI_T, kVK_ANSI_U, kVK_ANSI_V, kVK_ANSI_W, | |
| 148 // 0x58 - 0x5B | |
| 149 kVK_ANSI_X, kVK_ANSI_Y, kVK_ANSI_Z, kVK_Command, | |
| 150 // 0x5C - 0x5F | |
| 151 kVK_Command, kVK_Command, kInvalidKeycode, /* VKEY_SLEEP */ kInvalidKeycode, | |
| 152 | |
| 153 // 0x60 - 0x63 | |
| 154 kVK_ANSI_Keypad0, kVK_ANSI_Keypad1, kVK_ANSI_Keypad2, kVK_ANSI_Keypad3, | |
| 155 // 0x64 - 0x67 | |
| 156 kVK_ANSI_Keypad4, kVK_ANSI_Keypad5, kVK_ANSI_Keypad6, kVK_ANSI_Keypad7, | |
| 157 // 0x68 - 0x6B | |
| 158 kVK_ANSI_Keypad8, kVK_ANSI_Keypad9, kVK_ANSI_KeypadMultiply, | |
| 159 kVK_ANSI_KeypadPlus, | |
| 160 // 0x6C - 0x6F | |
| 161 /* VKEY_SEPARATOR */ kInvalidKeycode, kVK_ANSI_KeypadMinus, | |
| 162 kVK_ANSI_KeypadDecimal, kVK_ANSI_KeypadDivide, | |
| 163 | |
| 164 // 0x70 - 0x73 | |
| 165 kVK_F1, kVK_F2, kVK_F3, kVK_F4, | |
| 166 // 0x74 - 0x77 | |
| 167 kVK_F5, kVK_F6, kVK_F7, kVK_F8, | |
| 168 // 0x78 - 0x7B | |
| 169 kVK_F9, kVK_F10, kVK_F11, kVK_F12, | |
| 170 // 0x7C - 0x7F | |
| 171 kVK_F13, kVK_F14, kVK_F15, kVK_F16, | |
| 172 | |
| 173 // 0x80 - 0x83 | |
| 174 kVK_F17, kVK_F18, kVK_F19, kVK_F20, | |
| 175 // 0x84 - 0x87 | |
| 176 /* VKEY_F21 */ kInvalidKeycode, /* VKEY_F22 */ kInvalidKeycode, | |
| 177 /* VKEY_F23 */ kInvalidKeycode, /* XKEY_F24 */ kInvalidKeycode, | |
| 178 // 0x88 - 0x8B | |
| 179 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 180 // 0x8C - 0x8F | |
| 181 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 182 | |
| 183 // 0x90 - 0x93 | |
| 184 /* VKEY_NUMLOCK */ kInvalidKeycode, /* VKEY_SCROLL */ kInvalidKeycode, | |
| 185 kInvalidKeycode, kInvalidKeycode, | |
| 186 // 0x94 - 0x97 | |
| 187 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 188 // 0x98 - 0x9B | |
| 189 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 190 // 0x9C - 0x9F | |
| 191 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 192 | |
| 193 // 0xA0 - 0xA3 | |
| 194 kVK_Shift, kVK_RightShift, kVK_Control, kVK_RightControl, | |
| 195 // 0xA4 - 0xA7 | |
| 196 kVK_Option, kVK_RightOption, | |
| 197 /* XF86kVK_Back */ kInvalidKeycode, /* XF86kVK_Forward */ kInvalidKeycode, | |
| 198 // 0xA8 - 0xAB | |
| 199 /* XF86kVK_Refresh */ kInvalidKeycode, /* XF86kVK_Stop */ kInvalidKeycode, | |
| 200 /* XF86kVK_Search */ kInvalidKeycode, | |
| 201 /* XF86kVK_Favorites */ kInvalidKeycode, | |
| 202 // 0xAC - 0xAF | |
| 203 /* XF86kVK_HomePage */ kInvalidKeycode, kVK_Mute, kVK_VolumeDown, | |
| 204 kVK_VolumeUp, | |
| 205 | |
| 206 // 0xB0 - 0xB3 | |
| 207 /* XF86kVK_AudioNext */ kInvalidKeycode, | |
| 208 /* XF86kVK_AudioPrev */ kInvalidKeycode, | |
| 209 /* XF86kVK_AudioStop */ kInvalidKeycode, | |
| 210 /* XF86kVK_AudioPause */ kInvalidKeycode, | |
| 211 // 0xB4 - 0xB7 | |
| 212 /* XF86kVK_Mail */ kInvalidKeycode, /* XF86kVK_AudioMedia */ kInvalidKeycode, | |
| 213 /* XF86kVK_Launch0 */ kInvalidKeycode, /* XF86kVK_Launch1 */ kInvalidKeycode, | |
| 214 // 0xB8 - 0xBB | |
| 215 kInvalidKeycode, kInvalidKeycode, kVK_ANSI_Semicolon, kVK_ANSI_Equal, | |
| 216 // 0xBC - 0xBF | |
| 217 kVK_ANSI_Comma, kVK_ANSI_Minus, kVK_ANSI_Period, kVK_ANSI_Slash, | |
| 218 | |
| 219 // 0xC0 - 0xC3 | |
| 220 kVK_ANSI_Grave, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 221 // 0xC4 - 0xC7 | |
| 222 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 223 // 0xC8 - 0xCB | |
| 224 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 225 // 0xCC - 0xCF | |
| 226 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 227 | |
| 228 // 0xD0 - 0xD3 | |
| 229 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 230 // 0xD4 - 0xD7 | |
| 231 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 232 // 0xD8 - 0xDB | |
| 233 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kVK_ANSI_LeftBracket, | |
| 234 // 0xDC - 0xDF | |
| 235 kVK_ANSI_Backslash, kVK_ANSI_RightBracket, kVK_ANSI_Quote, | |
| 236 /* VKEY_OEM_8 */ kInvalidKeycode, | |
| 237 | |
| 238 // 0xE0 - 0xE3 | |
| 239 kInvalidKeycode, kInvalidKeycode, /* VKEY_OEM_102 */ kInvalidKeycode, | |
| 240 kInvalidKeycode, | |
| 241 // 0xE4 - 0xE7 | |
| 242 kInvalidKeycode, /* VKEY_PROCESSKEY */ kInvalidKeycode, kInvalidKeycode, | |
| 243 /* VKEY_PACKET */ kInvalidKeycode, | |
| 244 // 0xE8 - 0xEB | |
| 245 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 246 // 0xEC - 0xEF | |
| 247 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 248 | |
| 249 // 0xF0 - 0xF3 | |
| 250 kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, kInvalidKeycode, | |
| 251 // 0xF4 - 0xF7 | |
| 252 kInvalidKeycode, kInvalidKeycode, /* VKEY_ATTN */ kInvalidKeycode, | |
| 253 /* VKEY_CRSEL */ kInvalidKeycode, | |
| 254 // 0xF8 - 0xFB | |
| 255 /* VKEY_EXSEL */ kInvalidKeycode, /* VKEY_EREOF */ kInvalidKeycode, | |
| 256 /* VKEY_PLAY */ kInvalidKeycode, /* VKEY_ZOOM */ kInvalidKeycode, | |
| 257 // 0xFC - 0xFF | |
| 258 /* VKEY_NONAME */ kInvalidKeycode, /* VKEY_PA1 */ kInvalidKeycode, | |
| 259 /* VKEY_OEM_CLEAR */ kInvalidKeycode, kInvalidKeycode | |
| 260 }; | |
| 261 | |
| 262 void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { | 80 void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { |
| 263 if (!task_runner_->BelongsToCurrentThread()) { | 81 if (!task_runner_->BelongsToCurrentThread()) { |
| 264 task_runner_->PostTask( | 82 task_runner_->PostTask( |
| 265 FROM_HERE, | 83 FROM_HERE, |
| 266 base::Bind(&EventExecutorMac::InjectClipboardEvent, | 84 base::Bind(&EventExecutorMac::InjectClipboardEvent, |
| 267 base::Unretained(this), | 85 base::Unretained(this), |
| 268 event)); | 86 event)); |
| 269 return; | 87 return; |
| 270 } | 88 } |
| 271 | 89 |
| 272 clipboard_->InjectClipboardEvent(event); | 90 clipboard_->InjectClipboardEvent(event); |
| 273 } | 91 } |
| 274 | 92 |
| 275 void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { | 93 void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { |
| 276 // HostEventDispatcher should filter events missing the pressed field. | 94 // HostEventDispatcher should filter events missing the pressed field. |
| 277 DCHECK(event.has_pressed()); | 95 DCHECK(event.has_pressed()); |
| 96 DCHECK(event.has_usb_keycode()); |
| 278 | 97 |
| 279 int keycode = kInvalidKeycode; | 98 int keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); |
| 280 if (event.has_usb_keycode()) { | 99 |
| 281 keycode = UsbKeycodeToNativeKeycode(event.usb_keycode()); | 100 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() |
| 282 VLOG(3) << "Converting USB keycode: " << std::hex << event.usb_keycode() | 101 << " to keycode: " << keycode << std::dec; |
| 283 << " to keycode: " << keycode << std::dec; | |
| 284 } else if (event.has_keycode()) { | |
| 285 int win_keycode = event.keycode(); | |
| 286 if (win_keycode >= 0 && win_keycode < 256) { | |
| 287 keycode = kUsVkeyToKeysym[win_keycode]; | |
| 288 } | |
| 289 VLOG(3) << "Converting VKEY: " << std::hex << event.keycode() | |
| 290 << " to keycode: " << keycode << std::dec; | |
| 291 } | |
| 292 | 102 |
| 293 // If we couldn't determine the Mac virtual key code then ignore the event. | 103 // If we couldn't determine the Mac virtual key code then ignore the event. |
| 294 if (keycode == kInvalidKeycode) | 104 if (keycode == kInvalidKeycode) |
| 295 return; | 105 return; |
| 296 | 106 |
| 297 // We use the deprecated event injection API because the new one doesn't | 107 // We use the deprecated event injection API because the new one doesn't |
| 298 // work with switched-out sessions (curtain mode). | 108 // work with switched-out sessions (curtain mode). |
| 299 #pragma clang diagnostic push | 109 #pragma clang diagnostic push |
| 300 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 110 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| 301 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); | 111 CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 201 |
| 392 } // namespace | 202 } // namespace |
| 393 | 203 |
| 394 scoped_ptr<EventExecutor> EventExecutor::Create( | 204 scoped_ptr<EventExecutor> EventExecutor::Create( |
| 395 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 205 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
| 396 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 206 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
| 397 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); | 207 return scoped_ptr<EventExecutor>(new EventExecutorMac(main_task_runner)); |
| 398 } | 208 } |
| 399 | 209 |
| 400 } // namespace remoting | 210 } // namespace remoting |
| OLD | NEW |