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

Side by Side Diff: remoting/host/linux/x_server_keyboard_interface.cc

Issue 2346643003: [Remoting Host] Handle text event characters that are not presented on the keyboard (Closed)
Patch Set: Create KeyboardInterface and XServerKeyboardInterface Created 4 years, 3 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
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/x_server_keyboard_interface.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 *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, *keycode, kModifiersToTry[i], nullptr,
38 &key_sym_with_mods) &&
39 key_sym_with_mods == key_sym) {
40 *modifiers = kModifiersToTry[i];
41 return true;
42 }
43 }
44 return false;
45 }
46
47 KeySym CodePointToKeySym(uint32_t code_point) {
48 if (code_point == 0) {
49 return NoSymbol;
50 }
51 std::string sym_hex = base::StringPrintf("U%x", code_point);
52 return XStringToKeysym(sym_hex.c_str());
53 }
54
55 } // namespace
56
57 namespace remoting {
58
59 XServerKeyboardInterface::XServerKeyboardInterface(Display* display) :
60 display_(display) {}
61
62 XServerKeyboardInterface::~XServerKeyboardInterface() {}
63
64 std::vector<uint32_t> XServerKeyboardInterface::GetUnusedKeycodes() {
65 std::vector<uint32_t> unused_keycodes_;
66 int min_keycode;
67 int max_keycode;
68 XDisplayKeycodes(display_, &min_keycode, &max_keycode);
69 uint32_t keycode_count = max_keycode - min_keycode + 1;
70
71 int sym_per_key;
72 gfx::XScopedPtr<KeySym> mapping(XGetKeyboardMapping(
73 display_, min_keycode, keycode_count, &sym_per_key));
74 for (int keycode = max_keycode; keycode >= min_keycode; keycode--) {
75 bool used = false;
76 int offset = (keycode - min_keycode) * sym_per_key;
77 for (int level = 0; level < sym_per_key; level++) {
78 if (mapping.get()[offset + level]) {
79 used = true;
80 break;
81 }
82 }
83 if (!used) {
84 unused_keycodes_.push_back(keycode);
85 }
86 }
87 return unused_keycodes_;
88 }
89
90 void XServerKeyboardInterface::PressKey(uint32_t keycode, uint32_t modifiers) {
91 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers);
92
93 XTestFakeKeyEvent(display_, keycode, True, CurrentTime);
94 XTestFakeKeyEvent(display_, keycode, False, CurrentTime);
95
96 XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0);
97 }
98
99 bool XServerKeyboardInterface::FindKeycode(uint32_t code_point,
100 uint32_t* keycode,
101 uint32_t* modifiers) {
102 std::vector<uint32_t> keysyms;
103 GetKeySymsForUnicode(code_point, &keysyms);
104
105 for (std::vector<uint32_t>::iterator it = keysyms.begin();
Sergey Ulanov 2016/09/21 19:59:23 Use range loop please: for (auto& keysym : keysy
Yuwei 2016/09/23 01:40:38 Done.
106 it != keysyms.end(); ++it) {
107 if (FindKeycodeForKeySym(display_, *it, keycode, modifiers)) {
108 return true;
109 }
110 }
111 return false;
112 }
113
114 bool XServerKeyboardInterface::ChangeKeyMapping(
115 uint32_t keycode,
Sergey Ulanov 2016/09/21 19:59:23 int instead of uint32_t.
Yuwei 2016/09/23 01:40:37 Is there any reason we prefer int? Looks like keyc
116 uint32_t lower_case_code_point,
117 uint32_t upper_case_code_point) {
Sergey Ulanov 2016/09/21 19:59:23 Maybe use KeySym for these two parameters?
Sergey Ulanov 2016/09/21 19:59:24 Do we need it here? It doesn't appear to be useful
Yuwei 2016/09/23 01:40:37 Removed. I just thought it could be useful if we
Yuwei 2016/09/23 01:40:37 KeySym is tyepdef'ed as unsigned int. I tried to a
118 KeySym lower_case_keysym = CodePointToKeySym(lower_case_code_point);
119 KeySym upper_case_keysum = (lower_case_code_point == upper_case_code_point) ?
120 lower_case_keysym : CodePointToKeySym(upper_case_code_point);
121 if ((lower_case_code_point && !lower_case_keysym) ||
122 (upper_case_code_point && !upper_case_keysum)) {
123 // Non-null code point translated to NoSymbol. The server may not support
124 // Unicode-to-KeySym translation.
125 return false;
126 }
127 KeySym syms[2];
Sergey Ulanov 2016/09/21 19:59:24 = {lower_case_keysym, upper_case_keysum};
Yuwei 2016/09/23 01:40:37 Done.
128 syms[0] = lower_case_keysym;
129 syms[1] = upper_case_keysum;
130 XChangeKeyboardMapping(display_, keycode, 2, syms, 1);
131 return true;
132 }
133
134 void XServerKeyboardInterface::Flush() {
135 XFlush(display_);
136 }
137
138 void XServerKeyboardInterface::Sync() {
139 XSync(display_, false);
140 }
141
142 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698