Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.event;
     18 
     19 import android.view.KeyCharacterMap;
     20 import android.view.KeyEvent;
     21 
     22 import com.android.inputmethod.latin.common.Constants;
     23 
     24 /**
     25  * A hardware event decoder for a hardware qwerty-ish keyboard.
     26  *
     27  * The events are always hardware keypresses, but they can be key down or key up events, they
     28  * can be dead keys, they can be meta keys like shift or ctrl... This does not deal with
     29  * 10-key like keyboards; a different decoder is used for this.
     30  */
     31 public class HardwareKeyboardEventDecoder implements HardwareEventDecoder {
     32     final int mDeviceId;
     33 
     34     public HardwareKeyboardEventDecoder(final int deviceId) {
     35         mDeviceId = deviceId;
     36         // TODO: get the layout for this hardware keyboard
     37     }
     38 
     39     @Override
     40     public Event decodeHardwareKey(final KeyEvent keyEvent) {
     41         // KeyEvent#getUnicodeChar() does not exactly returns a unicode char, but rather a value
     42         // that includes both the unicode char in the lower 21 bits and flags in the upper bits,
     43         // hence the name "codePointAndFlags". {@see KeyEvent#getUnicodeChar()} for more info.
     44         final int codePointAndFlags = keyEvent.getUnicodeChar();
     45         // The keyCode is the abstraction used by the KeyEvent to represent different keys that
     46         // do not necessarily map to a unicode character. This represents a physical key, like
     47         // the key for 'A' or Space, but also Backspace or Ctrl or Caps Lock.
     48         final int keyCode = keyEvent.getKeyCode();
     49         final boolean isKeyRepeat = (0 != keyEvent.getRepeatCount());
     50         if (KeyEvent.KEYCODE_DEL == keyCode) {
     51             return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, Constants.CODE_DELETE,
     52                     null /* next */, isKeyRepeat);
     53         }
     54         if (keyEvent.isPrintingKey() || KeyEvent.KEYCODE_SPACE == keyCode
     55                 || KeyEvent.KEYCODE_ENTER == keyCode) {
     56             if (0 != (codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT)) {
     57                 // A dead key.
     58                 return Event.createDeadEvent(
     59                         codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT_MASK, keyCode,
     60                         null /* next */);
     61             }
     62             if (KeyEvent.KEYCODE_ENTER == keyCode) {
     63                 // The Enter key. If the Shift key is not being pressed, this should send a
     64                 // CODE_ENTER to trigger the action if any, or a carriage return otherwise. If the
     65                 // Shift key is being pressed, this should send a CODE_SHIFT_ENTER and let
     66                 // Latin IME decide what to do with it.
     67                 if (keyEvent.isShiftPressed()) {
     68                     return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT,
     69                             Constants.CODE_SHIFT_ENTER, null /* next */, isKeyRepeat);
     70                 }
     71                 return Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
     72                         null /* next */, isKeyRepeat);
     73             }
     74             // If not Enter, then this is just a regular keypress event for a normal character
     75             // that can be committed right away, taking into account the current state.
     76             return Event.createHardwareKeypressEvent(codePointAndFlags, keyCode, null /* next */,
     77                     isKeyRepeat);
     78         }
     79         return Event.createNotHandledEvent();
     80     }
     81 }
     82