Home | History | Annotate | Download | only in webdriver
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/test/webdriver/keycode_text_conversion.h"
      6 
      7 #include <gdk/gdk.h>
      8 
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/common/automation_constants.h"
     12 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h"
     13 
     14 namespace webdriver {
     15 
     16 std::string ConvertKeyCodeToText(ui::KeyboardCode key_code, int modifiers) {
     17   // |gdk_keyval_to_upper| does not convert some keys like '1' to '!', so
     18   // provide |ui::GdkKeyCodeForWindowsKeyCode| with our shift state as well,
     19   // which will do basic conversions like it for us.
     20   guint gdk_key_code = ui::GdkKeyCodeForWindowsKeyCode(
     21       key_code, modifiers & automation::kShiftKeyMask);
     22   if (modifiers & automation::kShiftKeyMask)
     23     gdk_key_code = gdk_keyval_to_upper(gdk_key_code);
     24   guint32 unicode_char = gdk_keyval_to_unicode(gdk_key_code);
     25   if (!unicode_char)
     26     return std::string();
     27   gchar buffer[6];
     28   gint length = g_unichar_to_utf8(unicode_char, buffer);
     29   return std::string(buffer, length);
     30 }
     31 
     32 // Converts a character to the key code and modifier set that would
     33 // produce the character using the given keyboard layout.
     34 bool ConvertCharToKeyCode(
     35     char16 key, ui::KeyboardCode* key_code, int *necessary_modifiers) {
     36   guint gdk_key_code = gdk_unicode_to_keyval(key);
     37   if (!gdk_key_code)
     38     return false;
     39 
     40   string16 key_string;
     41   key_string.push_back(key);
     42   const std::string kNeedsShiftSymbols= "!@#$%^&*()_+~{}|\":<>?";
     43   bool is_special_symbol = IsStringASCII(key_string) &&
     44       kNeedsShiftSymbols.find(static_cast<char>(key)) != std::string::npos;
     45 
     46   glong char_count = 0;
     47   gunichar* key_string_utf32 = g_utf16_to_ucs4(
     48       &key, 1, NULL, &char_count, NULL);
     49   if (!key_string_utf32)
     50     return false;
     51   if (char_count != 1) {
     52     g_free(key_string_utf32);
     53     return false;
     54   }
     55   gunichar key_utf32 = key_string_utf32[0];
     56   g_free(key_string_utf32);
     57 
     58   if (is_special_symbol || key_utf32 != g_unichar_tolower(key_utf32))
     59     *necessary_modifiers = automation::kShiftKeyMask;
     60   ui::KeyboardCode code = ui::WindowsKeyCodeForGdkKeyCode(gdk_key_code);
     61   if (code != ui::VKEY_UNKNOWN)
     62     *key_code = code;
     63   return code != ui::VKEY_UNKNOWN;
     64 }
     65 
     66 }  // namespace webdriver
     67