Index: remoting/host/linux/x11_character_injector.cc |
diff --git a/remoting/host/linux/x11_character_injector.cc b/remoting/host/linux/x11_character_injector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b5afb0ca28d057fb7a00fa346b5d1f7b5dce3876 |
--- /dev/null |
+++ b/remoting/host/linux/x11_character_injector.cc |
@@ -0,0 +1,61 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/host/linux/x11_character_injector.h" |
+ |
+#include <X11/XKBlib.h> |
+ |
+#include "base/bind.h" |
+#include "remoting/host/linux/x11_keyboard_impl.h" |
+ |
+namespace remoting { |
+ |
+X11CharacterInjector::X11CharacterInjector(Display* display) |
+ : keyboard_(new X11KeyboardImpl(display)), |
+ key_mapper_(keyboard_.get()), |
+ weak_factory_(this) {} |
+ |
+X11CharacterInjector::~X11CharacterInjector() {} |
+ |
+void X11CharacterInjector::Inject(uint32_t code_point) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ characters_queue_.push(code_point); |
+ Schedule(base::TimeDelta()); |
+} |
+ |
+void X11CharacterInjector::Schedule(base::TimeDelta delay) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (consume_timer_.IsRunning() && |
+ scheduled_consume_time_ > base::TimeTicks::Now() + delay) { |
+ return; |
+ } |
+ consume_timer_.Stop(); |
Sergey Ulanov
2016/09/23 18:51:27
Don't need to call Stop(). Start() call below will
Yuwei
2016/09/26 17:57:19
Done.
|
+ consume_timer_.Start(FROM_HERE, delay, this, &X11CharacterInjector::Consume); |
+ scheduled_consume_time_ = base::TimeTicks::Now() + delay; |
Sergey Ulanov
2016/09/23 18:51:27
base::TimeTicks::Now() is called twice in this fun
Yuwei
2016/09/26 17:57:19
Done.
|
+} |
+ |
+void X11CharacterInjector::Consume() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(!scheduled_consume_time_.is_null() && |
+ base::TimeTicks::Now() >= scheduled_consume_time_); |
+ scheduled_consume_time_ = base::TimeTicks(); |
+ while (!characters_queue_.empty()) { |
+ uint32_t code_point = characters_queue_.front(); |
+ X11KeyMapper::MapResult result = key_mapper_.MapCharacter(code_point); |
+ if (!result.success) { |
+ if (result.retry_after.is_zero()) { |
+ continue; |
+ } |
+ Schedule(result.retry_after); |
+ break; |
+ } |
+ keyboard_->PressKey(result.keycode, result.modifiers); |
+ |
+ characters_queue_.pop(); |
+ } |
+ |
+ keyboard_->Flush(); |
+} |
+ |
+} // namespace remoting |