KeyCharacterMap.h revision 6b53e8daa69cba1a2a5a7c95a01e37ce9c53226c
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef _UI_KEY_CHARACTER_MAP_H
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define _UI_KEY_CHARACTER_MAP_H
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
226b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <ui/Input.h>
236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <utils/Errors.h>
246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <utils/KeyedVector.h>
256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <utils/Tokenizer.h>
266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <utils/String8.h>
276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <utils/Unicode.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownnamespace android {
306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown/**
326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * Describes a mapping from Android key codes to characters.
336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * Also specifies other functions of the keyboard such as the keyboard type
346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown * and key modifier semantics.
356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown */
366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownclass KeyCharacterMap {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    enum KeyboardType {
396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_UNKNOWN = 0,
406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_NUMERIC = 1,
416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_PREDICTIVE = 2,
426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_ALPHA = 3,
436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_FULL = 4,
446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    };
466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~KeyCharacterMap();
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static status_t load(const String8& filename, KeyCharacterMap** outMap);
506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static status_t loadByDeviceId(int32_t deviceId, KeyCharacterMap** outMap);
516b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets the keyboard type. */
536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    int32_t getKeyboardType() const;
546b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets the primary character for this key as in the label physically printed on it.
566b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * Returns 0 if none (eg. for non-printing keys). */
576b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    char16_t getDisplayLabel(int32_t keyCode) const;
586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets the Unicode character for the number or symbol generated by the key
606b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * when the keyboard is used as a dialing pad.
616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * Returns 0 if no number or symbol is generated.
626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     */
636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    char16_t getNumber(int32_t keyCode) const;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets the Unicode character generated by the key and meta key modifiers.
666b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * Returns 0 if no character is generated.
676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     */
686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets the first matching Unicode character that can be generated by the key,
716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * preferring the one with the specified meta key modifiers.
726b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * Returns 0 if no matching character is generated.
736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     */
746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    char16_t getMatch(int32_t keyCode, const char16_t* chars,
756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            size_t numChars, int32_t metaState) const;
766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    /* Gets a sequence of key events that could plausibly generate the specified
786b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     * character sequence.  Returns false if some of the characters cannot be generated.
796b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown     */
806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            Vector<KeyEvent>& outEvents) const;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
846b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    struct Behavior {
856b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Behavior();
866b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
876b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The next behavior in the list, or NULL if none. */
886b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Behavior* next;
896b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
906b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The meta key modifiers for this behavior. */
916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        int32_t metaState;
926b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
936b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The character to insert. */
946b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        char16_t character;
956b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
966b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The fallback keycode if the key is not handled. */
976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        int32_t fallbackKeyCode;
986b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    };
996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1006b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    struct Key {
1016b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Key();
1026b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ~Key();
1036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The single character label printed on the key, or 0 if none. */
1056b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        char16_t label;
1066b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The number or symbol character generated by the key, or 0 if none. */
1086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        char16_t number;
1096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1106b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        /* The list of key behaviors sorted from most specific to least specific
1116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown         * meta key binding. */
1126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Behavior* firstBehavior;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    class Parser {
1166b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        enum State {
1176b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            STATE_TOP = 0,
1186b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            STATE_KEY = 1,
1196b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        };
1206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1216b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        enum {
1226b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            PROPERTY_LABEL = 1,
1236b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            PROPERTY_NUMBER = 2,
1246b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            PROPERTY_META = 3,
1256b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        };
1266b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1276b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        struct Property {
1286b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            inline Property(int32_t property = 0, int32_t metaState = 0) :
1296b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                    property(property), metaState(metaState) { }
1306b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1316b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t property;
1326b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t metaState;
1336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        };
1346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1356b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        KeyCharacterMap* mMap;
1366b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Tokenizer* mTokenizer;
1376b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        State mState;
1386b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        int32_t mKeyCode;
1396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1406b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    public:
1416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        Parser(KeyCharacterMap* map, Tokenizer* tokenizer);
1426b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        ~Parser();
1436b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parse();
1446b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    private:
1466b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parseType();
1476b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parseKey();
1486b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parseKeyProperty();
1496b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parseModifier(const String8& token, int32_t* outMetaState);
1506b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown        status_t parseCharacterLiteral(char16_t* outCharacter);
1516b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    };
1526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1536b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    KeyedVector<int32_t, Key*> mKeys;
1546b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    int mType;
1556b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    KeyCharacterMap();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1586b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
1596b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1606b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static void addKey(Vector<KeyEvent>& outEvents,
1616b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
1626b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static void addMetaKeys(Vector<KeyEvent>& outEvents,
1636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
1646b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t* currentMetaState);
1656b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
1666b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
1676b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t keyCode, int32_t keyMetaState,
1686b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t* currentMetaState);
1696b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
1706b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
1716b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t leftKeyCode, int32_t leftKeyMetaState,
1726b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t rightKeyCode, int32_t rightKeyMetaState,
1736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t eitherKeyMetaState,
1746b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t* currentMetaState);
1756b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
1766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t deviceId, int32_t metaState, nsecs_t time,
1776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t keyCode, int32_t keyMetaState,
1786b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            int32_t* currentMetaState);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1816b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown} // namespace android
1826b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif // _UI_KEY_CHARACTER_MAP_H
184