// Copyright 2010-2015, 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.

#include "win32/base/keyevent_handler.h"

#include <ime.h>
#include <string.h>
#include <windows.h>

#include <set>

#include "base/logging.h"
#include "base/util.h"
#include "client/client_interface.h"
#include "config/config_handler.h"
#include "session/commands.pb.h"
#include "session/key_info_util.h"
#include "win32/base/conversion_mode_util.h"
#include "win32/base/input_state.h"
#include "win32/base/keyboard.h"

namespace mozc {
namespace win32 {
using commands::KeyEvent;
using commands::Output;

namespace {

// The Mozc protocol has expected the client to send a key event with
// |KeyEvent::HANKAKU| special key as if there was single Hankaku/Zenkaku
// key.  This is why we map both VK_DBE_SBCSCHAR and VK_DBE_DBCSCHAR into
// KeyEvent::HANKAKU.
const KeyEvent::SpecialKey kSpecialKeyMap[] = {
  KeyEvent::NO_SPECIALKEY,        // 0x00:
  KeyEvent::NO_SPECIALKEY,        // 0x01: VK_LBUTTON
  KeyEvent::NO_SPECIALKEY,        // 0x02: VK_RBUTTON
  KeyEvent::NO_SPECIALKEY,        // 0x03: VK_CANCEL
  KeyEvent::NO_SPECIALKEY,        // 0x04: VK_MBUTTON
  KeyEvent::NO_SPECIALKEY,        // 0x05: VK_XBUTTON1
  KeyEvent::NO_SPECIALKEY,        // 0x06: VK_XBUTTON2
  KeyEvent::NO_SPECIALKEY,        // 0x07:
  KeyEvent::BACKSPACE,            // 0x08: VK_BACK
  KeyEvent::TAB,                  // 0x09: VK_TAB
  KeyEvent::NO_SPECIALKEY,        // 0x0A:
  KeyEvent::NO_SPECIALKEY,        // 0x0B:
  KeyEvent::CLEAR,                // 0x0C: VK_CLEAR
  KeyEvent::ENTER,                // 0x0D: VK_RETURN
  KeyEvent::NO_SPECIALKEY,        // 0x0E:
  KeyEvent::NO_SPECIALKEY,        // 0x0F:
  KeyEvent::NO_SPECIALKEY,        // 0x10: VK_SHIFT
  KeyEvent::NO_SPECIALKEY,        // 0x11: VK_CONTROL
  KeyEvent::NO_SPECIALKEY,        // 0x12: VK_MENU
  KeyEvent::NO_SPECIALKEY,        // 0x13: VK_PAUSE
  KeyEvent::CAPS_LOCK,            // 0x14: VK_CAPITAL
  KeyEvent::NO_SPECIALKEY,        // 0x15: VK_HANGUL, VK_KANA
  KeyEvent::NO_SPECIALKEY,        // 0x16:
  KeyEvent::NO_SPECIALKEY,        // 0x17: VK_JUNJA
  KeyEvent::NO_SPECIALKEY,        // 0x18: VK_FINAL
  // VK_KANJI is very special in IMM32 mode. It activates IME in OS-side
  // regardless of the actual key binding in an IME. On the other hand,
  // this automatic activation does not happen in TSF mode. To work around
  // this anomaly, we map VK_KANJI to KeyEvent::NO_SPECIALKEY instead of
  // KeyEvent::KANJI in IMM32 mode and map VK_KANJI to KeyEvent::HANKAKU
  // via VK_DBE_DBCSCHAR in TSF mode. See b/7970379 for the background.
  KeyEvent::NO_SPECIALKEY,        // 0x19: VK_HANJA, VK_KANJI
  KeyEvent::NO_SPECIALKEY,        // 0x1A:
  KeyEvent::ESCAPE,               // 0x1B: VK_ESCAPE
  KeyEvent::HENKAN,               // 0x1C: VK_CONVERT
  KeyEvent::MUHENKAN,             // 0x1D: VK_NONCONVERT
  KeyEvent::NO_SPECIALKEY,        // 0x1E: VK_ACCEPT
  KeyEvent::NO_SPECIALKEY,        // 0x1F: VK_MODECHANGE
  KeyEvent::SPACE,                // 0x20: VK_SPACE
  KeyEvent::PAGE_UP,              // 0x21: VK_PRIOR
  KeyEvent::PAGE_DOWN,            // 0x22: VK_NEXT
  KeyEvent::END,                  // 0x23: VK_END
  KeyEvent::HOME,                 // 0x24: VK_HOME
  KeyEvent::LEFT,                 // 0x25: VK_LEFT
  KeyEvent::UP,                   // 0x26: VK_UP
  KeyEvent::RIGHT,                // 0x27: VK_RIGHT
  KeyEvent::DOWN,                 // 0x28: VK_DOWN
  KeyEvent::NO_SPECIALKEY,        // 0x29: VK_SELECT
  KeyEvent::NO_SPECIALKEY,        // 0x2A: VK_PRINT
  KeyEvent::NO_SPECIALKEY,        // 0x2B: VK_EXECUTE
  KeyEvent::NO_SPECIALKEY,        // 0x2C: VK_SNAPSHOT
  KeyEvent::INSERT,               // 0x2D: VK_INSERT
  KeyEvent::DEL,                  // 0x2E: VK_DELETE
  KeyEvent::NO_SPECIALKEY,        // 0x2F: VK_HELP
  KeyEvent::NO_SPECIALKEY,        // 0x30: VK_0
  KeyEvent::NO_SPECIALKEY,        // 0x31: VK_1
  KeyEvent::NO_SPECIALKEY,        // 0x32: VK_2
  KeyEvent::NO_SPECIALKEY,        // 0x33: VK_3
  KeyEvent::NO_SPECIALKEY,        // 0x34: VK_4
  KeyEvent::NO_SPECIALKEY,        // 0x35: VK_5
  KeyEvent::NO_SPECIALKEY,        // 0x36: VK_6
  KeyEvent::NO_SPECIALKEY,        // 0x37: VK_7
  KeyEvent::NO_SPECIALKEY,        // 0x38: VK_8
  KeyEvent::NO_SPECIALKEY,        // 0x39: VK_9
  KeyEvent::NO_SPECIALKEY,        // 0x3A:
  KeyEvent::NO_SPECIALKEY,        // 0x3B:
  KeyEvent::NO_SPECIALKEY,        // 0x3C:
  KeyEvent::NO_SPECIALKEY,        // 0x3D:
  KeyEvent::NO_SPECIALKEY,        // 0x3E:
  KeyEvent::NO_SPECIALKEY,        // 0x3F:
  KeyEvent::NO_SPECIALKEY,        // 0x40:
  KeyEvent::NO_SPECIALKEY,        // 0x41: VK_A
  KeyEvent::NO_SPECIALKEY,        // 0x42: VK_B
  KeyEvent::NO_SPECIALKEY,        // 0x43: VK_C
  KeyEvent::NO_SPECIALKEY,        // 0x44: VK_D
  KeyEvent::NO_SPECIALKEY,        // 0x45: VK_E
  KeyEvent::NO_SPECIALKEY,        // 0x46: VK_F
  KeyEvent::NO_SPECIALKEY,        // 0x47: VK_G
  KeyEvent::NO_SPECIALKEY,        // 0x48: VK_H
  KeyEvent::NO_SPECIALKEY,        // 0x49: VK_I
  KeyEvent::NO_SPECIALKEY,        // 0x4A: VK_J
  KeyEvent::NO_SPECIALKEY,        // 0x4B: VK_K
  KeyEvent::NO_SPECIALKEY,        // 0x4C: VK_L
  KeyEvent::NO_SPECIALKEY,        // 0x4D: VK_M
  KeyEvent::NO_SPECIALKEY,        // 0x4E: VK_N
  KeyEvent::NO_SPECIALKEY,        // 0x4F: VK_O
  KeyEvent::NO_SPECIALKEY,        // 0x50: VK_P
  KeyEvent::NO_SPECIALKEY,        // 0x51: VK_Q
  KeyEvent::NO_SPECIALKEY,        // 0x52: VK_R
  KeyEvent::NO_SPECIALKEY,        // 0x53: VK_S
  KeyEvent::NO_SPECIALKEY,        // 0x54: VK_T
  KeyEvent::NO_SPECIALKEY,        // 0x55: VK_U
  KeyEvent::NO_SPECIALKEY,        // 0x56: VK_V
  KeyEvent::NO_SPECIALKEY,        // 0x57: VK_W
  KeyEvent::NO_SPECIALKEY,        // 0x58: VK_X
  KeyEvent::NO_SPECIALKEY,        // 0x59: VK_Y
  KeyEvent::NO_SPECIALKEY,        // 0x5A: VK_Z
  KeyEvent::NO_SPECIALKEY,        // 0x5B: VK_LWIN
  KeyEvent::NO_SPECIALKEY,        // 0x5C: VK_RWIN
  KeyEvent::NO_SPECIALKEY,        // 0x5D: VK_APPS
  KeyEvent::NO_SPECIALKEY,        // 0x5E:
  KeyEvent::NO_SPECIALKEY,        // 0x5F: VK_SLEEP
  KeyEvent::NUMPAD0,              // 0x60: VK_NUMPAD0
  KeyEvent::NUMPAD1,              // 0x61: VK_NUMPAD1
  KeyEvent::NUMPAD2,              // 0x62: VK_NUMPAD2
  KeyEvent::NUMPAD3,              // 0x63: VK_NUMPAD3
  KeyEvent::NUMPAD4,              // 0x64: VK_NUMPAD4
  KeyEvent::NUMPAD5,              // 0x65: VK_NUMPAD5
  KeyEvent::NUMPAD6,              // 0x66: VK_NUMPAD6
  KeyEvent::NUMPAD7,              // 0x67: VK_NUMPAD7
  KeyEvent::NUMPAD8,              // 0x68: VK_NUMPAD8
  KeyEvent::NUMPAD9,              // 0x69: VK_NUMPAD9
  KeyEvent::MULTIPLY,             // 0x6A: VK_MULTIPLY
  KeyEvent::ADD,                  // 0x6B: VK_ADD
  KeyEvent::SEPARATOR,            // 0x6C: VK_SEPARATOR
  KeyEvent::SUBTRACT,             // 0x6D: VK_SUBTRACT
  KeyEvent::DECIMAL,              // 0x6E: VK_DECIMAL
  KeyEvent::DIVIDE,               // 0x6F: VK_DIVIDE
  KeyEvent::F1,                   // 0x70: VK_F1
  KeyEvent::F2,                   // 0x71: VK_F2
  KeyEvent::F3,                   // 0x72: VK_F3
  KeyEvent::F4,                   // 0x73: VK_F4
  KeyEvent::F5,                   // 0x74: VK_F5
  KeyEvent::F6,                   // 0x75: VK_F6
  KeyEvent::F7,                   // 0x76: VK_F7
  KeyEvent::F8,                   // 0x77: VK_F8
  KeyEvent::F9,                   // 0x78: VK_F9
  KeyEvent::F10,                  // 0x79: VK_F10
  KeyEvent::F11,                  // 0x7A: VK_F11
  KeyEvent::F12,                  // 0x7B: VK_F12
  KeyEvent::F13,                  // 0x7C: VK_F13
  KeyEvent::F14,                  // 0x7D: VK_F14
  KeyEvent::F15,                  // 0x7E: VK_F15
  KeyEvent::F16,                  // 0x7F: VK_F16
  KeyEvent::F17,                  // 0x80: VK_F17
  KeyEvent::F18,                  // 0x81: VK_F18
  KeyEvent::F19,                  // 0x82: VK_F19
  KeyEvent::F20,                  // 0x83: VK_F20
  KeyEvent::F21,                  // 0x84: VK_F21
  KeyEvent::F22,                  // 0x85: VK_F22
  KeyEvent::F23,                  // 0x86: VK_F23
  KeyEvent::F24,                  // 0x87: VK_F24
  KeyEvent::NO_SPECIALKEY,        // 0x88:
  KeyEvent::NO_SPECIALKEY,        // 0x89:
  KeyEvent::NO_SPECIALKEY,        // 0x8A:
  KeyEvent::NO_SPECIALKEY,        // 0x8B:
  KeyEvent::NO_SPECIALKEY,        // 0x8C:
  KeyEvent::NO_SPECIALKEY,        // 0x8D:
  KeyEvent::NO_SPECIALKEY,        // 0x8E:
  KeyEvent::NO_SPECIALKEY,        // 0x8F:
  KeyEvent::NO_SPECIALKEY,        // 0x90: VK_NUMLOCK
  KeyEvent::NO_SPECIALKEY,        // 0x91: VK_SCROLL
  KeyEvent::NO_SPECIALKEY,        // 0x92: VK_OEM_FJ_JISHO, VK_OEM_NEC_EQUAL
  KeyEvent::NO_SPECIALKEY,        // 0x93: VK_OEM_FJ_MASSHOU
  KeyEvent::NO_SPECIALKEY,        // 0x94: VK_OEM_FJ_TOUROKU
  KeyEvent::NO_SPECIALKEY,        // 0x95: VK_OEM_FJ_LOYA
  KeyEvent::NO_SPECIALKEY,        // 0x96: VK_OEM_FJ_ROYA
  KeyEvent::NO_SPECIALKEY,        // 0x97:
  KeyEvent::NO_SPECIALKEY,        // 0x98:
  KeyEvent::NO_SPECIALKEY,        // 0x99:
  KeyEvent::NO_SPECIALKEY,        // 0x9A:
  KeyEvent::NO_SPECIALKEY,        // 0x9B:
  KeyEvent::NO_SPECIALKEY,        // 0x9C:
  KeyEvent::NO_SPECIALKEY,        // 0x9D:
  KeyEvent::NO_SPECIALKEY,        // 0x9E:
  KeyEvent::NO_SPECIALKEY,        // 0x9F:
  KeyEvent::NO_SPECIALKEY,        // 0xA0: VK_LSHIFT
  KeyEvent::NO_SPECIALKEY,        // 0xA1: VK_RSHIFT
  KeyEvent::NO_SPECIALKEY,        // 0xA2: VK_LCONTROL
  KeyEvent::NO_SPECIALKEY,        // 0xA3: VK_RCONTROL
  KeyEvent::NO_SPECIALKEY,        // 0xA4: VK_LMENU
  KeyEvent::NO_SPECIALKEY,        // 0xA5: VK_RMENU
  KeyEvent::NO_SPECIALKEY,        // 0xA6: VK_BROWSER_BACK
  KeyEvent::NO_SPECIALKEY,        // 0xA7: VK_BROWSER_FORWARD
  KeyEvent::NO_SPECIALKEY,        // 0xA8: VK_BROWSER_REFRESH
  KeyEvent::NO_SPECIALKEY,        // 0xA9: VK_BROWSER_STOP
  KeyEvent::NO_SPECIALKEY,        // 0xAA: VK_BROWSER_SEARCH
  KeyEvent::NO_SPECIALKEY,        // 0xAB: VK_BROWSER_FAVORITES
  KeyEvent::NO_SPECIALKEY,        // 0xAC: VK_BROWSER_HOME
  KeyEvent::NO_SPECIALKEY,        // 0xAD: VK_VOLUME_MUTE
  KeyEvent::NO_SPECIALKEY,        // 0xAE: VK_VOLUME_DOWN
  KeyEvent::NO_SPECIALKEY,        // 0xAF: VK_VOLUME_UP
  KeyEvent::NO_SPECIALKEY,        // 0xB0: VK_MEDIA_NEXT_TRACK
  KeyEvent::NO_SPECIALKEY,        // 0xB1: VK_MEDIA_PREV_TRACK
  KeyEvent::NO_SPECIALKEY,        // 0xB2: VK_MEDIA_STOP
  KeyEvent::NO_SPECIALKEY,        // 0xB3: VK_MEDIA_PLAY_PAUSE
  KeyEvent::NO_SPECIALKEY,        // 0xB4: VK_LAUNCH_MAIL
  KeyEvent::NO_SPECIALKEY,        // 0xB5: VK_LAUNCH_MEDIA_SELECT
  KeyEvent::NO_SPECIALKEY,        // 0xB6: VK_LAUNCH_APP1
  KeyEvent::NO_SPECIALKEY,        // 0xB7: VK_LAUNCH_APP2
  KeyEvent::NO_SPECIALKEY,        // 0xB8:
  KeyEvent::NO_SPECIALKEY,        // 0xB9:
  KeyEvent::NO_SPECIALKEY,        // 0xBA: VK_OEM_1
  KeyEvent::NO_SPECIALKEY,        // 0xBB: VK_OEM_PLUS
  KeyEvent::NO_SPECIALKEY,        // 0xBC: VK_OEM_COMMA
  KeyEvent::NO_SPECIALKEY,        // 0xBD: VK_OEM_MINUS
  KeyEvent::NO_SPECIALKEY,        // 0xBE: VK_OEM_PERIOD
  KeyEvent::NO_SPECIALKEY,        // 0xBF: VK_OEM_2
  KeyEvent::NO_SPECIALKEY,        // 0xC0: VK_OEM_3
  KeyEvent::NO_SPECIALKEY,        // 0xC1: VK_ABNT_C1
  // The numpad comma on the Apple Japanese 109 keyboard is somehow mapped into
  // VK_ABNT_C2, which is only defined in kbd.h.
  // See also http://blogs.msdn.com/b/michkap/archive/2006/10/07/799605.aspx
  // See also b/6639635.
  KeyEvent::COMMA,                // 0xC2: VK_ABNT_C2
  KeyEvent::NO_SPECIALKEY,        // 0xC3:
  KeyEvent::NO_SPECIALKEY,        // 0xC4:
  KeyEvent::NO_SPECIALKEY,        // 0xC5:
  KeyEvent::NO_SPECIALKEY,        // 0xC6:
  KeyEvent::NO_SPECIALKEY,        // 0xC7:
  KeyEvent::NO_SPECIALKEY,        // 0xC8:
  KeyEvent::NO_SPECIALKEY,        // 0xC9:
  KeyEvent::NO_SPECIALKEY,        // 0xCA:
  KeyEvent::NO_SPECIALKEY,        // 0xCB:
  KeyEvent::NO_SPECIALKEY,        // 0xCC:
  KeyEvent::NO_SPECIALKEY,        // 0xCD:
  KeyEvent::NO_SPECIALKEY,        // 0xCE:
  KeyEvent::NO_SPECIALKEY,        // 0xCF:
  KeyEvent::NO_SPECIALKEY,        // 0xD0:
  KeyEvent::NO_SPECIALKEY,        // 0xD1:
  KeyEvent::NO_SPECIALKEY,        // 0xD2:
  KeyEvent::NO_SPECIALKEY,        // 0xD3:
  KeyEvent::NO_SPECIALKEY,        // 0xD4:
  KeyEvent::NO_SPECIALKEY,        // 0xD5:
  KeyEvent::NO_SPECIALKEY,        // 0xD6:
  KeyEvent::NO_SPECIALKEY,        // 0xD7:
  KeyEvent::NO_SPECIALKEY,        // 0xD8:
  KeyEvent::NO_SPECIALKEY,        // 0xD9:
  KeyEvent::NO_SPECIALKEY,        // 0xDA:
  KeyEvent::NO_SPECIALKEY,        // 0xDB: VK_OEM_4
  KeyEvent::NO_SPECIALKEY,        // 0xDC: VK_OEM_5
  KeyEvent::NO_SPECIALKEY,        // 0xDD: VK_OEM_6
  KeyEvent::NO_SPECIALKEY,        // 0xDE: VK_OEM_7
  KeyEvent::NO_SPECIALKEY,        // 0xDF: VK_OEM_8
  KeyEvent::NO_SPECIALKEY,        // 0xE0:
  KeyEvent::NO_SPECIALKEY,        // 0xE1: VK_OEM_AX
  KeyEvent::NO_SPECIALKEY,        // 0xE2: VK_OEM_102
  KeyEvent::NO_SPECIALKEY,        // 0xE3: VK_ICO_HELP
  KeyEvent::NO_SPECIALKEY,        // 0xE4: VK_ICO_00
  KeyEvent::NO_SPECIALKEY,        // 0xE5: VK_PROCESSKEY
  KeyEvent::NO_SPECIALKEY,        // 0xE6: VK_ICO_CLEAR
  KeyEvent::NO_SPECIALKEY,        // 0xE7: VK_PACKET
  KeyEvent::NO_SPECIALKEY,        // 0xE8:
  KeyEvent::NO_SPECIALKEY,        // 0xE9:
  KeyEvent::NO_SPECIALKEY,        // 0xEA:
  KeyEvent::NO_SPECIALKEY,        // 0xEB:
  KeyEvent::NO_SPECIALKEY,        // 0xEC:
  KeyEvent::NO_SPECIALKEY,        // 0xED:
  KeyEvent::NO_SPECIALKEY,        // 0xEE:
  KeyEvent::NO_SPECIALKEY,        // 0xEF:
  KeyEvent::EISU,                 // 0xF0: VK_DBE_ALPHANUMERIC
  KeyEvent::KATAKANA,             // 0xF1: VK_DBE_KATAKANA
  KeyEvent::KANA,                 // 0xF2: VK_DBE_HIRAGANA
  KeyEvent::HANKAKU,              // 0xF3: VK_DBE_SBCSCHAR
  KeyEvent::HANKAKU,              // 0xF4: VK_DBE_DBCSCHAR
  KeyEvent::NO_SPECIALKEY,        // 0xF5: VK_DBE_ROMAN
  KeyEvent::NO_SPECIALKEY,        // 0xF6: VK_DBE_NOROMAN
  KeyEvent::NO_SPECIALKEY,        // 0xF7: VK_DBE_ENTERWORDREGISTERMODE
  KeyEvent::NO_SPECIALKEY,        // 0xF8: VK_DBE_ENTERIMECONFIGMODE
  KeyEvent::NO_SPECIALKEY,        // 0xF9: VK_DBE_FLUSHSTRING
  KeyEvent::NO_SPECIALKEY,        // 0xFA: VK_DBE_CODEINPUT
  KeyEvent::NO_SPECIALKEY,        // 0xFB: VK_DBE_NOCODEINPUT
  KeyEvent::NO_SPECIALKEY,        // 0xFC: VK_DBE_DETERMINESTRING
  KeyEvent::NO_SPECIALKEY,        // 0xFD: VK_DBE_ENTERDLGCONVERSIONMODE
  KeyEvent::NO_SPECIALKEY,        // 0xFE:
  KeyEvent::NO_SPECIALKEY,        // 0xFF:
};

void ClearModifyerKeyIfNeeded(
    const KeyEvent *key, set<KeyEvent::ModifierKey> *modifiers) {
  if (key == nullptr) {
    return;
  }
  if (modifiers == nullptr) {
    return;
  }
  if (key->has_special_key()) {
    switch (key->special_key()) {
      // Clear modifier keys when the key is filtered in
      // KeyBindingFilter::Encode in gui/config_dialog/keybinding_editor.cc
      case KeyEvent::EISU:      // VK_DBE_ALPHANUMERIC
      case KeyEvent::HANKAKU:   // VK_DBE_SBCSCHAR or VK_DBE_DBCSCHAR
      case KeyEvent::KANA:      // VK_DBE_HIRAGANA
      case KeyEvent::KATAKANA:  // VK_DBE_KATAKANA
        modifiers->clear();
        break;
      default:
        // Do nothing.
        break;
    }
  }
}

// See b/2576120 for details.
bool IsNotimplementedKey(const VirtualKey &virtual_key) {
  switch (virtual_key.virtual_key()) {
    case VK_DBE_ROMAN:    // Changes the mode to Roman characters.
    case VK_DBE_NOROMAN:  // Changes the mode to non-Roman characters.
      // Cuurently these keys are handled by the client, NOT the server.
      // See b/3118905
      // TODO(yukawa, komatsu): Handle these keys in the server.
      return true;
    case VK_DBE_ENTERWORDREGISTERMODE:
      // Activates the word registration dialog box.
      // Ctrl+Alt+Muhenkan on 106 Japanese Keyboard.
      return true;
    case VK_DBE_ENTERIMECONFIGMODE:
      // Activates a dialog box for setting up an IME environment.
      // Ctrl+Alt+Hankaku/Zenkaku on 106 Japanese Keyboard.
      return true;
    case VK_DBE_FLUSHSTRING:
      // Deletes the undetermined string without determining it.
      return true;
    case VK_DBE_CODEINPUT:
      // Changes the mode to code input.
      return true;
    case VK_DBE_NOCODEINPUT:
      // Changes the mode to no-code input.
      return true;
    case VK_DBE_DETERMINESTRING:
      return true;
    case VK_DBE_ENTERDLGCONVERSIONMODE:
      return true;
    default:
      return false;
  }
}

bool ConvertToKeyEventMain(const VirtualKey &virtual_key,
                           BYTE scan_code,
                           bool is_key_down,
                           bool is_menu_active,
                           const InputBehavior &behavior,
                           const InputState &ime_state,
                           const KeyboardStatus &keyboard_status,
                           Win32KeyboardInterface *keyboard,
                           commands::KeyEvent *key,
                           set<KeyEvent::ModifierKey> *modifer_keys) {
  if (key == nullptr) {
    return false;
  }
  key->Clear();

  if (modifer_keys == nullptr) {
    return false;
  }
  modifer_keys->clear();

  // Support VK_PACKET.
  if (virtual_key.virtual_key() == VK_PACKET) {
    const char32 character = virtual_key.unicode_char();
    string utf8_characters;
    Util::UCS4ToUTF8(character, &utf8_characters);
    if (utf8_characters.empty()) {
      return false;
    }
    // Setting |key_string| only to pass an arbitrary character to the
    // converter.
    key->set_key_string(utf8_characters);
    return true;
  }

  // TODO(yukawa): Distinguish left key from right key to fix b/2674446.
  if (keyboard_status.IsPressed(VK_SHIFT)) {
    modifer_keys->insert(KeyEvent::SHIFT);
  }
  if (keyboard_status.IsPressed(VK_CONTROL)) {
    modifer_keys->insert(KeyEvent::CTRL);
  }
  if (keyboard_status.IsPressed(VK_MENU)) {
    modifer_keys->insert(KeyEvent::ALT);
  }
  if (keyboard_status.IsPressed(VK_CAPITAL)) {
    modifer_keys->insert(KeyEvent::CAPS);
  }

  const KeyEvent::SpecialKey special_key =
      kSpecialKeyMap[virtual_key.virtual_key()];
  if (special_key != KeyEvent::NO_SPECIALKEY) {
    key->set_special_key(special_key);

    // Currently the Mozc server expects that the modifier keys are always
    // empty for some special keys.  So we have to clear the modifier keys if
    // needed.
    ClearModifyerKeyIfNeeded(key, modifer_keys);
    return true;
  }

  // Modifier keys should be handled.
  // Due to the anomaly of Mozc protocol, |modifer_keys| should be set even
  // when this is the key-up message of the modifier key.
  switch (virtual_key.virtual_key()) {
    case VK_SHIFT:
      modifer_keys->insert(KeyEvent::SHIFT);
      return true;
    case VK_CONTROL:
      modifer_keys->insert(KeyEvent::CTRL);
      return true;
    case VK_MENU:
      modifer_keys->insert(KeyEvent::ALT);
      return true;
    case VK_CAPITAL:
      modifer_keys->insert(KeyEvent::CAPS);
      return true;
  }

  // The high-order bit of this value is set if the key is up.
  // http://msdn.microsoft.com/en-us/library/ms646322.aspx
  const UINT to_unicode_scancode =
      static_cast<UINT>(scan_code) | (is_key_down ? 0 : 0x8000);

  const DWORD to_unicode_flag = (is_menu_active ? 1 : 0);

  KeyboardStatus keyboard_status_wo_kana_lock = keyboard_status;
  keyboard_status_wo_kana_lock.SetState(VK_KANA, 0);

  bool has_valid_key_string = false;

  // Instead of using the actual toggle state of Kana-lock key, an expected
  // toggle state of the Kana-lock is emulated based on the IME open/close
  // state and conversion mode.  See b/3046717 for details.
  // Note that we never set |key_string| when Ctrl key is pressed because
  // no valid Kana character will be generated with Ctrl key. See b/9684668.
  const bool use_kana_input =
      behavior.prefer_kana_input && ime_state.open &&
      !keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL) &&
      ((ime_state.logical_conversion_mode & IME_CMODE_NATIVE) ==
       IME_CMODE_NATIVE);

  if (use_kana_input) {
    // Make a snapshot of keyboard state, then update it so that the
    // Kana-lock state is 'locked'.
    KeyboardStatus keyboard_status_w_kana_lock = keyboard_status;
    const BYTE kKeyPressed = 0x80;
    const BYTE kKeyToggled = 0x1;
    keyboard_status_w_kana_lock.SetState(VK_KANA, kKeyPressed | kKeyToggled);

    WCHAR kana_codes[16] = {};
    const int kana_locked_length = keyboard->ToUnicode(
        virtual_key.virtual_key(), to_unicode_scancode,
        keyboard_status_w_kana_lock.status(), &kana_codes[0],
        arraysize(kana_codes),
        to_unicode_flag);
    if (kana_locked_length != 1) {
      return false;
    }
    const wchar_t kana_code = kana_codes[0];

    // TODO(yukawa): Move the following character conversion logic into
    //   mozc::Util as HalfWidthKatakanaToHiragana.
    const wchar_t whalf_katakana[] = {static_cast<wchar_t>(kana_code), L'\0' };
    string half_katakana, full_katakana, full_hiragana;
    mozc::Util::WideToUTF8(whalf_katakana, &half_katakana);
    mozc::Util::HalfWidthKatakanaToFullWidthKatakana(
        half_katakana.c_str(),
        &full_katakana);
    mozc::Util::KatakanaToHiragana(full_katakana.c_str(),
                                   &full_hiragana);
    key->set_key_string(full_hiragana);
    has_valid_key_string = true;
  }

  // To conform to Mozc protocol, we need special hack for VK_A, VK_B, ...,
  // VK_Z.  For these keys, currently we cannot support the current keyboard
  // layout.   For example, imagine a keyboard layout which generates
  // characters as follows.
  //    VK_A         -> 'a'
  //    VK_A + SHIFT -> '('
  // Unfortunately, the current Mozc protocol cannot handle these cases because
  // there is serious ambiguity betwen 'Key' and 'Character' in Mozc key
  // bindings.
  const bool is_vk_alpha =
      ('A' <= virtual_key.virtual_key() && virtual_key.virtual_key() <= 'Z');
  if (is_vk_alpha) {
    const char keycode = static_cast<char>(virtual_key.virtual_key());
    const size_t index = (keycode - 'A');
    if (keyboard_status_wo_kana_lock.IsToggled(VK_CAPITAL)) {
      // CapsLock is enabled.
      modifer_keys->insert(KeyEvent::CAPS);
      if (keyboard_status_wo_kana_lock.IsPressed(VK_SHIFT)) {
        if (!keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL)) {
          modifer_keys->erase(KeyEvent::SHIFT);
        }
        key->set_key_code('a' + index);
      } else {
        key->set_key_code('A' + index);
      }
      if (keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL)) {
        modifer_keys->insert(KeyEvent::CTRL);
        return true;
      }
      return true;
    }

    // CapsLock is not enabled.
    DCHECK(!keyboard_status_wo_kana_lock.IsPressed(VK_CAPITAL));
    if (keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL)) {
      modifer_keys->insert(KeyEvent::CTRL);
      key->set_key_code('a' + index);
      return true;
    }
    if (keyboard_status_wo_kana_lock.IsPressed(VK_SHIFT)) {
      // In this cases, SHIFT modifier should be removed.
      modifer_keys->erase(KeyEvent::SHIFT);
      key->set_key_code('A' + index);
      return true;
    }

    key->set_key_code('a' + index);
    return true;
  }

  // Mozc key binding tool does not allow to use a key combination
  // |KeyEvent::CTRL| + |KeyEvent::Shift| + X except that X is VK_A, ..., or,
  // VK_Z, or other special keys defined in Mozc protocol such as backspace
  // or space.
  if (keyboard_status_wo_kana_lock.IsPressed(VK_SHIFT) &&
      keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL)) {
    // Assume the server does not support this key combination.
    DCHECK(!is_vk_alpha);
    return false;
  }

  // To conform to Mozc protocol, we have to clear control modifier before
  // obtaining the unicode text.  For example, the mozc server expects Ctrl+^
  // to be sent as '^' + |KeyEvent::CTRL|.
  if (keyboard_status_wo_kana_lock.IsPressed(VK_CONTROL)) {
    // We can assume the shiftkey is not pressed here.
    DCHECK(!keyboard_status_wo_kana_lock.IsPressed(VK_SHIFT));

    keyboard_status_wo_kana_lock.SetState(VK_CONTROL, 0);
    keyboard_status_wo_kana_lock.SetState(VK_LCONTROL, 0);
    keyboard_status_wo_kana_lock.SetState(VK_RCONTROL, 0);
  }

  WCHAR codes[16] = {};
  int kana_unlocked_length = keyboard->ToUnicode(
      virtual_key.virtual_key(), to_unicode_scancode,
      keyboard_status_wo_kana_lock.status(), &codes[0],
      arraysize(codes), to_unicode_flag);

  // A workaround for b/3029665.
  // Keyboard drivers of the JIS keyboard do not produce a key code for
  // some key combinations such as SHIFT + '0' but the mozc server requires
  // the client to set a key code if it is in the kana mode.
  // So change the keycode for SHIFT + X to the one without SHIFT.
  // TODO(komatsu): Clarify the expected algorithm for the client.
  if ((kana_unlocked_length == 0) &&
      keyboard_status_wo_kana_lock.IsPressed(VK_SHIFT) &&
      has_valid_key_string) {
    // Remove shift key.
    keyboard_status_wo_kana_lock.SetState(VK_SHIFT, 0);
    keyboard_status_wo_kana_lock.SetState(VK_LSHIFT, 0);
    keyboard_status_wo_kana_lock.SetState(VK_RSHIFT, 0);

    kana_unlocked_length = keyboard->ToUnicode(
        virtual_key.virtual_key(), to_unicode_scancode,
        keyboard_status_wo_kana_lock.status(), &codes[0],
        arraysize(codes), to_unicode_flag);
  }

  if (kana_unlocked_length != 1) {
    return false;
  }

  // Remove the SHIFT modifier if CapsLock is not locked.
  if (modifer_keys->find(KeyEvent::CAPS) == modifer_keys->end()) {
    modifer_keys->erase(KeyEvent::SHIFT);
  }

  key->set_key_code(codes[0]);

  return true;
}

}  // namespace

KeyEventHandlerResult::KeyEventHandlerResult()
    : should_be_eaten(false),
      should_be_sent_to_server(false),
      succeeded(false) {
}

KeyEventHandlerResult KeyEventHandler::HandleKey(
    const VirtualKey &virtual_key,
    BYTE scan_code,
    bool is_key_down,
    const KeyboardStatus &keyboard_status,
    const InputBehavior &behavior,
    const InputState &ime_state,
    Win32KeyboardInterface *keyboard,
    mozc::commands::KeyEvent *key) {
  KeyEventHandlerResult result;

  if (key == nullptr) {
    result.succeeded = false;
    result.should_be_eaten = false;
    result.should_be_sent_to_server = false;
    return result;
  }

  if (behavior.disabled) {
    result.succeeded = true;
    result.should_be_eaten = false;
    result.should_be_sent_to_server = false;
    return result;
  }

  // There exist some keys which are ideally handled but the server has not
  // supported them yet.  In order not to pass these key events to the
  // application, we will trap them but do not send them to the server.
  if (IsNotimplementedKey(virtual_key)) {
    result.succeeded = true;
    result.should_be_eaten = true;
    result.should_be_sent_to_server = false;
    return result;
  }

  if (!ConvertToKeyEvent(virtual_key, scan_code, is_key_down, false,
                         behavior, ime_state, keyboard_status, keyboard, key)) {
    result.succeeded = true;
    result.should_be_eaten = false;
    result.should_be_sent_to_server = false;
    return result;
  }

  // We do not handle key message unless the key is one of force activation
  // keys.
  if (!ime_state.open) {
    // TODO(yukawa): Treat VK_PACKET as a direct mode key.
    const bool is_direct_mode_command =
        is_key_down &&
        KeyInfoUtil::ContainsKey(behavior.direct_mode_keys, *key);
    if (!is_direct_mode_command) {
      result.succeeded = true;
      result.should_be_eaten = false;
      result.should_be_sent_to_server = false;
      return result;
    }

    // For historical reasons, pass the visible conversion mode to the
    // converter.
    const DWORD repotring_mode = ime_state.visible_conversion_mode;
    commands::CompositionMode mozc_mode = commands::DIRECT;
    if (!ConversionModeUtil::GetMozcModeFromNativeMode(
            repotring_mode, &mozc_mode)) {
      result.succeeded = false;
      result.should_be_eaten = false;
      result.should_be_sent_to_server = false;
      return result;
    }
    key->set_activated(ime_state.open);
    key->set_mode(mozc_mode);
    result.succeeded = true;
    result.should_be_eaten = true;
    result.should_be_sent_to_server = true;
    return result;
  }

  DCHECK(ime_state.open);

  // For historical reasons, pass the visible conversion mode to the converter.
  const DWORD repotring_mode = ime_state.visible_conversion_mode;

  commands::CompositionMode mozc_mode = commands::HIRAGANA;
  if (!ConversionModeUtil::GetMozcModeFromNativeMode(
          repotring_mode, &mozc_mode)) {
    result.succeeded = false;
    result.should_be_eaten = false;
    result.should_be_sent_to_server = false;
    return result;
  }

  key->set_activated(ime_state.open);
  key->set_mode(mozc_mode);

  switch (virtual_key.virtual_key()) {
    case VK_SHIFT:
    case VK_CONTROL:
    case VK_MENU:
      if (is_key_down) {
        // Will not eat this message.
        result.succeeded = true;
        result.should_be_eaten = false;
        result.should_be_sent_to_server = false;
        return result;
      }
      if (ime_state.last_down_key.virtual_key() !=
          virtual_key.virtual_key()) {
        // Will not eat this message.
        result.succeeded = true;
        result.should_be_eaten = false;
        result.should_be_sent_to_server = false;
        return result;
      }
      // We will send this message to the server.
      result.succeeded = true;
      result.should_be_eaten = true;
      result.should_be_sent_to_server = true;
      return result;
      break;
  }

  // As commented above, we do not send key-up messages in general. Few
  // exceptional cases have already been examined.
  if (!is_key_down) {
    result.succeeded = true;
    result.should_be_eaten = false;
    result.should_be_sent_to_server = false;
    return result;
  }

  // We will send this message to the server.
  result.succeeded = true;
  result.should_be_eaten = true;
  result.should_be_sent_to_server = true;
  return result;
}

KeyEventHandlerResult KeyEventHandler::ImeProcessKey(
    const VirtualKey &virtual_key,
    BYTE scan_code,
    bool is_key_down,
    const KeyboardStatus &keyboard_status,
    const InputBehavior &behavior,
    const InputState &initial_state,
    const commands::Context &context,
    client::ClientInterface *client,
    Win32KeyboardInterface *keyboard,
    InputState *next_state,
    commands::Output *output) {
  // We will update kana-lock state even if the IME is disabled, including
  // safe-mode.
  KeyboardStatus new_keyboard_status;
  UnlockKanaLock(keyboard_status, keyboard, &new_keyboard_status);

  InputState dummy_state;
  if (next_state == nullptr) {
    next_state = &dummy_state;
  }
  *next_state = initial_state;

  Output dummy_output;
  if (output == nullptr) {
    output = &dummy_output;
  }
  output->Clear();

  // Although Mozc has not explicitly supported any key-up message, there exist
  // some situations where the client has to send key message when it receives
  // a key-up message.  Currently we have following exceptions.
  // - Shift/Control/Alt keys
  //    The Mozc protocol had originally allowed the client to ignore key-up
  //    events of these modifier keys but later has changed to expect the
  //    client to send a key message which contains only modifiers field and
  //    mode field to support b/2269058 and b/1995170.
  if (is_key_down) {
    // This is an ugly workaround to determine which key-up message for a
    // modifier key should be sent to the server.  Currently, the Mozc server
    // expects the client to send such a key-up message only when a modifier
    // key is released just after the same key is pressed, that is, any other
    // key is not pressed between the key-down and key-up of a modifier key.
    // Here are some examples, where [D] and [U] mean 'key down' and 'key up'.
    //   (1) [D]Shift -> [D]A -> [U]Shift -> [U]A
    //      In this case, only 'A' will be sent to the server
    //   (2) [D]Shift -> [U]Shift -> [D]A -> [U]A
    //      In this case, 'Shift' and 'A' will be sent to the server.
    //   (3) [D]Shift -> [D]Control -> [U]Shift -> [U]Control
    //      In this case, no key message will be sent to the server.
    //   (4) [D]Shift -> [D]Control -> [U]Control -> [U]Shift
    //      In this case, 'Control+Shift' will be sent to the server.  Note
    //      that |KeyEvent::modifier_keys| will contain all the modifier keys
    //      when the client receives '[U]Control'.
    // Unfortunately, it is currently client's responsibility to remember the
    // key sequence to generate appropriate key messages as expected by the
    // server.  Strictly speaking, the Mozc client is actually stateful in
    // this sense.
    next_state->last_down_key = virtual_key;
  }

  KeyEvent key;
  KeyEventHandlerResult result = HandleKey(
      virtual_key, scan_code, is_key_down, keyboard_status,
      behavior, initial_state, keyboard, &key);

  if (!result.succeeded) {
    return result;
  }

  if (!result.should_be_sent_to_server) {
    return result;
  }

  if (!client->TestSendKeyWithContext(key, context, output)) {
    result.succeeded = false;
    return result;
  }

  if (!output->has_consumed()) {
    result.succeeded = false;
    return result;
  }

  if (output->has_status()) {
    if (!mozc::win32::ConversionModeUtil::ConvertStatusFromMozcToNative(
            output->status(), behavior.prefer_kana_input,
            &next_state->open,
            &next_state->logical_conversion_mode,
            &next_state->visible_conversion_mode)) {
      result.succeeded = false;
      return result;
    }
  }

  result.should_be_eaten = output->consumed();
  return result;
}

KeyEventHandlerResult KeyEventHandler::ImeToAsciiEx(
    const VirtualKey &virtual_key,
    BYTE scan_code,
    bool is_key_down,
    const KeyboardStatus &keyboard_status,
    const InputBehavior &behavior,
    const InputState &initial_state,
    const commands::Context &context,
    client::ClientInterface *client,
    Win32KeyboardInterface *keyboard,
    InputState *next_state,
    commands::Output *output) {
  KeyboardStatus new_keyboard_status;
  UnlockKanaLock(keyboard_status, keyboard, &new_keyboard_status);

  InputState dummy_state;
  if (next_state == nullptr) {
    next_state = &dummy_state;
  }
  *next_state = initial_state;

  Output dummy_output;
  if (output == nullptr) {
    output = &dummy_output;
  }
  output->Clear();

  KeyEvent key;
  KeyEventHandlerResult result = HandleKey(
      virtual_key, scan_code, is_key_down, keyboard_status, behavior,
      initial_state, keyboard, &key);

  if (!result.succeeded) {
    return result;
  }

  if (!result.should_be_sent_to_server) {
    return result;
  }

  if (!client->SendKeyWithContext(key, context, output)) {
    result.succeeded = false;
    return result;
  }

  // Launch tool if required.
  MaybeSpawnTool(client, output);

  if (!output->has_consumed()) {
    result.succeeded = false;
    return result;
  }

  if (output->has_status()) {
    if (!mozc::win32::ConversionModeUtil::ConvertStatusFromMozcToNative(
            output->status(), behavior.prefer_kana_input,
            &next_state->open,
            &next_state->logical_conversion_mode,
            &next_state->visible_conversion_mode)) {
      result.succeeded = false;
      return result;
    }
  }

  result.should_be_eaten = output->consumed();
  return result;
}

bool KeyEventHandler::ConvertToKeyEvent(
    const VirtualKey &virtual_key,
    BYTE scan_code,
    bool is_key_down,
    bool is_menu_active,
    const InputBehavior &behavior,
    const InputState &ime_state,
    const KeyboardStatus &keyboard_status,
    Win32KeyboardInterface *keyboard,
    mozc::commands::KeyEvent *key) {
  // Since Mozc protocol requires tricky conditions for modifiers, using set
  // container makes the the main part of key event conversion simple rather
  // than using vector-like container.
  set<KeyEvent::ModifierKey> modifiers;
  const bool result = ConvertToKeyEventMain(
      virtual_key,
      scan_code,
      is_key_down,
      is_menu_active,
      behavior,
      ime_state,
      keyboard_status,
      keyboard,
      key,
      &modifiers);
  if (!result) {
    return false;
  }

  // Updates |modifier_keys| field based on the returned set of modifier keys.
  for (set<KeyEvent::ModifierKey>::const_iterator i = modifiers.begin();
       i != modifiers.end(); ++i) {
    key->add_modifier_keys(*i);
  }
  return true;
}

void KeyEventHandler::UnlockKanaLock(
    const KeyboardStatus &keyboard_status,
    Win32KeyboardInterface *keyboard,
    KeyboardStatus *new_keyboard_status) {
  KeyboardStatus dummy_status;
  if (new_keyboard_status == nullptr) {
    new_keyboard_status = &dummy_status;
  }

  *new_keyboard_status = keyboard_status;

  if (keyboard->IsKanaLocked(keyboard_status)) {
    new_keyboard_status->SetState(VK_KANA, 0);
    keyboard->SetKeyboardState(*new_keyboard_status);
  }
}

void KeyEventHandler::MaybeSpawnTool(mozc::client::ClientInterface *client,
                                     commands::Output *output) {
  // URL handling:
  // When Output::url is set, MozcTool is supposed to be launched by client.
  // At this moment, we disable this feature as it may cause security hole.
  // if (output->has_url()) {
  //   client->OpenBrowser(output->url());
  //   output->clear_url();
  // }

  // launch_tool_mode handling:
  // When Output::launch_tool_mode is set, MozcTool is supposed to be launched
  // by client with specified mode.
  // TODO(team):  move it to better place.
  if (output->has_launch_tool_mode()) {
    string mode;
    switch (output->launch_tool_mode()) {
      case commands::Output::CONFIG_DIALOG:
        mode = "config_dialog";
        break;
      case commands::Output::WORD_REGISTER_DIALOG:
        mode = "word_register_dialog";
        break;
      case commands::Output::DICTIONARY_TOOL:
        mode = "dictionary_tool";
        break;
      case commands::Output::NO_TOOL:
      default:
        // Do nothing.
        break;
    }
    output->clear_launch_tool_mode();
    if (!mode.empty()) {
      client->LaunchTool(mode, "");
    }
  }
}

void KeyEventHandler::UpdateBehaviorInImeProcessKey(
    const VirtualKey &virtual_key,
    bool is_key_down,
    const InputState &initial_state,
    InputBehavior *behavior) {
  if (behavior == nullptr) {
    return;
  }

  if (!initial_state.open) {
    return;
  }

  if (!behavior->use_romaji_key_to_toggle_input_style) {
    return;
  }

  switch (virtual_key.virtual_key()) {
    // Do not discriminate between VK_DBE_ROMAN and VK_DBE_NOROMAN because
    // these key states are not per-thread nor per-process but system-wide
    // or session-wide, which means that any key stroke in another
    // thread/process may change the global toggle state at any time.
    case VK_DBE_ROMAN:
    case VK_DBE_NOROMAN:
      if (is_key_down) {
        // Flip the input style if this is key down event.
        behavior->prefer_kana_input = !behavior->prefer_kana_input;
      }
      break;
    default:
      // Otherwise, do nothing.
      break;
  }
}
}  // namespace win32
}  // namespace mozc
