blob: 4cc055a78b116c3446c4c2eb05907acfc9b8fdf1 [file] [log] [blame]
// 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.
package org.mozc.android.inputmethod.japanese;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.KeyEvent.ModifierKey;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.KeyEvent.SpecialKey;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
/**
* Converts Androids's KeyEvent to Mozc's KeyEvent.
*
* Because Mozc to Android conversion is impossible (by information lack), such
* feature is not provided.
*
*/
public class KeycodeConverter {
/**
* KeyEventInterface just enables lazy keycode evaluation than android.view.KeyEvent.
* This interface is only used from InputMethodService.sendDownUpKeyEvents.
* The value returned by {@code getKeyCode} method is used only when a user's input
* (from s/w or h/w keyboard) is not consumed by Mozc server.
* In such a case we send back the event as a key-code to the framework.
* If consumed, {@code getKeyCode} is not invoked.
*/
public interface KeyEventInterface {
int getKeyCode();
Optional<android.view.KeyEvent> getNativeEvent();
}
private static final int ASCII_MIN = 32; // Space.
private static final int ASCII_MAX = 126; // Tilde.
private static final int NUM_ASCII = ASCII_MAX - ASCII_MIN + 1;
// Pre-generated KeyEvents for commonly used key codes.
private static final ProtoCommands.KeyEvent[] keyCodeToMozcKeyCodeEvent =
new ProtoCommands.KeyEvent[NUM_ASCII];
public static final ProtoCommands.KeyEvent SPECIALKEY_SPACE =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.SPACE).build();
// TODO(matsuzakit): UP (and DOWN) is no more used. Remove.
public static final ProtoCommands.KeyEvent SPECIALKEY_UP =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.UP).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_VIRTUAL_LEFT =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.VIRTUAL_LEFT).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_VIRTUAL_RIGHT =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.VIRTUAL_RIGHT).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_VIRTUAL_ENTER =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.VIRTUAL_ENTER).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_DOWN =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.DOWN).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_BACKSPACE =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.BACKSPACE).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_ESCAPE =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.ESCAPE).build();
public static final ProtoCommands.KeyEvent SPECIALKEY_SHIFT_LEFT =
ProtoCommands.KeyEvent.newBuilder()
.setSpecialKey(SpecialKey.LEFT)
.addModifierKeys(ModifierKey.SHIFT)
.build();
public static final ProtoCommands.KeyEvent SPECIALKEY_SHIFT_RIGHT =
ProtoCommands.KeyEvent.newBuilder()
.setSpecialKey(SpecialKey.RIGHT)
.addModifierKeys(ModifierKey.SHIFT)
.build();
public static final ProtoCommands.KeyEvent SPECIALKEY_CTRL_BACKSPACE =
ProtoCommands.KeyEvent.newBuilder()
.setSpecialKey(SpecialKey.BACKSPACE)
.addModifierKeys(ModifierKey.CTRL)
.build();
static {
for (int i = ASCII_MIN; i <= ASCII_MAX; ++i) {
keyCodeToMozcKeyCodeEvent[i - ASCII_MIN] =
ProtoCommands.KeyEvent.newBuilder().setKeyCode(i).build();
}
}
public static ProtoCommands.KeyEvent getMozcKeyEvent(int keyCode) {
int offsetKeyCode = keyCode - ASCII_MIN;
if (offsetKeyCode >= 0 && offsetKeyCode < NUM_ASCII) {
return keyCodeToMozcKeyCodeEvent[offsetKeyCode];
}
// FallBack.
return ProtoCommands.KeyEvent.newBuilder().setKeyCode(keyCode).build();
}
public static KeyEventInterface getKeyEventInterface(final android.view.KeyEvent keyEvent) {
Preconditions.checkNotNull(keyEvent);
return new KeyEventInterface() {
@Override
public int getKeyCode() {
return keyEvent.getKeyCode();
}
@Override
public Optional<android.view.KeyEvent> getNativeEvent() {
return Optional.of(keyEvent);
}
};
}
public static KeyEventInterface getKeyEventInterface(final int keyCode) {
return new KeyEventInterface() {
@Override
public int getKeyCode() {
return keyCode;
}
@Override
public Optional<android.view.KeyEvent> getNativeEvent() {
return Optional.<android.view.KeyEvent>absent();
}
};
}
public static boolean isMetaKey(android.view.KeyEvent keyEvent) {
int keyCode = Preconditions.checkNotNull(keyEvent).getKeyCode();
return keyCode == android.view.KeyEvent.KEYCODE_SHIFT_LEFT ||
keyCode == android.view.KeyEvent.KEYCODE_SHIFT_RIGHT ||
keyCode == android.view.KeyEvent.KEYCODE_CTRL_LEFT ||
keyCode == android.view.KeyEvent.KEYCODE_CTRL_RIGHT ||
keyCode == android.view.KeyEvent.KEYCODE_ALT_LEFT ||
keyCode == android.view.KeyEvent.KEYCODE_ALT_RIGHT;
}
}