| // Copyright 2010-2014, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| // Parser of key events |
| |
| #include "session/key_parser.h" |
| |
| #include <map> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/logging.h" |
| #include "base/port.h" |
| #include "base/singleton.h" |
| #include "base/util.h" |
| #include "session/commands.pb.h" |
| |
| namespace mozc { |
| using commands::KeyEvent; |
| |
| namespace { |
| |
| typedef map<string, KeyEvent::SpecialKey> SpecialKeysMap; |
| typedef multimap<string, KeyEvent::ModifierKey> ModifiersMap; |
| |
| class KeyParserData { |
| public: |
| KeyParserData() { |
| InitData(); |
| } |
| |
| const SpecialKeysMap &keycode_map() { |
| return keycode_map_; |
| } |
| const ModifiersMap &modifiers_map() { |
| return modifiers_map_; |
| } |
| |
| private: |
| void InitData() { |
| // CHECK(keymap::KeyType::NUM_KEYTYPES < static_cast<int32>(' ')); |
| VLOG(1) << "Init KeyParser Data"; |
| |
| modifiers_map_.insert(make_pair("ctrl", KeyEvent::CTRL)); |
| modifiers_map_.insert(make_pair("control", KeyEvent::CTRL)); |
| modifiers_map_.insert(make_pair("alt", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("option", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("meta", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("super", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("hyper", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("shift", KeyEvent::SHIFT)); |
| modifiers_map_.insert(make_pair("caps", KeyEvent::CAPS)); |
| modifiers_map_.insert(make_pair("keydown", KeyEvent::KEY_DOWN)); |
| modifiers_map_.insert(make_pair("keyup", KeyEvent::KEY_UP)); |
| |
| modifiers_map_.insert(make_pair("leftctrl", KeyEvent::CTRL)); |
| modifiers_map_.insert(make_pair("leftctrl", KeyEvent::LEFT_CTRL)); |
| modifiers_map_.insert(make_pair("rightctrl", KeyEvent::CTRL)); |
| modifiers_map_.insert(make_pair("rightctrl", KeyEvent::RIGHT_CTRL)); |
| modifiers_map_.insert(make_pair("leftalt", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("leftalt", KeyEvent::LEFT_ALT)); |
| modifiers_map_.insert(make_pair("rightalt", KeyEvent::ALT)); |
| modifiers_map_.insert(make_pair("rightalt", KeyEvent::RIGHT_ALT)); |
| modifiers_map_.insert(make_pair("leftshift", KeyEvent::SHIFT)); |
| modifiers_map_.insert(make_pair("leftshift", KeyEvent::LEFT_SHIFT)); |
| modifiers_map_.insert(make_pair("rightshift", KeyEvent::SHIFT)); |
| modifiers_map_.insert(make_pair("rightshift", KeyEvent::RIGHT_SHIFT)); |
| |
| keycode_map_["on"] = KeyEvent::ON; |
| keycode_map_["off"] = KeyEvent::OFF; |
| keycode_map_["left"] = KeyEvent::LEFT; |
| keycode_map_["down"] = KeyEvent::DOWN; |
| keycode_map_["up"] = KeyEvent::UP; |
| keycode_map_["right"] = KeyEvent::RIGHT; |
| keycode_map_["enter"] = KeyEvent::ENTER; |
| keycode_map_["return"] = KeyEvent::ENTER; |
| keycode_map_["esc"] = KeyEvent::ESCAPE; |
| keycode_map_["escape"] = KeyEvent::ESCAPE; |
| keycode_map_["delete"] = KeyEvent::DEL; |
| keycode_map_["del"] = KeyEvent::DEL; |
| keycode_map_["bs"] = KeyEvent::BACKSPACE; |
| keycode_map_["backspace"] = KeyEvent::BACKSPACE; |
| keycode_map_["henkan"] = KeyEvent::HENKAN; |
| keycode_map_["muhenkan"] = KeyEvent::MUHENKAN; |
| keycode_map_["kana"] = KeyEvent::KANA; |
| keycode_map_["hiragana"] = KeyEvent::KANA; |
| keycode_map_["katakana"] = KeyEvent::KATAKANA; |
| keycode_map_["eisu"] = KeyEvent::EISU; |
| keycode_map_["home"] = KeyEvent::HOME; |
| keycode_map_["end"] = KeyEvent::END; |
| keycode_map_["space"] = KeyEvent::SPACE; |
| keycode_map_["ascii"] = KeyEvent::TEXT_INPUT; // deprecated |
| keycode_map_["textinput"] = KeyEvent::TEXT_INPUT; |
| keycode_map_["tab"] = KeyEvent::TAB; |
| keycode_map_["pageup"] = KeyEvent::PAGE_UP; |
| keycode_map_["pagedown"] = KeyEvent::PAGE_DOWN; |
| keycode_map_["insert"] = KeyEvent::INSERT; |
| keycode_map_["hankaku"] = KeyEvent::HANKAKU; |
| keycode_map_["zenkaku"] = KeyEvent::HANKAKU; |
| keycode_map_["hankaku/zenkaku"] = KeyEvent::HANKAKU; |
| keycode_map_["kanji"] = KeyEvent::KANJI; |
| |
| keycode_map_["f1"] = KeyEvent::F1; |
| keycode_map_["f2"] = KeyEvent::F2; |
| keycode_map_["f3"] = KeyEvent::F3; |
| keycode_map_["f4"] = KeyEvent::F4; |
| keycode_map_["f5"] = KeyEvent::F5; |
| keycode_map_["f6"] = KeyEvent::F6; |
| keycode_map_["f7"] = KeyEvent::F7; |
| keycode_map_["f8"] = KeyEvent::F8; |
| keycode_map_["f9"] = KeyEvent::F9; |
| keycode_map_["f10"] = KeyEvent::F10; |
| keycode_map_["f11"] = KeyEvent::F11; |
| keycode_map_["f12"] = KeyEvent::F12; |
| keycode_map_["f13"] = KeyEvent::F13; |
| keycode_map_["f14"] = KeyEvent::F14; |
| keycode_map_["f15"] = KeyEvent::F15; |
| keycode_map_["f16"] = KeyEvent::F16; |
| keycode_map_["f17"] = KeyEvent::F17; |
| keycode_map_["f18"] = KeyEvent::F18; |
| keycode_map_["f19"] = KeyEvent::F19; |
| keycode_map_["f20"] = KeyEvent::F20; |
| keycode_map_["f21"] = KeyEvent::F21; |
| keycode_map_["f22"] = KeyEvent::F22; |
| keycode_map_["f23"] = KeyEvent::F23; |
| keycode_map_["f24"] = KeyEvent::F24; |
| |
| keycode_map_["numpad0"] = KeyEvent::NUMPAD0; |
| keycode_map_["numpad1"] = KeyEvent::NUMPAD1; |
| keycode_map_["numpad2"] = KeyEvent::NUMPAD2; |
| keycode_map_["numpad3"] = KeyEvent::NUMPAD3; |
| keycode_map_["numpad4"] = KeyEvent::NUMPAD4; |
| keycode_map_["numpad5"] = KeyEvent::NUMPAD5; |
| keycode_map_["numpad6"] = KeyEvent::NUMPAD6; |
| keycode_map_["numpad7"] = KeyEvent::NUMPAD7; |
| keycode_map_["numpad8"] = KeyEvent::NUMPAD8; |
| keycode_map_["numpad9"] = KeyEvent::NUMPAD9; |
| |
| keycode_map_["multiply"] = KeyEvent::MULTIPLY; |
| keycode_map_["add"] = KeyEvent::ADD; |
| keycode_map_["separator"] = KeyEvent::SEPARATOR; |
| keycode_map_["subtract"] = KeyEvent::SUBTRACT; |
| keycode_map_["decimal"] = KeyEvent::DECIMAL; |
| keycode_map_["divide"] = KeyEvent::DIVIDE; |
| keycode_map_["equals"] = KeyEvent::EQUALS; |
| keycode_map_["comma"] = KeyEvent::COMMA; |
| keycode_map_["clear"] = KeyEvent::CLEAR; |
| |
| keycode_map_["virtualleft"] = KeyEvent::VIRTUAL_LEFT; |
| keycode_map_["virtualright"] = KeyEvent::VIRTUAL_RIGHT; |
| keycode_map_["virtualenter"] = KeyEvent::VIRTUAL_ENTER; |
| |
| // Meant to be used for any other special keys. |
| keycode_map_["undefinedkey"] = KeyEvent::UNDEFINED_KEY; |
| } |
| |
| SpecialKeysMap keycode_map_; |
| ModifiersMap modifiers_map_; |
| }; |
| } // namespace |
| |
| bool KeyParser::ParseKey(const string &key_string, |
| KeyEvent *key_event) { |
| if (Util::GetFormType(key_string) != mozc::Util::HALF_WIDTH) { |
| LOG(ERROR) << "key should be half-width"; |
| return false; |
| } |
| vector<string> keys; |
| Util::SplitStringUsing(key_string, " ", &keys); |
| if (keys.empty()) { |
| LOG(ERROR) << "keys is empty"; |
| return false; |
| } |
| return KeyParser::ParseKeyVector(keys, key_event); |
| } |
| |
| bool KeyParser::ParseKeyVector(const vector<string> &keys, |
| KeyEvent *key_event) { |
| CHECK(key_event); |
| |
| const ModifiersMap &modifiers_map = |
| Singleton<KeyParserData>::get()->modifiers_map(); |
| const SpecialKeysMap &keycode_map = |
| Singleton<KeyParserData>::get()->keycode_map(); |
| |
| key_event->Clear(); |
| set<commands::KeyEvent::ModifierKey> modifiers_set; |
| |
| for (size_t i = 0; i < keys.size(); ++i) { |
| if (Util::CharsLen(keys[i]) == 1) { |
| char32 key_code = 0; |
| if (Util::SplitFirstChar32(keys[i], &key_code, NULL)) { |
| key_event->set_key_code(key_code); |
| } |
| } else { |
| string key = keys[i]; |
| Util::LowerString(&key); |
| |
| if (modifiers_map.count(key) > 0) { |
| pair<ModifiersMap::const_iterator, ModifiersMap::const_iterator> range = |
| modifiers_map.equal_range(key); |
| for (ModifiersMap::const_iterator iter = range.first; |
| iter != range.second; ++iter) { |
| modifiers_set.insert(iter->second); |
| } |
| } else if (keycode_map.count(key) == 1) { |
| key_event->set_special_key(keycode_map.find(key)->second); |
| } else { |
| LOG(ERROR) << "Unknown key: " << keys[i]; |
| return false; |
| } |
| } |
| } |
| |
| for (set<commands::KeyEvent::ModifierKey>::iterator iter = |
| modifiers_set.begin(); iter != modifiers_set.end(); ++iter) { |
| key_event->add_modifier_keys(*iter); |
| } |
| |
| return true; |
| } |
| |
| } // namespace mozc |