Codebase list mozc / debian/1.2.855.102-1 session / key_parser.cc
debian/1.2.855.102-1

Tree @debian/1.2.855.102-1 (Download .tar.gz)

key_parser.cc @debian/1.2.855.102-1raw · history · blame

// Copyright 2010-2011, 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 "base/base.h"
#include "base/singleton.h"
#include "base/util.h"
#include "session/commands.pb.h"
#include "session/internal/keymap_interface.h"

namespace mozc {

namespace {

class KeyParserData {
 public:
  KeyParserData() {
    InitData();
  }

  const map<string, commands::KeyEvent::SpecialKey> &keycode_map() {
    return keycode_map_;
  }
  const map<string, commands::KeyEvent::ModifierKey> &modifiers_map() {
    return modifiers_map_;
  }

 private:
  void InitData() {
    //  CHECK(keymap::KeyType::NUM_KEYTYPES < static_cast<int32>(' '));
    VLOG(1) << "Init KeyParser Data";

    modifiers_map_["ctrl"] = commands::KeyEvent::CTRL;
    modifiers_map_["control"] = commands::KeyEvent::CTRL;
    modifiers_map_["alt"] = commands::KeyEvent::ALT;
    modifiers_map_["option"] = commands::KeyEvent::ALT;
    modifiers_map_["meta"] = commands::KeyEvent::ALT;
    modifiers_map_["super"] = commands::KeyEvent::ALT;
    modifiers_map_["hyper"] = commands::KeyEvent::ALT;
    modifiers_map_["shift"] = commands::KeyEvent::SHIFT;
    modifiers_map_["caps"] = commands::KeyEvent::CAPS;
    modifiers_map_["keydown"] = commands::KeyEvent::KEY_DOWN;
    modifiers_map_["keyup"] = commands::KeyEvent::KEY_UP;

    keycode_map_["on"] = commands::KeyEvent::ON;
    keycode_map_["off"] = commands::KeyEvent::OFF;
    keycode_map_["left"] = commands::KeyEvent::LEFT;
    keycode_map_["down"] = commands::KeyEvent::DOWN;
    keycode_map_["up"] = commands::KeyEvent::UP;
    keycode_map_["right"] = commands::KeyEvent::RIGHT;
    keycode_map_["enter"] = commands::KeyEvent::ENTER;
    keycode_map_["return"] = commands::KeyEvent::ENTER;
    keycode_map_["esc"] = commands::KeyEvent::ESCAPE;
    keycode_map_["escape"] = commands::KeyEvent::ESCAPE;
    keycode_map_["delete"] = commands::KeyEvent::DEL;
    keycode_map_["del"] = commands::KeyEvent::DEL;
    keycode_map_["bs"] = commands::KeyEvent::BACKSPACE;
    keycode_map_["backspace"] = commands::KeyEvent::BACKSPACE;
    keycode_map_["henkan"] = commands::KeyEvent::HENKAN;
    keycode_map_["muhenkan"] = commands::KeyEvent::MUHENKAN;
    keycode_map_["kana"] = commands::KeyEvent::KANA;
    keycode_map_["hiragana"] = commands::KeyEvent::KANA;
    keycode_map_["katakana"] = commands::KeyEvent::KATAKANA;
    keycode_map_["eisu"] = commands::KeyEvent::EISU;
    keycode_map_["home"] = commands::KeyEvent::HOME;
    keycode_map_["end"] = commands::KeyEvent::END;
    keycode_map_["space"] = commands::KeyEvent::SPACE;
    keycode_map_["ascii"] = commands::KeyEvent::ASCII;
    keycode_map_["tab"] = commands::KeyEvent::TAB;
    keycode_map_["pageup"] = commands::KeyEvent::PAGE_UP;
    keycode_map_["pagedown"] = commands::KeyEvent::PAGE_DOWN;
    keycode_map_["insert"] = commands::KeyEvent::INSERT;
    keycode_map_["hankaku"] = commands::KeyEvent::HANKAKU;
    keycode_map_["zenkaku"] = commands::KeyEvent::HANKAKU;
    keycode_map_["hankaku/zenkaku"] = commands::KeyEvent::HANKAKU;
    keycode_map_["kanji"] = commands::KeyEvent::KANJI;

    keycode_map_["f1"] = commands::KeyEvent::F1;
    keycode_map_["f2"] = commands::KeyEvent::F2;
    keycode_map_["f3"] = commands::KeyEvent::F3;
    keycode_map_["f4"] = commands::KeyEvent::F4;
    keycode_map_["f5"] = commands::KeyEvent::F5;
    keycode_map_["f6"] = commands::KeyEvent::F6;
    keycode_map_["f7"] = commands::KeyEvent::F7;
    keycode_map_["f8"] = commands::KeyEvent::F8;
    keycode_map_["f9"] = commands::KeyEvent::F9;
    keycode_map_["f10"] = commands::KeyEvent::F10;
    keycode_map_["f11"] = commands::KeyEvent::F11;
    keycode_map_["f12"] = commands::KeyEvent::F12;
    keycode_map_["f13"] = commands::KeyEvent::F13;
    keycode_map_["f14"] = commands::KeyEvent::F14;
    keycode_map_["f15"] = commands::KeyEvent::F15;
    keycode_map_["f16"] = commands::KeyEvent::F16;
    keycode_map_["f17"] = commands::KeyEvent::F17;
    keycode_map_["f18"] = commands::KeyEvent::F18;
    keycode_map_["f19"] = commands::KeyEvent::F19;
    keycode_map_["f20"] = commands::KeyEvent::F20;
    keycode_map_["f21"] = commands::KeyEvent::F21;
    keycode_map_["f22"] = commands::KeyEvent::F22;
    keycode_map_["f23"] = commands::KeyEvent::F23;
    keycode_map_["f24"] = commands::KeyEvent::F24;

    keycode_map_["numpad0"] = commands::KeyEvent::NUMPAD0;
    keycode_map_["numpad1"] = commands::KeyEvent::NUMPAD1;
    keycode_map_["numpad2"] = commands::KeyEvent::NUMPAD2;
    keycode_map_["numpad3"] = commands::KeyEvent::NUMPAD3;
    keycode_map_["numpad4"] = commands::KeyEvent::NUMPAD4;
    keycode_map_["numpad5"] = commands::KeyEvent::NUMPAD5;
    keycode_map_["numpad6"] = commands::KeyEvent::NUMPAD6;
    keycode_map_["numpad7"] = commands::KeyEvent::NUMPAD7;
    keycode_map_["numpad8"] = commands::KeyEvent::NUMPAD8;
    keycode_map_["numpad9"] = commands::KeyEvent::NUMPAD9;

    keycode_map_["multiply"] = commands::KeyEvent::MULTIPLY;
    keycode_map_["add"] = commands::KeyEvent::ADD;
    keycode_map_["separator"] = commands::KeyEvent::SEPARATOR;
    keycode_map_["subtract"] = commands::KeyEvent::SUBTRACT;
    keycode_map_["decimal"] = commands::KeyEvent::DECIMAL;
    keycode_map_["divide"] = commands::KeyEvent::DIVIDE;
    keycode_map_["equals"] = commands::KeyEvent::EQUALS;
  }

  map<string, commands::KeyEvent::SpecialKey> keycode_map_;
  map<string, commands::KeyEvent::ModifierKey> modifiers_map_;
};
}  // namespace

bool KeyParser::ParseKey(const string &key_string,
                         commands::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,
                               commands::KeyEvent *key_event) {
  CHECK(key_event);

  const map<string, commands::KeyEvent::ModifierKey> &modifiers_map =
    Singleton<KeyParserData>::get()->modifiers_map();
  const map<string, commands::KeyEvent::SpecialKey> &keycode_map =
    Singleton<KeyParserData>::get()->keycode_map();

  key_event->Clear();

  for (size_t i = 0; i < keys.size(); ++i) {
    if (Util::CharsLen(keys[i]) == 1) {
      const char *begin = keys[i].c_str();
      size_t mblen = 0;
      uint16 key_code = Util::UTF8ToUCS2(begin, begin + keys[i].size(), &mblen);
      key_event->set_key_code(key_code);
    } else {
      string key = keys[i];
      Util::LowerString(&key);
      if (modifiers_map.count(key) == 1) {
        key_event->add_modifier_keys(modifiers_map.find(key)->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;
      }
    }
  }
  return true;
}

}  // namespace mozc