1cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard/*
2cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * Copyright (C) 2012 The Android Open Source Project
3cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard *
4cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * Licensed under the Apache License, Version 2.0 (the "License");
5cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * you may not use this file except in compliance with the License.
6cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * You may obtain a copy of the License at
7cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard *
8cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard *      http://www.apache.org/licenses/LICENSE-2.0
9cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard *
10cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * Unless required by applicable law or agreed to in writing, software
11cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * distributed under the License is distributed on an "AS IS" BASIS,
12cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * See the License for the specific language governing permissions and
14cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * limitations under the License.
15cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard */
16cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard
17cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalardpackage com.android.inputmethod.event;
18cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard
19581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalardimport android.view.KeyCharacterMap;
20cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalardimport android.view.KeyEvent;
21cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard
22997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalardimport com.android.inputmethod.latin.Constants;
23997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard
24cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard/**
25cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard * A hardware event decoder for a hardware qwerty-ish keyboard.
26581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard *
27581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard * The events are always hardware keypresses, but they can be key down or key up events, they
28581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard * can be dead keys, they can be meta keys like shift or ctrl... This does not deal with
29581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard * 10-key like keyboards; a different decoder is used for this.
30cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard */
31cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalardpublic class HardwareKeyboardEventDecoder implements HardwareEventDecoder {
32cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard    final int mDeviceId;
33cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard
34cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard    public HardwareKeyboardEventDecoder(final int deviceId) {
35cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard        mDeviceId = deviceId;
36cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard        // TODO: get the layout for this hardware keyboard
37cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard    }
38cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard
39cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard    @Override
405112b59db2beece8353da9044bc297ab7f2df6f3Jean Chalard    public Event decodeHardwareKey(final KeyEvent keyEvent) {
41581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard        // KeyEvent#getUnicodeChar() does not exactly returns a unicode char, but rather a value
42581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard        // that includes both the unicode char in the lower 21 bits and flags in the upper bits,
43581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard        // hence the name "codePointAndFlags". {@see KeyEvent#getUnicodeChar()} for more info.
44581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard        final int codePointAndFlags = keyEvent.getUnicodeChar();
45997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        // The keyCode is the abstraction used by the KeyEvent to represent different keys that
46997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        // do not necessarily map to a unicode character. This represents a physical key, like
47997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        // the key for 'A' or Space, but also Backspace or Ctrl or Caps Lock.
48997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        final int keyCode = keyEvent.getKeyCode();
492282e8520a2c1984989a14fb09896536f5033b26Jean Chalard        final boolean isKeyRepeat = (0 != keyEvent.getRepeatCount());
50997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        if (KeyEvent.KEYCODE_DEL == keyCode) {
51a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard            return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, Constants.CODE_DELETE,
522282e8520a2c1984989a14fb09896536f5033b26Jean Chalard                    null /* next */, isKeyRepeat);
53997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        }
54997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard        if (keyEvent.isPrintingKey() || KeyEvent.KEYCODE_SPACE == keyCode
55997cba7decce9694b3c2f9487deb9710ebb19595Jean Chalard                || KeyEvent.KEYCODE_ENTER == keyCode) {
56581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard            if (0 != (codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT)) {
57581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard                // A dead key.
586c75253c114991f9878822f018898d7f4bd90986Jean Chalard                return Event.createDeadEvent(
5992db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard                        codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT_MASK, keyCode,
6092db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard                        null /* next */);
61581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard            }
62b4ac04ae4891d74a7cabd6438a1369624255fc13Jean Chalard            if (KeyEvent.KEYCODE_ENTER == keyCode) {
63b4ac04ae4891d74a7cabd6438a1369624255fc13Jean Chalard                // The Enter key. If the Shift key is not being pressed, this should send a
644e4f88127b6a75302fac3a004e41fff1899a773fJean Chalard                // CODE_ENTER to trigger the action if any, or a carriage return otherwise. If the
654e4f88127b6a75302fac3a004e41fff1899a773fJean Chalard                // Shift key is being pressed, this should send a CODE_SHIFT_ENTER and let
664e4f88127b6a75302fac3a004e41fff1899a773fJean Chalard                // Latin IME decide what to do with it.
6792db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard                if (keyEvent.isShiftPressed()) {
68a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard                    return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT,
692282e8520a2c1984989a14fb09896536f5033b26Jean Chalard                            Constants.CODE_SHIFT_ENTER, null /* next */, isKeyRepeat);
7092db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard                } else {
71a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard                    return Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
722282e8520a2c1984989a14fb09896536f5033b26Jean Chalard                            null /* next */, isKeyRepeat);
7392db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard                }
74b4ac04ae4891d74a7cabd6438a1369624255fc13Jean Chalard            }
7592db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard            // If not Enter, then this is just a regular keypress event for a normal character
7692db209c60f82dee19e2c684ef58093817bf8bbaJean Chalard            // that can be committed right away, taking into account the current state.
7709291050a028192a39fd745c6696df1c504eb38bJean Chalard            return Event.createHardwareKeypressEvent(codePointAndFlags, keyCode, null /* next */,
782282e8520a2c1984989a14fb09896536f5033b26Jean Chalard                    isKeyRepeat);
79581f324ed8314befdf7d8cf1c923791455cc11a5Jean Chalard        }
80b4ac04ae4891d74a7cabd6438a1369624255fc13Jean Chalard        return Event.createNotHandledEvent();
81cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard    }
82cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard}
83