Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: remoting/host/input_injector_x11.cc

Issue 2346643003: [Remoting Host] Handle text event characters that are not presented on the keyboard (Closed)
Patch Set: Reviewer's Feedback Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/host/BUILD.gn ('k') | remoting/host/linux/unicode_to_keysym.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/input_injector.h" 5 #include "remoting/host/input_injector.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <X11/extensions/XInput.h> 9 #include <X11/extensions/XInput.h>
10 #include <X11/extensions/XTest.h> 10 #include <X11/extensions/XTest.h>
11 #include <X11/Xlib.h> 11 #include <X11/Xlib.h>
12 #include <X11/XKBlib.h> 12 #include <X11/XKBlib.h>
13 #undef Status // Xlib.h #defines this, which breaks protobuf headers. 13 #undef Status // Xlib.h #defines this, which breaks protobuf headers.
14 14
15 #include <set> 15 #include <set>
16 #include <utility> 16 #include <utility>
17 17
18 #include "base/bind.h" 18 #include "base/bind.h"
19 #include "base/compiler_specific.h" 19 #include "base/compiler_specific.h"
20 #include "base/location.h" 20 #include "base/location.h"
21 #include "base/macros.h" 21 #include "base/macros.h"
22 #include "base/memory/ptr_util.h"
22 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
23 #include "base/strings/utf_string_conversion_utils.h" 24 #include "base/strings/utf_string_conversion_utils.h"
24 #include "build/build_config.h" 25 #include "build/build_config.h"
25 #include "remoting/base/logging.h" 26 #include "remoting/base/logging.h"
26 #include "remoting/host/clipboard.h" 27 #include "remoting/host/clipboard.h"
27 #include "remoting/host/linux/unicode_to_keysym.h" 28 #include "remoting/host/linux/unicode_to_keysym.h"
29 #include "remoting/host/linux/x11_character_injector.h"
30 #include "remoting/host/linux/x11_keyboard_impl.h"
28 #include "remoting/host/linux/x11_util.h" 31 #include "remoting/host/linux/x11_util.h"
29 #include "remoting/proto/internal.pb.h" 32 #include "remoting/proto/internal.pb.h"
30 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 33 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
31 #include "ui/events/keycodes/dom/dom_code.h" 34 #include "ui/events/keycodes/dom/dom_code.h"
32 #include "ui/events/keycodes/dom/keycode_converter.h" 35 #include "ui/events/keycodes/dom/keycode_converter.h"
33 36
34 #if defined(OS_CHROMEOS) 37 #if defined(OS_CHROMEOS)
35 #include "remoting/host/chromeos/point_transformer.h" 38 #include "remoting/host/chromeos/point_transformer.h"
36 #endif 39 #endif
37 40
38 namespace remoting { 41 namespace remoting {
39 42
40 namespace { 43 namespace {
41 44
42 using protocol::ClipboardEvent; 45 using protocol::ClipboardEvent;
43 using protocol::KeyEvent; 46 using protocol::KeyEvent;
44 using protocol::TextEvent; 47 using protocol::TextEvent;
45 using protocol::MouseEvent; 48 using protocol::MouseEvent;
46 using protocol::TouchEvent; 49 using protocol::TouchEvent;
47 50
48 bool FindKeycodeForKeySym(Display* display,
49 KeySym key_sym,
50 uint32_t* keycode,
51 uint32_t* modifiers) {
52 *keycode = XKeysymToKeycode(display, key_sym);
53
54 const uint32_t kModifiersToTry[] = {
55 0,
56 ShiftMask,
57 Mod2Mask,
58 Mod3Mask,
59 Mod4Mask,
60 ShiftMask | Mod2Mask,
61 ShiftMask | Mod3Mask,
62 ShiftMask | Mod4Mask,
63 };
64
65 // TODO(sergeyu): Is there a better way to find modifiers state?
66 for (size_t i = 0; i < arraysize(kModifiersToTry); ++i) {
67 unsigned long key_sym_with_mods;
68 if (XkbLookupKeySym(display, *keycode, kModifiersToTry[i], nullptr,
69 &key_sym_with_mods) &&
70 key_sym_with_mods == key_sym) {
71 *modifiers = kModifiersToTry[i];
72 return true;
73 }
74 }
75
76 return false;
77 }
78
79 // Finds a keycode and set of modifiers that generate character with the
80 // specified |code_point|.
81 bool FindKeycodeForUnicode(Display* display,
82 uint32_t code_point,
83 uint32_t* keycode,
84 uint32_t* modifiers) {
85 std::vector<uint32_t> keysyms;
86 GetKeySymsForUnicode(code_point, &keysyms);
87
88 for (std::vector<uint32_t>::iterator it = keysyms.begin();
89 it != keysyms.end(); ++it) {
90 if (FindKeycodeForKeySym(display, *it, keycode, modifiers)) {
91 return true;
92 }
93 }
94
95 return false;
96 }
97
98 bool IsModifierKey(ui::DomCode dom_code) { 51 bool IsModifierKey(ui::DomCode dom_code) {
99 return dom_code == ui::DomCode::CONTROL_LEFT || 52 return dom_code == ui::DomCode::CONTROL_LEFT ||
100 dom_code == ui::DomCode::SHIFT_LEFT || 53 dom_code == ui::DomCode::SHIFT_LEFT ||
101 dom_code == ui::DomCode::ALT_LEFT || 54 dom_code == ui::DomCode::ALT_LEFT ||
102 dom_code == ui::DomCode::META_LEFT || 55 dom_code == ui::DomCode::META_LEFT ||
103 dom_code == ui::DomCode::CONTROL_RIGHT || 56 dom_code == ui::DomCode::CONTROL_RIGHT ||
104 dom_code == ui::DomCode::SHIFT_RIGHT || 57 dom_code == ui::DomCode::SHIFT_RIGHT ||
105 dom_code == ui::DomCode::ALT_RIGHT || 58 dom_code == ui::DomCode::ALT_RIGHT ||
106 dom_code == ui::DomCode::META_RIGHT; 59 dom_code == ui::DomCode::META_RIGHT;
107 } 60 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 static const int kNumPointerButtons = 7; 145 static const int kNumPointerButtons = 7;
193 146
194 int pointer_button_map_[kNumPointerButtons]; 147 int pointer_button_map_[kNumPointerButtons];
195 148
196 #if defined(OS_CHROMEOS) 149 #if defined(OS_CHROMEOS)
197 PointTransformer point_transformer_; 150 PointTransformer point_transformer_;
198 #endif 151 #endif
199 152
200 std::unique_ptr<Clipboard> clipboard_; 153 std::unique_ptr<Clipboard> clipboard_;
201 154
155 std::unique_ptr<X11CharacterInjector> character_injector_;
156
202 bool saved_auto_repeat_enabled_; 157 bool saved_auto_repeat_enabled_;
203 158
204 DISALLOW_COPY_AND_ASSIGN(Core); 159 DISALLOW_COPY_AND_ASSIGN(Core);
205 }; 160 };
206 161
207 scoped_refptr<Core> core_; 162 scoped_refptr<Core> core_;
208 163
209 DISALLOW_COPY_AND_ASSIGN(InputInjectorX11); 164 DISALLOW_COPY_AND_ASSIGN(InputInjectorX11);
210 }; 165 };
211 166
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 312 }
358 pressed_keys_.clear(); 313 pressed_keys_.clear();
359 314
360 const std::string text = event.text(); 315 const std::string text = event.text();
361 for (int32_t index = 0; index < static_cast<int32_t>(text.size()); ++index) { 316 for (int32_t index = 0; index < static_cast<int32_t>(text.size()); ++index) {
362 uint32_t code_point; 317 uint32_t code_point;
363 if (!base::ReadUnicodeCharacter( 318 if (!base::ReadUnicodeCharacter(
364 text.c_str(), text.size(), &index, &code_point)) { 319 text.c_str(), text.size(), &index, &code_point)) {
365 continue; 320 continue;
366 } 321 }
367 322 character_injector_->Inject(code_point);
368 uint32_t keycode;
369 uint32_t modifiers;
370 if (!FindKeycodeForUnicode(display_, code_point, &keycode, &modifiers))
371 continue;
372
373 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers);
374
375 XTestFakeKeyEvent(display_, keycode, True, CurrentTime);
376 XTestFakeKeyEvent(display_, keycode, False, CurrentTime);
377
378 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0);
379 } 323 }
380
381 XFlush(display_);
382 } 324 }
383 325
384 InputInjectorX11::Core::~Core() { 326 InputInjectorX11::Core::~Core() {
385 CHECK(pressed_keys_.empty()); 327 CHECK(pressed_keys_.empty());
386 } 328 }
387 329
388 void InputInjectorX11::Core::InitClipboard() { 330 void InputInjectorX11::Core::InitClipboard() {
389 DCHECK(task_runner_->BelongsToCurrentThread()); 331 DCHECK(task_runner_->BelongsToCurrentThread());
390 clipboard_ = Clipboard::Create(); 332 clipboard_ = Clipboard::Create();
391 } 333 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 if (!task_runner_->BelongsToCurrentThread()) { 569 if (!task_runner_->BelongsToCurrentThread()) {
628 task_runner_->PostTask( 570 task_runner_->PostTask(
629 FROM_HERE, 571 FROM_HERE,
630 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); 572 base::Bind(&Core::Start, this, base::Passed(&client_clipboard)));
631 return; 573 return;
632 } 574 }
633 575
634 InitMouseButtonMap(); 576 InitMouseButtonMap();
635 577
636 clipboard_->Start(std::move(client_clipboard)); 578 clipboard_->Start(std::move(client_clipboard));
579
580 character_injector_.reset(
581 new X11CharacterInjector(base::MakeUnique<X11KeyboardImpl>(display_)));
637 } 582 }
638 583
639 void InputInjectorX11::Core::Stop() { 584 void InputInjectorX11::Core::Stop() {
640 if (!task_runner_->BelongsToCurrentThread()) { 585 if (!task_runner_->BelongsToCurrentThread()) {
641 task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); 586 task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this));
642 return; 587 return;
643 } 588 }
644 589
645 clipboard_.reset(); 590 clipboard_.reset();
591 character_injector_.reset();
646 } 592 }
647 593
648 } // namespace 594 } // namespace
649 595
650 // static 596 // static
651 std::unique_ptr<InputInjector> InputInjector::Create( 597 std::unique_ptr<InputInjector> InputInjector::Create(
652 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 598 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
653 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { 599 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
654 std::unique_ptr<InputInjectorX11> injector( 600 std::unique_ptr<InputInjectorX11> injector(
655 new InputInjectorX11(main_task_runner)); 601 new InputInjectorX11(main_task_runner));
656 if (!injector->Init()) 602 if (!injector->Init())
657 return nullptr; 603 return nullptr;
658 return std::move(injector); 604 return std::move(injector);
659 } 605 }
660 606
661 // static 607 // static
662 bool InputInjector::SupportsTouchEvents() { 608 bool InputInjector::SupportsTouchEvents() {
663 return false; 609 return false;
664 } 610 }
665 611
666 } // namespace remoting 612 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/BUILD.gn ('k') | remoting/host/linux/unicode_to_keysym.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698