12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/keycode_text_conversion.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/keysym.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/XKBlib.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/Xlib.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/Xutil.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/x/x11_util.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion_x.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct KeyCodeAndXKeyCode { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode key_code; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x_key_code; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Contains a list of keyboard codes, in order, with their corresponding 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// X key code. This list is not complete. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(kkania): Merge this table with the existing one in 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// keyboard_code_conversion_x.cc. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KeyCodeAndXKeyCode kKeyCodeToXKeyCode[] = { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_BACK, 22 }, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_TAB, 23 }, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_RETURN, 36 }, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_SHIFT, 50 }, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_CONTROL, 37 }, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_MENU, 64 }, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_CAPITAL, 66 }, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_HANGUL, 130 }, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_HANJA, 131 }, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_ESCAPE, 9 }, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_SPACE, 65 }, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_PRIOR, 112 }, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NEXT, 117 }, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_END, 115 }, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_HOME, 110 }, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_LEFT, 113 }, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_UP, 111 }, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_RIGHT, 114 }, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_DOWN, 116 }, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_INSERT, 118 }, 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_DELETE, 119 }, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_0, 19 }, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_1, 10 }, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_2, 11 }, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_3, 12 }, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_4, 13 }, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_5, 14 }, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_6, 15 }, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_7, 16 }, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_8, 17 }, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_9, 18 }, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_A, 38 }, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_B, 56 }, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_C, 54 }, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_D, 40 }, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_E, 26 }, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F, 41 }, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_G, 42 }, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_H, 43 }, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_I, 31 }, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_J, 44 }, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_K, 45 }, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_L, 46 }, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_M, 58 }, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_N, 57 }, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_O, 32 }, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_P, 33 }, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_Q, 24 }, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_R, 27 }, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_S, 39 }, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_T, 28 }, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_U, 30 }, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_V, 55 }, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, 25 }, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_X, 53 }, 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_Y, 29 }, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_Z, 52 }, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_LWIN, 133 }, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD0, 90 }, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD1, 87 }, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD2, 88 }, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD3, 89 }, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD4, 83 }, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD5, 84 }, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD6, 85 }, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD7, 79 }, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD8, 80 }, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMPAD9, 81 }, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_MULTIPLY, 63 }, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_ADD, 86 }, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_SUBTRACT, 82 }, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_DECIMAL, 129 }, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_DIVIDE, 106 }, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F1, 67 }, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F2, 68 }, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F3, 69 }, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F4, 70 }, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F5, 71 }, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F6, 72 }, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F7, 73 }, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F8, 74 }, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F9, 75 }, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F10, 76 }, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F11, 95 }, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F12, 96 }, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_NUMLOCK, 77 }, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_SCROLL, 78 }, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_1, 47 }, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_PLUS, 21 }, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_COMMA, 59 }, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_MINUS, 20 }, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_PERIOD, 60 }, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_2, 61 }, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_3, 49 }, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_4, 34 }, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_5, 51 }, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_6, 35 }, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_OEM_7, 48 } 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Uses to compare two KeyCodeAndXKeyCode structs based on their key code. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool operator<(const KeyCodeAndXKeyCode& a, const KeyCodeAndXKeyCode& b) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return a.key_code < b.key_code; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the equivalent X key code for the given key code. Returns -1 if 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// no X equivalent was found. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KeyboardCodeToXKeyCode(ui::KeyboardCode key_code) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyCodeAndXKeyCode find; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find.key_code = key_code; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const KeyCodeAndXKeyCode* found = std::lower_bound( 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kKeyCodeToXKeyCode, kKeyCodeToXKeyCode + arraysize(kKeyCodeToXKeyCode), 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found >= kKeyCodeToXKeyCode + arraysize(kKeyCodeToXKeyCode) || 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found->key_code != key_code) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return found->x_key_code; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Gets the X modifier mask (Mod1Mask through Mod5Mask) for the given 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// modifier. Only checks the alt, meta, and num lock keys currently. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true on success. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetXModifierMask(Display* display, int modifier, int* x_modifier) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XModifierKeymap* mod_map = XGetModifierMapping(display); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found = false; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_mod_keys = mod_map->max_keypermod; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int mod_index = 0; mod_index <= 8; ++mod_index) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int key_index = 0; key_index < max_mod_keys; ++key_index) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int key = mod_map->modifiermap[mod_index * max_mod_keys + key_index]; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int keysym = XkbKeycodeToKeysym(display, key, 0, 0); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifier == kAltKeyModifierMask) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = keysym == XK_Alt_L || keysym == XK_Alt_R; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (modifier == kMetaKeyModifierMask) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = keysym == XK_Meta_L || keysym == XK_Meta_R; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (modifier == kNumLockKeyModifierMask) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = keysym == XK_Num_Lock; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found) { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *x_modifier = 1 << mod_index; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XFreeModifiermap(mod_map); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return found; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1805e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)bool ConvertKeyCodeToText( 1815e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) ui::KeyboardCode key_code, int modifiers, std::string* text, 1825e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) std::string* error_msg) { 1835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *error_msg = std::string(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x_key_code = KeyboardCodeToXKeyCode(key_code); 1855e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (x_key_code == -1) { 1865e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *text = std::string(); 1875e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return true; 1885e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XEvent event; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset(&event, 0, sizeof(XEvent)); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XKeyEvent* key_event = &event.xkey; 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XDisplay* display = gfx::GetXDisplay(); 1945e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (!display) { 1955e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *error_msg = 1965e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) "an X display is required for keycode conversions, consider using Xvfb"; 1975e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *text = std::string(); 1985e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return false; 1995e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->display = display; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->keycode = x_key_code; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifiers & kShiftKeyModifierMask) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->state |= ShiftMask; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifiers & kControlKeyModifierMask) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->state |= ControlMask; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make a best attempt for non-standard modifiers. 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x_modifier; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifiers & kAltKeyModifierMask && 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetXModifierMask(display, kAltKeyModifierMask, &x_modifier)) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->state |= x_modifier; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifiers & kMetaKeyModifierMask && 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetXModifierMask(display, kMetaKeyModifierMask, &x_modifier)) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->state |= x_modifier; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifiers & kNumLockKeyModifierMask && 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetXModifierMask(display, kNumLockKeyModifierMask, &x_modifier)) { 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->state |= x_modifier; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_event->type = KeyPress; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint16 character = ui::GetCharacterFromXEvent(&event); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!character) 2255e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *text = std::string(); 2265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) else 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *text = base::UTF16ToUTF8(base::string16(1, character)); 2285e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return true; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ConvertCharToKeyCode( 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::char16 key, 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode* key_code, 2345e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) int* necessary_modifiers, 2355e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) std::string* error_msg) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string key_string(base::UTF16ToUTF8(base::string16(1, key))); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found = false; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode test_code; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int test_modifiers; 2405e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *error_msg = std::string(); 2415e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) std::string conv_string; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(kKeyCodeToXKeyCode); ++i) { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_code = kKeyCodeToXKeyCode[i].key_code; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Skip the numpad keys. 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (test_code >= ui::VKEY_NUMPAD0 && test_code <= ui::VKEY_DIVIDE) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_modifiers = 0; 2485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (!ConvertKeyCodeToText( 2495e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) test_code, test_modifiers, &conv_string, error_msg)) 2505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return false; 2515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (conv_string == key_string) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = true; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_modifiers = kShiftKeyModifierMask; 2565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (!ConvertKeyCodeToText( 2575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) test_code, test_modifiers, &conv_string, error_msg)) 2585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return false; 2595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (conv_string == key_string) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = true; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *key_code = test_code; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *necessary_modifiers = test_modifiers; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return found; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 270