diff options
author | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-07 17:56:50 +0000 |
---|---|---|
committer | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-07 17:56:50 +0000 |
commit | 34ebb250424e57b08876129ed8adf35b20b471c2 (patch) | |
tree | ff221a648545e08d6e236d36863c079d182001d3 /remoting | |
parent | 9f90a085c44812754e2be9a0a6be9f020ebb8767 (diff) | |
download | chromium_src-34ebb250424e57b08876129ed8adf35b20b471c2.zip chromium_src-34ebb250424e57b08876129ed8adf35b20b471c2.tar.gz chromium_src-34ebb250424e57b08876129ed8adf35b20b471c2.tar.bz2 |
Support keyboard input on Mac
BUG=
TEST=
Review URL: http://codereview.chromium.org/6610024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77155 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/event_executor_mac.cc | 206 | ||||
-rw-r--r-- | remoting/host/event_executor_mac.h | 1 |
2 files changed, 203 insertions, 4 deletions
diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc index 0f034f8..e28157a 100644 --- a/remoting/host/event_executor_mac.cc +++ b/remoting/host/event_executor_mac.cc @@ -5,9 +5,11 @@ #include "remoting/host/event_executor_mac.h" #include <ApplicationServices/ApplicationServices.h> +#include <Carbon/Carbon.h> #include "base/message_loop.h" #include "base/task.h" +#include "base/mac/scoped_cftyperef.h" #include "remoting/host/capturer.h" #include "remoting/protocol/message_decoder.h" #include "remoting/proto/internal.pb.h" @@ -20,13 +22,209 @@ using protocol::KeyEvent; EventExecutorMac::EventExecutorMac( MessageLoopForUI* message_loop, Capturer* capturer) : message_loop_(message_loop), - capturer_(capturer), last_x_(0), last_y_(0) { + capturer_(capturer), last_x_(0), last_y_(0), modifiers_(0) { } EventExecutorMac::~EventExecutorMac() { } +// Hard-coded mapping from Virtual Key codes to Mac KeySyms. +// This mapping is only valid if both client and host are using a +// US English keyboard layout. +// Because we're passing VK codes on the wire, with no Scancode, +// "extended" flag, etc, things like distinguishing left & right +// Shift keys doesn't work. +// +// TODO(wez): Replace this with something more closely tied to what +// WebInputEventFactory does on Linux/GTK, and which respects the +// host's keyboard layout. +const int kUsVkeyToKeysym[256] = { + // 0x00 - 0x07 + -1, -1, -1, -1, + // 0x04 - 0x07 + -1, -1, -1, -1, + // 0x08 - 0x0B + kVK_Delete, kVK_Tab, -1, -1, + // 0x0C - 0x0F + -1, kVK_Return, -1, -1, + + // 0x10 - 0x13 + kVK_Shift, kVK_Control, kVK_Option, -1, + // 0x14 - 0x17 + kVK_CapsLock, kVK_JIS_Kana, /* VKEY_HANGUL */ -1, /* VKEY_JUNJA */ -1, + // 0x18 - 0x1B + /* VKEY_FINAL */ -1, /* VKEY_Kanji */ -1, -1, kVK_Escape, + // 0x1C - 0x1F + /* VKEY_CONVERT */ -1, /* VKEY_NONCONVERT */ -1, + /* VKEY_ACCEPT */ -1, /* VKEY_MODECHANGE */ -1, + + // 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, + // 0x2C - 0x2F + /* VKEY_SNAPSHOT */ -1, /* XK_INSERT */ -1, 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, + // 0x3C - 0x3F + -1, -1, -1, -1, + + // 0x40 - 0x43 + -1, 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 + kVK_ANSI_H, kVK_ANSI_I, kVK_ANSI_J, kVK_ANSI_K, + // 0x4C - 0x4F + kVK_ANSI_L, kVK_ANSI_M, kVK_ANSI_N, kVK_ANSI_O, + + // 0x50 - 0x53 + kVK_ANSI_P, kVK_ANSI_Q, kVK_ANSI_R, kVK_ANSI_S, + // 0x54 - 0x57 + kVK_ANSI_T, kVK_ANSI_U, kVK_ANSI_V, kVK_ANSI_W, + // 0x58 - 0x5B + kVK_ANSI_X, kVK_ANSI_Y, kVK_ANSI_Z, kVK_Command, + // 0x5C - 0x5F + kVK_Command, kVK_Command, -1, /* VKEY_SLEEP */ -1, + + // 0x60 - 0x63 + kVK_ANSI_Keypad0, kVK_ANSI_Keypad1, kVK_ANSI_Keypad2, kVK_ANSI_Keypad3, + // 0x64 - 0x67 + kVK_ANSI_Keypad4, kVK_ANSI_Keypad5, kVK_ANSI_Keypad6, kVK_ANSI_Keypad7, + // 0x68 - 0x6B + kVK_ANSI_Keypad8, kVK_ANSI_Keypad9, kVK_ANSI_KeypadMultiply, + kVK_ANSI_KeypadPlus, + // 0x6C - 0x6F + /* VKEY_SEPARATOR */ -1, kVK_ANSI_KeypadMinus, + kVK_ANSI_KeypadDecimal, kVK_ANSI_KeypadDivide, + + // 0x70 - 0x73 + kVK_F1, kVK_F2, kVK_F3, kVK_F4, + // 0x74 - 0x77 + kVK_F5, kVK_F6, kVK_F7, kVK_F8, + // 0x78 - 0x7B + kVK_F9, kVK_F10, kVK_F11, kVK_F12, + // 0x7C - 0x7F + kVK_F13, kVK_F14, kVK_F15, kVK_F16, + + // 0x80 - 0x83 + kVK_F17, kVK_F18, kVK_F19, kVK_F20, + // 0x84 - 0x87 + /* VKEY_F21 */ -1, /* VKEY_F22 */ -1, /* VKEY_F23 */ -1, /* XKEY_F24 */ -1, + // 0x88 - 0x8B + -1, -1, -1, -1, + // 0x8C - 0x8F + -1, -1, -1, -1, + + // 0x90 - 0x93 + /* VKEY_NUMLOCK */ -1, /* VKEY_SCROLL */ -1, -1, -1, + // 0x94 - 0x97 + -1, -1, -1, -1, + // 0x98 - 0x9B + -1, -1, -1, -1, + // 0x9C - 0x9F + -1, -1, -1, -1, + + // 0xA0 - 0xA3 + kVK_Shift, kVK_RightShift, kVK_Control, kVK_RightControl, + // 0xA4 - 0xA7 + kVK_Option, kVK_RightOption, /* XF86kVK_Back */ -1, /* XF86kVK_Forward */ -1, + // 0xA8 - 0xAB + /* XF86kVK_Refresh */ -1, /* XF86kVK_Stop */ -1, /* XF86kVK_Search */ -1, + /* XF86kVK_Favorites */ -1, + // 0xAC - 0xAF + /* XF86kVK_HomePage */ -1, kVK_Mute, kVK_VolumeDown, kVK_VolumeUp, + + // 0xB0 - 0xB3 + /* XF86kVK_AudioNext */ -1, /* XF86kVK_AudioPrev */ -1, + /* XF86kVK_AudioStop */ -1, /* XF86kVK_AudioPause */ -1, + // 0xB4 - 0xB7 + /* XF86kVK_Mail */ -1, /* XF86kVK_AudioMedia */ -1, /* XF86kVK_Launch0 */ -1, + /* XF86kVK_Launch1 */ -1, + // 0xB8 - 0xBB + -1, -1, kVK_ANSI_Semicolon, kVK_ANSI_KeypadPlus, + // 0xBC - 0xBF + kVK_ANSI_Comma, kVK_ANSI_KeypadMinus, kVK_ANSI_Period, kVK_ANSI_Slash, + + // 0xC0 - 0xC3 + kVK_ANSI_Grave, -1, -1, -1, + // 0xC4 - 0xC7 + -1, -1, -1, -1, + // 0xC8 - 0xCB + -1, -1, -1, -1, + // 0xCC - 0xCF + -1, -1, -1, -1, + + // 0xD0 - 0xD3 + -1, -1, -1, -1, + // 0xD4 - 0xD7 + -1, -1, -1, -1, + // 0xD8 - 0xDB + -1, -1, -1, kVK_ANSI_LeftBracket, + // 0xDC - 0xDF + kVK_ANSI_Backslash, kVK_ANSI_RightBracket, kVK_ANSI_Quote, + /* VKEY_OEM_8 */ -1, + + // 0xE0 - 0xE3 + -1, -1, /* VKEY_OEM_102 */ -1, -1, + // 0xE4 - 0xE7 + -1, /* VKEY_PROCESSKEY */ -1, -1, /* VKEY_PACKET */ -1, + // 0xE8 - 0xEB + -1, -1, -1, -1, + // 0xEC - 0xEF + -1, -1, -1, -1, + + // 0xF0 - 0xF3 + -1, -1, -1, -1, + // 0xF4 - 0xF7 + -1, -1, /* VKEY_ATTN */ -1, /* VKEY_CRSEL */ -1, + // 0xF8 - 0xFB + /* VKEY_EXSEL */ -1, /* VKEY_EREOF */ -1, /* VKEY_PLAY */ -1, + /* VKEY_ZOOM */ -1, + // 0xFC - 0xFF + /* VKEY_NONAME */ -1, /* VKEY_PA1 */ -1, /* VKEY_OEM_CLEAR */ -1, -1 +}; + void EventExecutorMac::InjectKeyEvent(const KeyEvent* event, Task* done) { + int key_code = event->keycode(); + if (key_code >= 0 && key_code < 256) { + int key_sym = kUsVkeyToKeysym[key_code]; + if (key_sym != -1) { + base::mac::ScopedCFTypeRef<CGEventRef> kbd_event( + CGEventCreateKeyboardEvent(0, kUsVkeyToKeysym[key_code], + event->pressed())); + int this_modifier = 0; + switch (key_sym) { + case kVK_Shift: case kVK_RightShift: + this_modifier = kCGEventFlagMaskShift; + break; + case kVK_Control: case kVK_RightControl: + this_modifier = kCGEventFlagMaskControl; + break; + case kVK_Command: + this_modifier = kCGEventFlagMaskCommand; + break; + case kVK_Option: case kVK_RightOption: + this_modifier = kCGEventFlagMaskAlternate; + break; + } + if (this_modifier && event->pressed()) { + modifiers_ |= this_modifier; + } else if (this_modifier && !event->pressed()) { + modifiers_ &= ~this_modifier; + } + CGEventSetFlags(kbd_event, modifiers_); + CGEventPost(kCGSessionEventTap, kbd_event); + } + } done->Run(); delete done; } @@ -85,10 +283,10 @@ void EventExecutorMac::InjectMouseEvent(const MouseEvent* event, Task* done) { } if (event_type != kCGEventNull) { - CGEventRef mouse_event = CGEventCreateMouseEvent(NULL, event_type, - position, mouse_button); + base::mac::ScopedCFTypeRef<CGEventRef> mouse_event( + CGEventCreateMouseEvent(NULL, event_type, position, mouse_button)); + CGEventSetFlags(mouse_event, modifiers_); CGEventPost(kCGSessionEventTap, mouse_event); - CFRelease(mouse_event); } done->Run(); diff --git a/remoting/host/event_executor_mac.h b/remoting/host/event_executor_mac.h index 6b3054d9..d8ce6bc 100644 --- a/remoting/host/event_executor_mac.h +++ b/remoting/host/event_executor_mac.h @@ -26,6 +26,7 @@ class EventExecutorMac : public protocol::InputStub { MessageLoopForUI* message_loop_; Capturer* capturer_; int last_x_, last_y_; + int modifiers_; DISALLOW_COPY_AND_ASSIGN(EventExecutorMac); }; |