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)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <stdlib.h>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <windows.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)bool ConvertKeyCodeToText(
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    ui::KeyboardCode key_code, int modifiers, std::string* text,
155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    std::string* error_msg) {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UINT scan_code = ::MapVirtualKeyW(key_code, MAPVK_VK_TO_VSC);
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BYTE keyboard_state[256];
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(keyboard_state, 0, 256);
195e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  *error_msg = std::string();
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (modifiers & kShiftKeyModifierMask)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keyboard_state[VK_SHIFT] |= 0x80;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (modifiers & kControlKeyModifierMask)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keyboard_state[VK_CONTROL] |= 0x80;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (modifiers & kAltKeyModifierMask)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keyboard_state[VK_MENU] |= 0x80;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wchar_t chars[5];
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int code = ::ToUnicode(key_code, scan_code, keyboard_state, chars, 4, 0);
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |ToUnicode| converts some non-text key codes like F1 to various
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // control chars. Filter those out.
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (code <= 0 || (code == 1 && iswcntrl(chars[0])))
315e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    *text = std::string();
325e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  else
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::WideToUTF8(chars, code, text);
345e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  return true;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ConvertCharToKeyCode(
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::char16 key, ui::KeyboardCode* key_code, int *necessary_modifiers,
395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    std::string* error_msg) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  short vkey_and_modifiers = ::VkKeyScanW(key);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool translated = vkey_and_modifiers != -1 &&
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                    LOBYTE(vkey_and_modifiers) != 0xFF &&
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                    HIBYTE(vkey_and_modifiers) != 0xFF;
445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  *error_msg = std::string();
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (translated) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *key_code = static_cast<ui::KeyboardCode>(LOBYTE(vkey_and_modifiers));
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int win_modifiers = HIBYTE(vkey_and_modifiers);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int modifiers = 0;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (win_modifiers & 0x01)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      modifiers |= kShiftKeyModifierMask;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (win_modifiers & 0x02)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      modifiers |= kControlKeyModifierMask;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (win_modifiers & 0x04)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      modifiers |= kAltKeyModifierMask;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore bit 0x08: It is for Hankaku key.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *necessary_modifiers = modifiers;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return translated;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
60