Index: remoting/host/linux/x_server_character_injector.cc |
diff --git a/remoting/host/linux/x_server_character_injector.cc b/remoting/host/linux/x_server_character_injector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cb29d477eb105eeeb20f63fef00450fdbcea2cdb |
--- /dev/null |
+++ b/remoting/host/linux/x_server_character_injector.cc |
@@ -0,0 +1,70 @@ |
+// 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/x_server_character_injector.h" |
+ |
+#include <X11/XKBlib.h> |
+ |
+#include "base/bind.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "remoting/host/linux/keyboard_interface.h" |
+ |
+namespace remoting { |
+ |
+XServerCharacterInjector::XServerCharacterInjector(KeyboardInterface* keyboard) |
+ : keyboard_(keyboard), |
+ task_runner_(base::ThreadTaskRunnerHandle::Get()), |
Sergey Ulanov
2016/09/21 19:59:23
I don't think you need this. Just use base::Thread
Yuwei
2016/09/23 01:40:37
Done.
|
+ key_mapper_(keyboard), |
+ weak_factory_(this) {} |
+ |
+XServerCharacterInjector::~XServerCharacterInjector() {} |
+ |
+void XServerCharacterInjector::Inject(uint32_t code_point) { |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ characters_queue_.push(code_point); |
+ Schedule(base::TimeDelta()); |
+} |
+ |
+void XServerCharacterInjector::Schedule(base::TimeDelta delay) { |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ if (consume_scheduled_) { |
Sergey Ulanov
2016/09/21 19:59:23
DCHECK(!consume_scheduled_)
Yuwei
2016/09/23 01:40:37
Obsolete. Changed the definition of Schedule() a l
|
+ return; |
+ } |
+ task_runner_->PostDelayedTask(FROM_HERE, |
+ base::Bind(&XServerCharacterInjector::Consume, |
+ weak_factory_.GetWeakPtr()), |
+ delay); |
+ consume_scheduled_ = true; |
+} |
+ |
+void XServerCharacterInjector::Consume() { |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ consume_scheduled_ = false; |
Sergey Ulanov
2016/09/21 19:59:23
Addd DCHECK(consume_scheduled_);
Yuwei
2016/09/23 01:40:37
Obsolete. Add check for `scheduled_consume_time_ &
|
+ while (!characters_queue_.empty()) { |
+ uint32_t code_point = characters_queue_.front(); |
+ uint32_t keycode; |
+ uint32_t modifiers; |
+ if (!keyboard_->FindKeycode(code_point, &keycode, &modifiers)) { |
+ XServerKeyMapper::MapResult result = |
+ key_mapper_.AddNewCharacter(code_point); |
+ if (!result.success) { |
+ if (result.retry_after.is_zero()) { |
+ continue; |
+ } else { |
Sergey Ulanov
2016/09/21 19:59:23
don't need else after continue
Yuwei
2016/09/23 01:40:37
Done.
|
+ Schedule(result.retry_after); |
+ break; |
+ } |
+ } |
+ keycode = result.keycode; |
+ modifiers = 0; |
+ } |
+ keyboard_->PressKey(keycode, modifiers); |
+ |
+ characters_queue_.pop(); |
+ } |
+ |
+ keyboard_->Flush(); |
+} |
+ |
+} // namespace remoting |