summaryrefslogtreecommitdiffstats
path: root/remoting/host
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-28 07:50:55 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-28 07:50:55 +0000
commitd24a7f958ad3f98673006f27fcd3c8c63ef29cbf (patch)
treef4c885b837090af38e206f1d56af43cc353703bf /remoting/host
parentf02f6f5e35504369f8537b783766b9591dce4c35 (diff)
downloadchromium_src-d24a7f958ad3f98673006f27fcd3c8c63ef29cbf.zip
chromium_src-d24a7f958ad3f98673006f27fcd3c8c63ef29cbf.tar.gz
chromium_src-d24a7f958ad3f98673006f27fcd3c8c63ef29cbf.tar.bz2
Update input injectors on Mac and Windows to handle TextEvent.
BUG=270356,265945 R=lambroslambrou@chromium.org Review URL: https://codereview.chromium.org/214193002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260089 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host')
-rw-r--r--remoting/host/input_injector_mac.cc42
-rw-r--r--remoting/host/input_injector_win.cc64
2 files changed, 68 insertions, 38 deletions
diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc
index b450674..30ea580 100644
--- a/remoting/host/input_injector_mac.cc
+++ b/remoting/host/input_injector_mac.cc
@@ -15,6 +15,7 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/utf_string_conversions.h"
#include "remoting/host/clipboard.h"
#include "remoting/proto/internal.pb.h"
#include "remoting/protocol/message_decoder.h"
@@ -30,6 +31,20 @@ void SetOrClearBit(uint64_t &value, uint64_t bit, bool set_bit) {
value = set_bit ? (value | bit) : (value & ~bit);
}
+void CreateAndPostKeyEvent(int keycode,
+ bool pressed,
+ int flags,
+ const base::string16& unicode) {
+ base::ScopedCFTypeRef<CGEventRef> eventRef(
+ CGEventCreateKeyboardEvent(NULL, keycode, pressed));
+ if (eventRef) {
+ CGEventSetFlags(eventRef, flags);
+ if (!unicode.empty())
+ CGEventKeyboardSetUnicodeString(eventRef, unicode.size(), &(unicode[0]));
+ CGEventPost(kCGSessionEventTap, eventRef);
+ }
+}
+
// This value is not defined. Give it the obvious name so that if it is ever
// added there will be a handy compilation error to remind us to remove this
// definition.
@@ -194,24 +209,23 @@ void InputInjectorMac::Core::InjectKeyEvent(const KeyEvent& event) {
SetOrClearBit(right_modifiers_, kCGEventFlagMaskAlternate, event.pressed());
}
- base::ScopedCFTypeRef<CGEventRef> eventRef(
- CGEventCreateKeyboardEvent(NULL, keycode, event.pressed()));
-
- if (eventRef) {
- // In addition to the modifier keys pressed right now, we also need to set
- // AlphaShift if caps lock was active at the client (Mac ignores NumLock).
- uint64_t flags = left_modifiers_ | right_modifiers_;
- if (event.lock_states() & protocol::KeyEvent::LOCK_STATES_CAPSLOCK)
- flags |= kCGEventFlagMaskAlphaShift;
- CGEventSetFlags(eventRef, flags);
+ // In addition to the modifier keys pressed right now, we also need to set
+ // AlphaShift if caps lock was active at the client (Mac ignores NumLock).
+ uint64_t flags = left_modifiers_ | right_modifiers_;
+ if (event.lock_states() & protocol::KeyEvent::LOCK_STATES_CAPSLOCK)
+ flags |= kCGEventFlagMaskAlphaShift;
- // Post the event to the current session.
- CGEventPost(kCGSessionEventTap, eventRef);
- }
+ CreateAndPostKeyEvent(keycode, event.pressed(), flags, base::string16());
}
void InputInjectorMac::Core::InjectTextEvent(const TextEvent& event) {
- NOTIMPLEMENTED();
+ DCHECK(event.has_text());
+ base::string16 text = base::UTF8ToUTF16(event.text());
+
+ // Applications that ignore UnicodeString field will see the text event as
+ // Space key.
+ CreateAndPostKeyEvent(kVK_Space, true, 0, text);
+ CreateAndPostKeyEvent(kVK_Space, false, 0, text);
}
void InputInjectorMac::Core::InjectMouseEvent(const MouseEvent& event) {
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc
index 03e4b7e..235f45e 100644
--- a/remoting/host/input_injector_win.cc
+++ b/remoting/host/input_injector_win.cc
@@ -11,6 +11,8 @@
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
#include "remoting/base/util.h"
#include "remoting/host/clipboard.h"
#include "remoting/proto/event.pb.h"
@@ -20,6 +22,31 @@ namespace remoting {
namespace {
+// Helper used to call SendInput() API.
+void SendKeyboardInput(uint32_t flags, uint16_t scancode) {
+ // Populate a Windows INPUT structure for the event.
+ INPUT input;
+ memset(&input, 0, sizeof(input));
+ input.type = INPUT_KEYBOARD;
+ input.ki.time = 0;
+ input.ki.dwFlags = flags;
+ input.ki.wScan = scancode;
+
+ if ((flags & KEYEVENTF_UNICODE) == 0) {
+ // Windows scancodes are only 8-bit, so store the low-order byte into the
+ // event and set the extended flag if any high-order bits are set. The only
+ // high-order values we should see are 0xE0 or 0xE1. The extended bit
+ // usually distinguishes keys with the same meaning, e.g. left & right
+ // shift.
+ input.ki.wScan &= 0xFF;
+ if ((scancode & 0xFF00) != 0x0000)
+ input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
+ }
+
+ if (SendInput(1, &input, sizeof(INPUT)) == 0)
+ LOG_GETLASTERROR(ERROR) << "Failed to inject a key event";
+}
+
using protocol::ClipboardEvent;
using protocol::KeyEvent;
using protocol::TextEvent;
@@ -185,13 +212,11 @@ void InputInjectorWin::Core::Stop() {
clipboard_->Stop();
}
-InputInjectorWin::Core::~Core() {
-}
+InputInjectorWin::Core::~Core() {}
void InputInjectorWin::Core::HandleKey(const KeyEvent& event) {
// HostEventDispatcher should filter events missing the pressed field.
- if (!event.has_pressed() || !event.has_usb_keycode())
- return;
+ DCHECK(event.has_pressed() && event.has_usb_keycode());
// Reset the system idle suspend timeout.
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
@@ -205,29 +230,20 @@ void InputInjectorWin::Core::HandleKey(const KeyEvent& event) {
if (scancode == key_converter->InvalidNativeKeycode())
return;
- // Populate the a Windows INPUT structure for the event.
- INPUT input;
- memset(&input, 0, sizeof(input));
- input.type = INPUT_KEYBOARD;
- input.ki.time = 0;
- input.ki.dwFlags = KEYEVENTF_SCANCODE;
- if (!event.pressed())
- input.ki.dwFlags |= KEYEVENTF_KEYUP;
-
- // Windows scancodes are only 8-bit, so store the low-order byte into the
- // event and set the extended flag if any high-order bits are set. The only
- // high-order values we should see are 0xE0 or 0xE1. The extended bit usually
- // distinguishes keys with the same meaning, e.g. left & right shift.
- input.ki.wScan = scancode & 0xFF;
- if ((scancode & 0xFF00) != 0x0000)
- input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
-
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
- LOG_GETLASTERROR(ERROR) << "Failed to inject a key event";
+ uint32_t flags = KEYEVENTF_SCANCODE | (event.pressed() ? 0 : KEYEVENTF_KEYUP);
+ SendKeyboardInput(flags, scancode);
}
void InputInjectorWin::Core::HandleText(const TextEvent& event) {
- NOTIMPLEMENTED();
+ // HostEventDispatcher should filter events missing the pressed field.
+ DCHECK(event.has_text());
+
+ base::string16 text = base::UTF8ToUTF16(event.text());
+ for (base::string16::const_iterator it = text.begin();
+ it != text.end(); ++it) {
+ SendKeyboardInput(KEYEVENTF_UNICODE, *it);
+ SendKeyboardInput(KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, *it);
+ }
}
void InputInjectorWin::Core::HandleMouse(const MouseEvent& event) {