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