public boolean handleKeyCode(int keyCode, KeyEvent event, boolean appMode) throws IOException { String code = null; if (event != null) { int keyMod = 0; // META_CTRL_ON was added only in API 11, so don't use it, // use our own tracking of Ctrl key instead. // (event.getMetaState() & META_CTRL_ON) != 0 if (mHardwareControlKey || mControlKey.isActive()) { keyMod |= KEYMOD_CTRL; } if ((event.getMetaState() & META_ALT_ON) != 0) { keyMod |= KEYMOD_ALT; } if ((event.getMetaState() & META_SHIFT_ON) != 0) { keyMod |= KEYMOD_SHIFT; } // First try to map scancode code = mKeyMap.get(event.getScanCode() | KEYMOD_SCAN | keyMod); if (code == null) { code = mKeyMap.get(keyCode | keyMod); } } if (code == null && keyCode >= 0 && keyCode < mKeyCodes.length) { if (appMode) { code = mAppKeyCodes[keyCode]; } if (code == null) { code = mKeyCodes[keyCode]; } } if (code != null) { if (EmulatorDebug.LOG_CHARACTERS_FLAG) { byte[] bytes = code.getBytes(); Log.d( EmulatorDebug.LOG_TAG, "Out: '" + EmulatorDebug.bytesToString(bytes, 0, bytes.length) + "'"); } mTermSession.write(code); return true; } return false; }
public boolean isCtrlActive() { return mControlKey.isActive(); }
public boolean isAltActive() { return mAltKey.isActive(); }
/** * Handle a keyDown event. * * @param keyCode the keycode of the keyDown event */ public void keyDown(int keyCode, KeyEvent event, boolean appMode, boolean allowToggle) throws IOException { if (LOG_KEYS) { Log.i(TAG, "keyDown(" + keyCode + "," + event + "," + appMode + "," + allowToggle + ")"); } if (handleKeyCode(keyCode, event, appMode)) { return; } int result = -1; boolean chordedCtrl = false; boolean setHighBit = false; switch (keyCode) { case KeyEvent.KEYCODE_ALT_RIGHT: case KeyEvent.KEYCODE_ALT_LEFT: if (allowToggle) { mAltKey.onPress(); updateCursorMode(); } break; case KeyEvent.KEYCODE_SHIFT_LEFT: case KeyEvent.KEYCODE_SHIFT_RIGHT: if (allowToggle) { mCapKey.onPress(); updateCursorMode(); } break; case KEYCODE_CTRL_LEFT: case KEYCODE_CTRL_RIGHT: // Ignore the control key. return; case KEYCODE_CAPS_LOCK: // Ignore the capslock key. return; case KEYCODE_FUNCTION: // Ignore the function key. return; case KeyEvent.KEYCODE_BACK: result = mBackKeyCode; break; default: { int metaState = event.getMetaState(); chordedCtrl = ((META_CTRL_ON & metaState) != 0); boolean effectiveCaps = allowToggle && (mCapKey.isActive()); boolean effectiveAlt = allowToggle && mAltKey.isActive(); int effectiveMetaState = metaState & (~META_CTRL_MASK); if (effectiveCaps) { effectiveMetaState |= KeyEvent.META_SHIFT_ON; } if (!allowToggle && (effectiveMetaState & META_ALT_ON) != 0) { effectiveAlt = true; } if (effectiveAlt) { if (mAltSendsEsc) { mTermSession.write(new byte[] {0x1b}, 0, 1); effectiveMetaState &= ~KeyEvent.META_ALT_MASK; } else if (SUPPORT_8_BIT_META) { setHighBit = true; effectiveMetaState &= ~KeyEvent.META_ALT_MASK; } else { // Legacy behavior: Pass Alt through to allow composing characters. effectiveMetaState |= KeyEvent.META_ALT_ON; } } // Note: The Hacker keyboard IME key labeled Alt actually sends Meta. if ((metaState & KeyEvent.META_META_ON) != 0) { if (mAltSendsEsc) { mTermSession.write(new byte[] {0x1b}, 0, 1); effectiveMetaState &= ~KeyEvent.META_META_MASK; } else { if (SUPPORT_8_BIT_META) { setHighBit = true; effectiveMetaState &= ~KeyEvent.META_META_MASK; } } } result = event.getUnicodeChar(effectiveMetaState); if ((result & KeyCharacterMap.COMBINING_ACCENT) != 0) { if (LOG_COMBINING_ACCENT) { Log.i(TAG, "Got combining accent " + result); } mCombiningAccent = result & KeyCharacterMap.COMBINING_ACCENT_MASK; return; } if (mCombiningAccent != 0) { int unaccentedChar = result; result = KeyCharacterMap.getDeadChar(mCombiningAccent, unaccentedChar); if (LOG_COMBINING_ACCENT) { Log.i( TAG, "getDeadChar(" + mCombiningAccent + ", " + unaccentedChar + ") -> " + result); } mCombiningAccent = 0; } break; } } boolean effectiveControl = chordedCtrl || mHardwareControlKey || (allowToggle && mControlKey.isActive()); boolean effectiveFn = allowToggle && mFnKey.isActive(); result = mapControlChar(effectiveControl, effectiveFn, result); if (result >= KEYCODE_OFFSET) { handleKeyCode(result - KEYCODE_OFFSET, null, appMode); } else if (result >= 0) { if (setHighBit) { result |= 0x80; } mTermSession.write(result); } }
public int mapControlChar(int ch) { return mapControlChar(mHardwareControlKey || mControlKey.isActive(), mFnKey.isActive(), ch); }