Index: remoting/host/event_executor_mac.cc |
=================================================================== |
--- remoting/host/event_executor_mac.cc (revision 126631) |
+++ remoting/host/event_executor_mac.cc (working copy) |
@@ -19,6 +19,11 @@ |
namespace { |
+// USB to Mac keycode mapping table. |
+#define USB_KEYMAP(usb, xkb, win, mac) {usb, mac} |
+#include "remoting/host/usb_keycode_map.h" |
+#define INVALID_KEYCODE 0xffff |
+ |
using protocol::MouseEvent; |
using protocol::KeyEvent; |
@@ -56,47 +61,53 @@ |
// TODO(wez): Replace this with something more closely tied to what |
// WebInputEventFactory does on Linux/GTK, and which respects the |
// host's keyboard layout. |
+// |
+// TODO(garykac): Remove this table once we switch to using USB |
+// keycodes. |
const int kUsVkeyToKeysym[256] = { |
// 0x00 - 0x07 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x04 - 0x07 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x08 - 0x0B |
- kVK_Delete, kVK_Tab, -1, -1, |
+ kVK_Delete, kVK_Tab, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x0C - 0x0F |
- -1, kVK_Return, -1, -1, |
+ INVALID_KEYCODE, kVK_Return, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x10 - 0x13 |
- kVK_Shift, kVK_Control, kVK_Option, -1, |
+ kVK_Shift, kVK_Control, kVK_Option, INVALID_KEYCODE, |
// 0x14 - 0x17 |
- kVK_CapsLock, kVK_JIS_Kana, /* VKEY_HANGUL */ -1, /* VKEY_JUNJA */ -1, |
+ kVK_CapsLock, kVK_JIS_Kana, /* VKEY_HANGUL */ INVALID_KEYCODE, |
+ /* VKEY_JUNJA */ INVALID_KEYCODE, |
// 0x18 - 0x1B |
- /* VKEY_FINAL */ -1, /* VKEY_Kanji */ -1, -1, kVK_Escape, |
+ /* VKEY_FINAL */ INVALID_KEYCODE, /* VKEY_Kanji */ INVALID_KEYCODE, |
+ INVALID_KEYCODE, kVK_Escape, |
// 0x1C - 0x1F |
- /* VKEY_CONVERT */ -1, /* VKEY_NONCONVERT */ -1, |
- /* VKEY_ACCEPT */ -1, /* VKEY_MODECHANGE */ -1, |
+ /* VKEY_CONVERT */ INVALID_KEYCODE, /* VKEY_NONCONVERT */ INVALID_KEYCODE, |
+ /* VKEY_ACCEPT */ INVALID_KEYCODE, /* VKEY_MODECHANGE */ INVALID_KEYCODE, |
// 0x20 - 0x23 |
kVK_Space, kVK_PageUp, kVK_PageDown, kVK_End, |
// 0x24 - 0x27 |
kVK_Home, kVK_LeftArrow, kVK_UpArrow, kVK_RightArrow, |
// 0x28 - 0x2B |
- kVK_DownArrow, /* VKEY_SELECT */ -1, /* VKEY_PRINT */ -1, |
- /* VKEY_EXECUTE */ -1, |
+ kVK_DownArrow, /* VKEY_SELECT */ INVALID_KEYCODE, |
+ /* VKEY_PRINT */ INVALID_KEYCODE, /* VKEY_EXECUTE */ INVALID_KEYCODE, |
// 0x2C - 0x2F |
- /* VKEY_SNAPSHOT */ -1, /* XK_INSERT */ -1, kVK_ForwardDelete, kVK_Help, |
+ /* VKEY_SNAPSHOT */ INVALID_KEYCODE, /* XK_INSERT */ INVALID_KEYCODE, |
+ kVK_ForwardDelete, kVK_Help, |
// 0x30 - 0x33 |
kVK_ANSI_0, kVK_ANSI_1, kVK_ANSI_2, kVK_ANSI_3, |
// 0x34 - 0x37 |
kVK_ANSI_4, kVK_ANSI_5, kVK_ANSI_6, kVK_ANSI_7, |
// 0x38 - 0x3B |
- kVK_ANSI_8, kVK_ANSI_9, -1, -1, |
+ kVK_ANSI_8, kVK_ANSI_9, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x3C - 0x3F |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x40 - 0x43 |
- -1, kVK_ANSI_A, kVK_ANSI_B, kVK_ANSI_C, |
+ INVALID_KEYCODE, kVK_ANSI_A, kVK_ANSI_B, kVK_ANSI_C, |
// 0x44 - 0x47 |
kVK_ANSI_D, kVK_ANSI_E, kVK_ANSI_F, kVK_ANSI_G, |
// 0x48 - 0x4B |
@@ -111,7 +122,7 @@ |
// 0x58 - 0x5B |
kVK_ANSI_X, kVK_ANSI_Y, kVK_ANSI_Z, kVK_Command, |
// 0x5C - 0x5F |
- kVK_Command, kVK_Command, -1, /* VKEY_SLEEP */ -1, |
+ kVK_Command, kVK_Command, INVALID_KEYCODE, /* VKEY_SLEEP */ INVALID_KEYCODE, |
// 0x60 - 0x63 |
kVK_ANSI_Keypad0, kVK_ANSI_Keypad1, kVK_ANSI_Keypad2, kVK_ANSI_Keypad3, |
@@ -121,7 +132,7 @@ |
kVK_ANSI_Keypad8, kVK_ANSI_Keypad9, kVK_ANSI_KeypadMultiply, |
kVK_ANSI_KeypadPlus, |
// 0x6C - 0x6F |
- /* VKEY_SEPARATOR */ -1, kVK_ANSI_KeypadMinus, |
+ /* VKEY_SEPARATOR */ INVALID_KEYCODE, kVK_ANSI_KeypadMinus, |
kVK_ANSI_KeypadDecimal, kVK_ANSI_KeypadDivide, |
// 0x70 - 0x73 |
@@ -136,94 +147,125 @@ |
// 0x80 - 0x83 |
kVK_F17, kVK_F18, kVK_F19, kVK_F20, |
// 0x84 - 0x87 |
- /* VKEY_F21 */ -1, /* VKEY_F22 */ -1, /* VKEY_F23 */ -1, /* XKEY_F24 */ -1, |
+ /* VKEY_F21 */ INVALID_KEYCODE, /* VKEY_F22 */ INVALID_KEYCODE, |
+ /* VKEY_F23 */ INVALID_KEYCODE, /* XKEY_F24 */ INVALID_KEYCODE, |
// 0x88 - 0x8B |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x8C - 0x8F |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x90 - 0x93 |
- /* VKEY_NUMLOCK */ -1, /* VKEY_SCROLL */ -1, -1, -1, |
+ /* VKEY_NUMLOCK */ INVALID_KEYCODE, /* VKEY_SCROLL */ INVALID_KEYCODE, |
+ INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x94 - 0x97 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x98 - 0x9B |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0x9C - 0x9F |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xA0 - 0xA3 |
kVK_Shift, kVK_RightShift, kVK_Control, kVK_RightControl, |
// 0xA4 - 0xA7 |
- kVK_Option, kVK_RightOption, /* XF86kVK_Back */ -1, /* XF86kVK_Forward */ -1, |
+ kVK_Option, kVK_RightOption, |
+ /* XF86kVK_Back */ INVALID_KEYCODE, /* XF86kVK_Forward */ INVALID_KEYCODE, |
// 0xA8 - 0xAB |
- /* XF86kVK_Refresh */ -1, /* XF86kVK_Stop */ -1, /* XF86kVK_Search */ -1, |
- /* XF86kVK_Favorites */ -1, |
+ /* XF86kVK_Refresh */ INVALID_KEYCODE, /* XF86kVK_Stop */ INVALID_KEYCODE, |
+ /* XF86kVK_Search */ INVALID_KEYCODE, |
+ /* XF86kVK_Favorites */ INVALID_KEYCODE, |
// 0xAC - 0xAF |
- /* XF86kVK_HomePage */ -1, kVK_Mute, kVK_VolumeDown, kVK_VolumeUp, |
+ /* XF86kVK_HomePage */ INVALID_KEYCODE, kVK_Mute, kVK_VolumeDown, |
+ kVK_VolumeUp, |
// 0xB0 - 0xB3 |
- /* XF86kVK_AudioNext */ -1, /* XF86kVK_AudioPrev */ -1, |
- /* XF86kVK_AudioStop */ -1, /* XF86kVK_AudioPause */ -1, |
+ /* XF86kVK_AudioNext */ INVALID_KEYCODE, |
+ /* XF86kVK_AudioPrev */ INVALID_KEYCODE, |
+ /* XF86kVK_AudioStop */ INVALID_KEYCODE, |
+ /* XF86kVK_AudioPause */ INVALID_KEYCODE, |
// 0xB4 - 0xB7 |
- /* XF86kVK_Mail */ -1, /* XF86kVK_AudioMedia */ -1, /* XF86kVK_Launch0 */ -1, |
- /* XF86kVK_Launch1 */ -1, |
+ /* XF86kVK_Mail */ INVALID_KEYCODE, /* XF86kVK_AudioMedia */ INVALID_KEYCODE, |
+ /* XF86kVK_Launch0 */ INVALID_KEYCODE, /* XF86kVK_Launch1 */ INVALID_KEYCODE, |
// 0xB8 - 0xBB |
- -1, -1, kVK_ANSI_Semicolon, kVK_ANSI_Equal, |
+ INVALID_KEYCODE, INVALID_KEYCODE, kVK_ANSI_Semicolon, kVK_ANSI_Equal, |
// 0xBC - 0xBF |
kVK_ANSI_Comma, kVK_ANSI_Minus, kVK_ANSI_Period, kVK_ANSI_Slash, |
// 0xC0 - 0xC3 |
- kVK_ANSI_Grave, -1, -1, -1, |
+ kVK_ANSI_Grave, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xC4 - 0xC7 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xC8 - 0xCB |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xCC - 0xCF |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xD0 - 0xD3 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xD4 - 0xD7 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xD8 - 0xDB |
- -1, -1, -1, kVK_ANSI_LeftBracket, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, kVK_ANSI_LeftBracket, |
// 0xDC - 0xDF |
kVK_ANSI_Backslash, kVK_ANSI_RightBracket, kVK_ANSI_Quote, |
- /* VKEY_OEM_8 */ -1, |
+ /* VKEY_OEM_8 */ INVALID_KEYCODE, |
// 0xE0 - 0xE3 |
- -1, -1, /* VKEY_OEM_102 */ -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, /* VKEY_OEM_102 */ INVALID_KEYCODE, |
+ INVALID_KEYCODE, |
// 0xE4 - 0xE7 |
- -1, /* VKEY_PROCESSKEY */ -1, -1, /* VKEY_PACKET */ -1, |
+ INVALID_KEYCODE, /* VKEY_PROCESSKEY */ INVALID_KEYCODE, INVALID_KEYCODE, |
+ /* VKEY_PACKET */ INVALID_KEYCODE, |
// 0xE8 - 0xEB |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xEC - 0xEF |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xF0 - 0xF3 |
- -1, -1, -1, -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, INVALID_KEYCODE, |
// 0xF4 - 0xF7 |
- -1, -1, /* VKEY_ATTN */ -1, /* VKEY_CRSEL */ -1, |
+ INVALID_KEYCODE, INVALID_KEYCODE, /* VKEY_ATTN */ INVALID_KEYCODE, |
+ /* VKEY_CRSEL */ INVALID_KEYCODE, |
// 0xF8 - 0xFB |
- /* VKEY_EXSEL */ -1, /* VKEY_EREOF */ -1, /* VKEY_PLAY */ -1, |
- /* VKEY_ZOOM */ -1, |
+ /* VKEY_EXSEL */ INVALID_KEYCODE, /* VKEY_EREOF */ INVALID_KEYCODE, |
+ /* VKEY_PLAY */ INVALID_KEYCODE, /* VKEY_ZOOM */ INVALID_KEYCODE, |
// 0xFC - 0xFF |
- /* VKEY_NONAME */ -1, /* VKEY_PA1 */ -1, /* VKEY_OEM_CLEAR */ -1, -1 |
+ /* VKEY_NONAME */ INVALID_KEYCODE, /* VKEY_PA1 */ INVALID_KEYCODE, |
+ /* VKEY_OEM_CLEAR */ INVALID_KEYCODE, INVALID_KEYCODE |
}; |
+uint16_t UsbKeycodeToMacKeycode(uint32_t usb_keycode) { |
+ if (usb_keycode == 0) |
+ return INVALID_KEYCODE; |
+ |
+ for (uint i = 0; i < arraysize(usb_keycode_map); i++) { |
+ if (usb_keycode_map[i].usb_keycode == usb_keycode) |
+ return usb_keycode_map[i].native_keycode; |
+ } |
+ |
+ return INVALID_KEYCODE; |
+} |
+ |
void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { |
- int key_code = event.keycode(); |
- if (key_code >= 0 && key_code < 256) { |
- int key_sym = kUsVkeyToKeysym[key_code]; |
- if (key_sym != -1) { |
- // We use the deprecated event injection API because the new one doesn't |
- // work with switched-out sessions (curtain mode). |
- CGError error = CGPostKeyboardEvent(0, key_sym, event.pressed()); |
- if (error != kCGErrorSuccess) { |
- LOG(WARNING) << "CGPostKeyboardEvent error " << error; |
- } |
+ int keycode = 0; |
+ if (event.has_usb_keycode() && event.usb_keycode() != INVALID_KEYCODE) { |
+ keycode = UsbKeycodeToMacKeycode(event.usb_keycode()); |
+ VLOG(1) << "USB keycode: " << std::hex << event.usb_keycode() |
+ << " to Mac keycode: " << keycode << std::dec; |
+ } else { |
+ int win_keycode = event.keycode(); |
+ if (win_keycode >= 0 && win_keycode < 256) { |
+ keycode = kUsVkeyToKeysym[win_keycode]; |
} |
} |
+ |
+ if (keycode != INVALID_KEYCODE) { |
+ // We use the deprecated event injection API because the new one doesn't |
+ // work with switched-out sessions (curtain mode). |
+ CGError error = CGPostKeyboardEvent(0, keycode, event.pressed()); |
+ if (error != kCGErrorSuccess) { |
+ LOG(WARNING) << "CGPostKeyboardEvent error " << error; |
+ } |
+ } |
} |
void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { |