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

Side by Side Diff: remoting/host/linux/x11_keyboard_impl.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/linux/x11_keyboard_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/host/linux/x11_keyboard_impl.h"
6
7 #include <X11/extensions/XInput.h>
8 #include <X11/extensions/XTest.h>
9 #include <X11/XKBlib.h>
10
11 #include "base/strings/stringprintf.h"
12 #include "remoting/host/linux/unicode_to_keysym.h"
13 #include "ui/gfx/x/x11_types.h"
14
15 namespace {
16
17 bool FindKeycodeForKeySym(Display* display,
18 KeySym key_sym,
19 uint32_t* keycode,
20 uint32_t* modifiers) {
21 uint32_t found_keycode = XKeysymToKeycode(display, key_sym);
22
23 const uint32_t kModifiersToTry[] = {
24 0,
25 ShiftMask,
26 Mod2Mask,
27 Mod3Mask,
28 Mod4Mask,
29 ShiftMask | Mod2Mask,
30 ShiftMask | Mod3Mask,
31 ShiftMask | Mod4Mask,
32 };
33
34 // TODO(sergeyu): Is there a better way to find modifiers state?
35 for (size_t i = 0; i < arraysize(kModifiersToTry); ++i) {
36 unsigned long key_sym_with_mods;
37 if (XkbLookupKeySym(display, found_keycode, kModifiersToTry[i], nullptr,
38 &key_sym_with_mods) &&
39 key_sym_with_mods == key_sym) {
40 *modifiers = kModifiersToTry[i];
41 *keycode = found_keycode;
42 return true;
43 }
44 }
45 return false;
46 }
47
48 } // namespace
49
50 namespace remoting {
51
52 X11KeyboardImpl::X11KeyboardImpl(Display* display) : display_(display) {}
53
54 X11KeyboardImpl::~X11KeyboardImpl() {}
55
56 std::vector<uint32_t> X11KeyboardImpl::GetUnusedKeycodes() {
57 std::vector<uint32_t> unused_keycodes_;
58 int min_keycode;
59 int max_keycode;
60 XDisplayKeycodes(display_, &min_keycode, &max_keycode);
61 uint32_t keycode_count = max_keycode - min_keycode + 1;
62
63 int sym_per_key;
64 gfx::XScopedPtr<KeySym> mapping(
65 XGetKeyboardMapping(display_, min_keycode, keycode_count, &sym_per_key));
66 for (int keycode = max_keycode; keycode >= min_keycode; keycode--) {
67 bool used = false;
68 int offset = (keycode - min_keycode) * sym_per_key;
69 for (int level = 0; level < sym_per_key; level++) {
70 if (mapping.get()[offset + level]) {
71 used = true;
72 break;
73 }
74 }
75 if (!used) {
76 unused_keycodes_.push_back(keycode);
77 }
78 }
79 return unused_keycodes_;
80 }
81
82 void X11KeyboardImpl::PressKey(uint32_t keycode, uint32_t modifiers) {
83 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers);
84
85 XTestFakeKeyEvent(display_, keycode, True, CurrentTime);
86 XTestFakeKeyEvent(display_, keycode, False, CurrentTime);
87
88 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0);
89 }
90
91 bool X11KeyboardImpl::FindKeycode(uint32_t code_point,
92 uint32_t* keycode,
93 uint32_t* modifiers) {
94 for (uint32_t keysym : GetKeySymsForUnicode(code_point)) {
95 if (FindKeycodeForKeySym(display_, keysym, keycode, modifiers)) {
96 return true;
97 }
98 }
99 return false;
100 }
101
102 bool X11KeyboardImpl::ChangeKeyMapping(uint32_t keycode, uint32_t code_point) {
103 KeySym sym = NoSymbol;
104 if (code_point > 0) {
105 std::string sym_hex = base::StringPrintf("U%x", code_point);
106 sym = XStringToKeysym(sym_hex.c_str());
107 if (sym == NoSymbol) {
108 // The server may not support Unicode-to-KeySym translation.
109 return false;
110 }
111 }
112
113 KeySym syms[2]{sym, sym}; // {lower-case, upper-case}
114 XChangeKeyboardMapping(display_, keycode, 2, syms, 1);
115 return true;
116 }
117
118 void X11KeyboardImpl::Flush() {
119 XFlush(display_);
120 }
121
122 void X11KeyboardImpl::Sync() {
123 XSync(display_, false);
124 }
125
126 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/linux/x11_keyboard_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698