KeyCharacterMap.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. /*
  2. * Copyright (C) 2008 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. #define LOG_TAG "KeyCharacterMap"
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #if HAVE_ANDROID_OS
  20. #include <binder/Parcel.h>
  21. #endif
  22. #include <android/keycodes.h>
  23. #include <input/InputEventLabels.h>
  24. #include <input/Keyboard.h>
  25. #include <input/KeyCharacterMap.h>
  26. #include <utils/Log.h>
  27. #include <utils/Errors.h>
  28. #include <utils/Tokenizer.h>
  29. #include <utils/Timers.h>
  30. // Enables debug output for the parser.
  31. #define DEBUG_PARSER 0
  32. // Enables debug output for parser performance.
  33. #define DEBUG_PARSER_PERFORMANCE 0
  34. // Enables debug output for mapping.
  35. #define DEBUG_MAPPING 0
  36. namespace android {
  37. static const char* WHITESPACE = " \t\r";
  38. static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
  39. struct Modifier {
  40. const char* label;
  41. int32_t metaState;
  42. };
  43. static const Modifier modifiers[] = {
  44. { "shift", AMETA_SHIFT_ON },
  45. { "lshift", AMETA_SHIFT_LEFT_ON },
  46. { "rshift", AMETA_SHIFT_RIGHT_ON },
  47. { "alt", AMETA_ALT_ON },
  48. { "lalt", AMETA_ALT_LEFT_ON },
  49. { "ralt", AMETA_ALT_RIGHT_ON },
  50. { "ctrl", AMETA_CTRL_ON },
  51. { "lctrl", AMETA_CTRL_LEFT_ON },
  52. { "rctrl", AMETA_CTRL_RIGHT_ON },
  53. { "meta", AMETA_META_ON },
  54. { "lmeta", AMETA_META_LEFT_ON },
  55. { "rmeta", AMETA_META_RIGHT_ON },
  56. { "sym", AMETA_SYM_ON },
  57. { "fn", AMETA_FUNCTION_ON },
  58. { "capslock", AMETA_CAPS_LOCK_ON },
  59. { "numlock", AMETA_NUM_LOCK_ON },
  60. { "scrolllock", AMETA_SCROLL_LOCK_ON },
  61. };
  62. #if DEBUG_MAPPING
  63. static String8 toString(const char16_t* chars, size_t numChars) {
  64. String8 result;
  65. for (size_t i = 0; i < numChars; i++) {
  66. result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
  67. }
  68. return result;
  69. }
  70. #endif
  71. // --- KeyCharacterMap ---
  72. sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap();
  73. KeyCharacterMap::KeyCharacterMap() :
  74. mType(KEYBOARD_TYPE_UNKNOWN) {
  75. }
  76. KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
  77. RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
  78. mKeysByUsageCode(other.mKeysByUsageCode) {
  79. for (size_t i = 0; i < other.mKeys.size(); i++) {
  80. mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
  81. }
  82. }
  83. KeyCharacterMap::~KeyCharacterMap() {
  84. for (size_t i = 0; i < mKeys.size(); i++) {
  85. Key* key = mKeys.editValueAt(i);
  86. delete key;
  87. }
  88. }
  89. status_t KeyCharacterMap::load(const String8& filename,
  90. Format format, sp<KeyCharacterMap>* outMap) {
  91. outMap->clear();
  92. Tokenizer* tokenizer;
  93. status_t status = Tokenizer::open(filename, &tokenizer);
  94. if (status) {
  95. ALOGE("Error %d opening key character map file %s.", status, filename.string());
  96. } else {
  97. status = load(tokenizer, format, outMap);
  98. delete tokenizer;
  99. }
  100. return status;
  101. }
  102. status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
  103. Format format, sp<KeyCharacterMap>* outMap) {
  104. outMap->clear();
  105. Tokenizer* tokenizer;
  106. status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
  107. if (status) {
  108. ALOGE("Error %d opening key character map.", status);
  109. } else {
  110. status = load(tokenizer, format, outMap);
  111. delete tokenizer;
  112. }
  113. return status;
  114. }
  115. status_t KeyCharacterMap::load(Tokenizer* tokenizer,
  116. Format format, sp<KeyCharacterMap>* outMap) {
  117. status_t status = OK;
  118. sp<KeyCharacterMap> map = new KeyCharacterMap();
  119. if (!map.get()) {
  120. ALOGE("Error allocating key character map.");
  121. status = NO_MEMORY;
  122. } else {
  123. #if DEBUG_PARSER_PERFORMANCE
  124. nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
  125. #endif
  126. Parser parser(map.get(), tokenizer, format);
  127. status = parser.parse();
  128. #if DEBUG_PARSER_PERFORMANCE
  129. nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
  130. ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
  131. tokenizer->getFilename().string(), tokenizer->getLineNumber(),
  132. elapsedTime / 1000000.0);
  133. #endif
  134. if (!status) {
  135. *outMap = map;
  136. }
  137. }
  138. return status;
  139. }
  140. sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
  141. const sp<KeyCharacterMap>& overlay) {
  142. if (overlay == NULL) {
  143. return base;
  144. }
  145. if (base == NULL) {
  146. return overlay;
  147. }
  148. sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
  149. for (size_t i = 0; i < overlay->mKeys.size(); i++) {
  150. int32_t keyCode = overlay->mKeys.keyAt(i);
  151. Key* key = overlay->mKeys.valueAt(i);
  152. ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
  153. if (oldIndex >= 0) {
  154. delete map->mKeys.valueAt(oldIndex);
  155. map->mKeys.editValueAt(oldIndex) = new Key(*key);
  156. } else {
  157. map->mKeys.add(keyCode, new Key(*key));
  158. }
  159. }
  160. for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
  161. map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
  162. overlay->mKeysByScanCode.valueAt(i));
  163. }
  164. for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
  165. map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
  166. overlay->mKeysByUsageCode.valueAt(i));
  167. }
  168. return map;
  169. }
  170. sp<KeyCharacterMap> KeyCharacterMap::empty() {
  171. return sEmpty;
  172. }
  173. int32_t KeyCharacterMap::getKeyboardType() const {
  174. return mType;
  175. }
  176. char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
  177. char16_t result = 0;
  178. const Key* key;
  179. if (getKey(keyCode, &key)) {
  180. result = key->label;
  181. }
  182. #if DEBUG_MAPPING
  183. ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
  184. #endif
  185. return result;
  186. }
  187. char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
  188. char16_t result = 0;
  189. const Key* key;
  190. if (getKey(keyCode, &key)) {
  191. result = key->number;
  192. }
  193. #if DEBUG_MAPPING
  194. ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
  195. #endif
  196. return result;
  197. }
  198. char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
  199. char16_t result = 0;
  200. const Key* key;
  201. const Behavior* behavior;
  202. if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
  203. result = behavior->character;
  204. }
  205. #if DEBUG_MAPPING
  206. ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
  207. #endif
  208. return result;
  209. }
  210. bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
  211. FallbackAction* outFallbackAction) const {
  212. outFallbackAction->keyCode = 0;
  213. outFallbackAction->metaState = 0;
  214. bool result = false;
  215. const Key* key;
  216. const Behavior* behavior;
  217. if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
  218. if (behavior->fallbackKeyCode) {
  219. outFallbackAction->keyCode = behavior->fallbackKeyCode;
  220. outFallbackAction->metaState = metaState & ~behavior->metaState;
  221. result = true;
  222. }
  223. }
  224. #if DEBUG_MAPPING
  225. ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
  226. "fallback keyCode=%d, fallback metaState=0x%08x.",
  227. keyCode, metaState, result ? "true" : "false",
  228. outFallbackAction->keyCode, outFallbackAction->metaState);
  229. #endif
  230. return result;
  231. }
  232. char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
  233. int32_t metaState) const {
  234. char16_t result = 0;
  235. const Key* key;
  236. if (getKey(keyCode, &key)) {
  237. // Try to find the most general behavior that maps to this character.
  238. // For example, the base key behavior will usually be last in the list.
  239. // However, if we find a perfect meta state match for one behavior then use that one.
  240. for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
  241. if (behavior->character) {
  242. for (size_t i = 0; i < numChars; i++) {
  243. if (behavior->character == chars[i]) {
  244. result = behavior->character;
  245. if ((behavior->metaState & metaState) == behavior->metaState) {
  246. goto ExactMatch;
  247. }
  248. break;
  249. }
  250. }
  251. }
  252. }
  253. ExactMatch: ;
  254. }
  255. #if DEBUG_MAPPING
  256. ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
  257. keyCode, toString(chars, numChars).string(), metaState, result);
  258. #endif
  259. return result;
  260. }
  261. bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
  262. Vector<KeyEvent>& outEvents) const {
  263. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  264. for (size_t i = 0; i < numChars; i++) {
  265. int32_t keyCode, metaState;
  266. char16_t ch = chars[i];
  267. if (!findKey(ch, &keyCode, &metaState)) {
  268. #if DEBUG_MAPPING
  269. ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
  270. deviceId, toString(chars, numChars).string(), ch);
  271. #endif
  272. return false;
  273. }
  274. int32_t currentMetaState = 0;
  275. addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
  276. addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
  277. addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
  278. addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
  279. }
  280. #if DEBUG_MAPPING
  281. ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
  282. deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
  283. for (size_t i = 0; i < outEvents.size(); i++) {
  284. ALOGD(" Key: keyCode=%d, metaState=0x%08x, %s.",
  285. outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
  286. outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
  287. }
  288. #endif
  289. return true;
  290. }
  291. status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
  292. if (usageCode) {
  293. ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
  294. if (index >= 0) {
  295. *outKeyCode = mKeysByUsageCode.valueAt(index);
  296. #if DEBUG_MAPPING
  297. ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
  298. scanCode, usageCode, *outKeyCode);
  299. #endif
  300. return OK;
  301. }
  302. }
  303. if (scanCode) {
  304. ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
  305. if (index >= 0) {
  306. *outKeyCode = mKeysByScanCode.valueAt(index);
  307. #if DEBUG_MAPPING
  308. ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
  309. scanCode, usageCode, *outKeyCode);
  310. #endif
  311. return OK;
  312. }
  313. }
  314. #if DEBUG_MAPPING
  315. ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
  316. #endif
  317. *outKeyCode = AKEYCODE_UNKNOWN;
  318. return NAME_NOT_FOUND;
  319. }
  320. void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState,
  321. int32_t *outKeyCode, int32_t *outMetaState) const {
  322. *outKeyCode = keyCode;
  323. *outMetaState = metaState;
  324. const Key* key;
  325. const Behavior* behavior;
  326. if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
  327. if (behavior->replacementKeyCode) {
  328. *outKeyCode = behavior->replacementKeyCode;
  329. int32_t newMetaState = metaState & ~behavior->metaState;
  330. // Reset dependent meta states.
  331. if (behavior->metaState & AMETA_ALT_ON) {
  332. newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
  333. }
  334. if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
  335. newMetaState &= ~AMETA_ALT_ON;
  336. }
  337. if (behavior->metaState & AMETA_CTRL_ON) {
  338. newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
  339. }
  340. if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
  341. newMetaState &= ~AMETA_CTRL_ON;
  342. }
  343. if (behavior->metaState & AMETA_SHIFT_ON) {
  344. newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON);
  345. }
  346. if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
  347. newMetaState &= ~AMETA_SHIFT_ON;
  348. }
  349. // ... and put universal bits back if needed
  350. *outMetaState = normalizeMetaState(newMetaState);
  351. }
  352. }
  353. #if DEBUG_MAPPING
  354. ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ "
  355. "replacement keyCode=%d, replacement metaState=0x%08x.",
  356. keyCode, metaState, *outKeyCode, *outMetaState);
  357. #endif
  358. }
  359. bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
  360. ssize_t index = mKeys.indexOfKey(keyCode);
  361. if (index >= 0) {
  362. *outKey = mKeys.valueAt(index);
  363. return true;
  364. }
  365. return false;
  366. }
  367. bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
  368. const Key** outKey, const Behavior** outBehavior) const {
  369. const Key* key;
  370. if (getKey(keyCode, &key)) {
  371. const Behavior* behavior = key->firstBehavior;
  372. while (behavior) {
  373. if (matchesMetaState(metaState, behavior->metaState)) {
  374. *outKey = key;
  375. *outBehavior = behavior;
  376. return true;
  377. }
  378. behavior = behavior->next;
  379. }
  380. }
  381. return false;
  382. }
  383. bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
  384. // Behavior must have at least the set of meta states specified.
  385. // And if the key event has CTRL, ALT or META then the behavior must exactly
  386. // match those, taking into account that a behavior can specify that it handles
  387. // one, both or either of a left/right modifier pair.
  388. if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
  389. const int32_t EXACT_META_STATES =
  390. AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
  391. | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
  392. | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
  393. int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
  394. if (behaviorMetaState & AMETA_CTRL_ON) {
  395. unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
  396. } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
  397. unmatchedMetaState &= ~AMETA_CTRL_ON;
  398. }
  399. if (behaviorMetaState & AMETA_ALT_ON) {
  400. unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
  401. } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
  402. unmatchedMetaState &= ~AMETA_ALT_ON;
  403. }
  404. if (behaviorMetaState & AMETA_META_ON) {
  405. unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
  406. } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
  407. unmatchedMetaState &= ~AMETA_META_ON;
  408. }
  409. return !unmatchedMetaState;
  410. }
  411. return false;
  412. }
  413. bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
  414. if (!ch) {
  415. return false;
  416. }
  417. for (size_t i = 0; i < mKeys.size(); i++) {
  418. const Key* key = mKeys.valueAt(i);
  419. // Try to find the most general behavior that maps to this character.
  420. // For example, the base key behavior will usually be last in the list.
  421. const Behavior* found = NULL;
  422. for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
  423. if (behavior->character == ch) {
  424. found = behavior;
  425. }
  426. }
  427. if (found) {
  428. *outKeyCode = mKeys.keyAt(i);
  429. *outMetaState = found->metaState;
  430. return true;
  431. }
  432. }
  433. return false;
  434. }
  435. void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
  436. int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
  437. outEvents.push();
  438. KeyEvent& event = outEvents.editTop();
  439. event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
  440. down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
  441. 0, keyCode, 0, metaState, 0, time, time);
  442. }
  443. void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
  444. int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
  445. int32_t* currentMetaState) {
  446. // Add and remove meta keys symmetrically.
  447. if (down) {
  448. addLockedMetaKey(outEvents, deviceId, metaState, time,
  449. AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
  450. addLockedMetaKey(outEvents, deviceId, metaState, time,
  451. AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
  452. addLockedMetaKey(outEvents, deviceId, metaState, time,
  453. AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
  454. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  455. AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
  456. AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
  457. AMETA_SHIFT_ON, currentMetaState);
  458. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  459. AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
  460. AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
  461. AMETA_ALT_ON, currentMetaState);
  462. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  463. AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
  464. AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
  465. AMETA_CTRL_ON, currentMetaState);
  466. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  467. AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
  468. AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
  469. AMETA_META_ON, currentMetaState);
  470. addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  471. AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
  472. addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
  473. AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
  474. } else {
  475. addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  476. AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
  477. addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  478. AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
  479. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  480. AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
  481. AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
  482. AMETA_META_ON, currentMetaState);
  483. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  484. AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
  485. AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
  486. AMETA_CTRL_ON, currentMetaState);
  487. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  488. AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
  489. AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
  490. AMETA_ALT_ON, currentMetaState);
  491. addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
  492. AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
  493. AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
  494. AMETA_SHIFT_ON, currentMetaState);
  495. addLockedMetaKey(outEvents, deviceId, metaState, time,
  496. AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
  497. addLockedMetaKey(outEvents, deviceId, metaState, time,
  498. AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
  499. addLockedMetaKey(outEvents, deviceId, metaState, time,
  500. AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
  501. }
  502. }
  503. bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
  504. int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
  505. int32_t keyCode, int32_t keyMetaState,
  506. int32_t* currentMetaState) {
  507. if ((metaState & keyMetaState) == keyMetaState) {
  508. *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
  509. addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
  510. return true;
  511. }
  512. return false;
  513. }
  514. void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
  515. int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
  516. int32_t leftKeyCode, int32_t leftKeyMetaState,
  517. int32_t rightKeyCode, int32_t rightKeyMetaState,
  518. int32_t eitherKeyMetaState,
  519. int32_t* currentMetaState) {
  520. bool specific = false;
  521. specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
  522. leftKeyCode, leftKeyMetaState, currentMetaState);
  523. specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
  524. rightKeyCode, rightKeyMetaState, currentMetaState);
  525. if (!specific) {
  526. addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
  527. leftKeyCode, eitherKeyMetaState, currentMetaState);
  528. }
  529. }
  530. void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
  531. int32_t deviceId, int32_t metaState, nsecs_t time,
  532. int32_t keyCode, int32_t keyMetaState,
  533. int32_t* currentMetaState) {
  534. if ((metaState & keyMetaState) == keyMetaState) {
  535. *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
  536. addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
  537. *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
  538. addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
  539. }
  540. }
  541. #if HAVE_ANDROID_OS
  542. sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
  543. sp<KeyCharacterMap> map = new KeyCharacterMap();
  544. map->mType = parcel->readInt32();
  545. size_t numKeys = parcel->readInt32();
  546. if (parcel->errorCheck()) {
  547. return NULL;
  548. }
  549. for (size_t i = 0; i < numKeys; i++) {
  550. int32_t keyCode = parcel->readInt32();
  551. char16_t label = parcel->readInt32();
  552. char16_t number = parcel->readInt32();
  553. if (parcel->errorCheck()) {
  554. return NULL;
  555. }
  556. Key* key = new Key();
  557. key->label = label;
  558. key->number = number;
  559. map->mKeys.add(keyCode, key);
  560. Behavior* lastBehavior = NULL;
  561. while (parcel->readInt32()) {
  562. int32_t metaState = parcel->readInt32();
  563. char16_t character = parcel->readInt32();
  564. int32_t fallbackKeyCode = parcel->readInt32();
  565. int32_t replacementKeyCode = parcel->readInt32();
  566. if (parcel->errorCheck()) {
  567. return NULL;
  568. }
  569. Behavior* behavior = new Behavior();
  570. behavior->metaState = metaState;
  571. behavior->character = character;
  572. behavior->fallbackKeyCode = fallbackKeyCode;
  573. behavior->replacementKeyCode = replacementKeyCode;
  574. if (lastBehavior) {
  575. lastBehavior->next = behavior;
  576. } else {
  577. key->firstBehavior = behavior;
  578. }
  579. lastBehavior = behavior;
  580. }
  581. if (parcel->errorCheck()) {
  582. return NULL;
  583. }
  584. }
  585. return map;
  586. }
  587. void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
  588. parcel->writeInt32(mType);
  589. size_t numKeys = mKeys.size();
  590. parcel->writeInt32(numKeys);
  591. for (size_t i = 0; i < numKeys; i++) {
  592. int32_t keyCode = mKeys.keyAt(i);
  593. const Key* key = mKeys.valueAt(i);
  594. parcel->writeInt32(keyCode);
  595. parcel->writeInt32(key->label);
  596. parcel->writeInt32(key->number);
  597. for (const Behavior* behavior = key->firstBehavior; behavior != NULL;
  598. behavior = behavior->next) {
  599. parcel->writeInt32(1);
  600. parcel->writeInt32(behavior->metaState);
  601. parcel->writeInt32(behavior->character);
  602. parcel->writeInt32(behavior->fallbackKeyCode);
  603. parcel->writeInt32(behavior->replacementKeyCode);
  604. }
  605. parcel->writeInt32(0);
  606. }
  607. }
  608. #endif
  609. // --- KeyCharacterMap::Key ---
  610. KeyCharacterMap::Key::Key() :
  611. label(0), number(0), firstBehavior(NULL) {
  612. }
  613. KeyCharacterMap::Key::Key(const Key& other) :
  614. label(other.label), number(other.number),
  615. firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
  616. }
  617. KeyCharacterMap::Key::~Key() {
  618. Behavior* behavior = firstBehavior;
  619. while (behavior) {
  620. Behavior* next = behavior->next;
  621. delete behavior;
  622. behavior = next;
  623. }
  624. }
  625. // --- KeyCharacterMap::Behavior ---
  626. KeyCharacterMap::Behavior::Behavior() :
  627. next(NULL), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) {
  628. }
  629. KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
  630. next(other.next ? new Behavior(*other.next) : NULL),
  631. metaState(other.metaState), character(other.character),
  632. fallbackKeyCode(other.fallbackKeyCode),
  633. replacementKeyCode(other.replacementKeyCode) {
  634. }
  635. // --- KeyCharacterMap::Parser ---
  636. KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
  637. mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
  638. }
  639. KeyCharacterMap::Parser::~Parser() {
  640. }
  641. status_t KeyCharacterMap::Parser::parse() {
  642. while (!mTokenizer->isEof()) {
  643. #if DEBUG_PARSER
  644. ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
  645. mTokenizer->peekRemainderOfLine().string());
  646. #endif
  647. mTokenizer->skipDelimiters(WHITESPACE);
  648. if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
  649. switch (mState) {
  650. case STATE_TOP: {
  651. String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
  652. if (keywordToken == "type") {
  653. mTokenizer->skipDelimiters(WHITESPACE);
  654. status_t status = parseType();
  655. if (status) return status;
  656. } else if (keywordToken == "map") {
  657. mTokenizer->skipDelimiters(WHITESPACE);
  658. status_t status = parseMap();
  659. if (status) return status;
  660. } else if (keywordToken == "key") {
  661. mTokenizer->skipDelimiters(WHITESPACE);
  662. status_t status = parseKey();
  663. if (status) return status;
  664. } else {
  665. ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
  666. keywordToken.string());
  667. return BAD_VALUE;
  668. }
  669. break;
  670. }
  671. case STATE_KEY: {
  672. status_t status = parseKeyProperty();
  673. if (status) return status;
  674. break;
  675. }
  676. }
  677. mTokenizer->skipDelimiters(WHITESPACE);
  678. if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
  679. ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
  680. mTokenizer->getLocation().string(),
  681. mTokenizer->peekRemainderOfLine().string());
  682. return BAD_VALUE;
  683. }
  684. }
  685. mTokenizer->nextLine();
  686. }
  687. if (mState != STATE_TOP) {
  688. ALOGE("%s: Unterminated key description at end of file.",
  689. mTokenizer->getLocation().string());
  690. return BAD_VALUE;
  691. }
  692. if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
  693. ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
  694. mTokenizer->getLocation().string());
  695. return BAD_VALUE;
  696. }
  697. if (mFormat == FORMAT_BASE) {
  698. if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
  699. ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
  700. mTokenizer->getLocation().string());
  701. return BAD_VALUE;
  702. }
  703. } else if (mFormat == FORMAT_OVERLAY) {
  704. if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
  705. ALOGE("%s: Overlay keyboard layout missing required keyboard "
  706. "'type OVERLAY' declaration.",
  707. mTokenizer->getLocation().string());
  708. return BAD_VALUE;
  709. }
  710. }
  711. return NO_ERROR;
  712. }
  713. status_t KeyCharacterMap::Parser::parseType() {
  714. if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
  715. ALOGE("%s: Duplicate keyboard 'type' declaration.",
  716. mTokenizer->getLocation().string());
  717. return BAD_VALUE;
  718. }
  719. KeyboardType type;
  720. String8 typeToken = mTokenizer->nextToken(WHITESPACE);
  721. if (typeToken == "NUMERIC") {
  722. type = KEYBOARD_TYPE_NUMERIC;
  723. } else if (typeToken == "PREDICTIVE") {
  724. type = KEYBOARD_TYPE_PREDICTIVE;
  725. } else if (typeToken == "ALPHA") {
  726. type = KEYBOARD_TYPE_ALPHA;
  727. } else if (typeToken == "FULL") {
  728. type = KEYBOARD_TYPE_FULL;
  729. } else if (typeToken == "SPECIAL_FUNCTION") {
  730. type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
  731. } else if (typeToken == "OVERLAY") {
  732. type = KEYBOARD_TYPE_OVERLAY;
  733. } else {
  734. ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
  735. typeToken.string());
  736. return BAD_VALUE;
  737. }
  738. #if DEBUG_PARSER
  739. ALOGD("Parsed type: type=%d.", type);
  740. #endif
  741. mMap->mType = type;
  742. return NO_ERROR;
  743. }
  744. status_t KeyCharacterMap::Parser::parseMap() {
  745. String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
  746. if (keywordToken == "key") {
  747. mTokenizer->skipDelimiters(WHITESPACE);
  748. return parseMapKey();
  749. }
  750. ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
  751. keywordToken.string());
  752. return BAD_VALUE;
  753. }
  754. status_t KeyCharacterMap::Parser::parseMapKey() {
  755. String8 codeToken = mTokenizer->nextToken(WHITESPACE);
  756. bool mapUsage = false;
  757. if (codeToken == "usage") {
  758. mapUsage = true;
  759. mTokenizer->skipDelimiters(WHITESPACE);
  760. codeToken = mTokenizer->nextToken(WHITESPACE);
  761. }
  762. char* end;
  763. int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
  764. if (*end) {
  765. ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
  766. mapUsage ? "usage" : "scan code", codeToken.string());
  767. return BAD_VALUE;
  768. }
  769. KeyedVector<int32_t, int32_t>& map =
  770. mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
  771. if (map.indexOfKey(code) >= 0) {
  772. ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
  773. mapUsage ? "usage" : "scan code", codeToken.string());
  774. return BAD_VALUE;
  775. }
  776. mTokenizer->skipDelimiters(WHITESPACE);
  777. String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
  778. int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
  779. if (!keyCode) {
  780. ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
  781. keyCodeToken.string());
  782. return BAD_VALUE;
  783. }
  784. #if DEBUG_PARSER
  785. ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
  786. mapUsage ? "usage" : "scan code", code, keyCode);
  787. #endif
  788. map.add(code, keyCode);
  789. return NO_ERROR;
  790. }
  791. status_t KeyCharacterMap::Parser::parseKey() {
  792. String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
  793. int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
  794. if (!keyCode) {
  795. ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
  796. keyCodeToken.string());
  797. return BAD_VALUE;
  798. }
  799. if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
  800. ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
  801. keyCodeToken.string());
  802. return BAD_VALUE;
  803. }
  804. mTokenizer->skipDelimiters(WHITESPACE);
  805. String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
  806. if (openBraceToken != "{") {
  807. ALOGE("%s: Expected '{' after key code label, got '%s'.",
  808. mTokenizer->getLocation().string(), openBraceToken.string());
  809. return BAD_VALUE;
  810. }
  811. #if DEBUG_PARSER
  812. ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
  813. #endif
  814. mKeyCode = keyCode;
  815. mMap->mKeys.add(keyCode, new Key());
  816. mState = STATE_KEY;
  817. return NO_ERROR;
  818. }
  819. status_t KeyCharacterMap::Parser::parseKeyProperty() {
  820. Key* key = mMap->mKeys.valueFor(mKeyCode);
  821. String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
  822. if (token == "}") {
  823. mState = STATE_TOP;
  824. return finishKey(key);
  825. }
  826. Vector<Property> properties;
  827. // Parse all comma-delimited property names up to the first colon.
  828. for (;;) {
  829. if (token == "label") {
  830. properties.add(Property(PROPERTY_LABEL));
  831. } else if (token == "number") {
  832. properties.add(Property(PROPERTY_NUMBER));
  833. } else {
  834. int32_t metaState;
  835. status_t status = parseModifier(token, &metaState);
  836. if (status) {
  837. ALOGE("%s: Expected a property name or modifier, got '%s'.",
  838. mTokenizer->getLocation().string(), token.string());
  839. return status;
  840. }
  841. properties.add(Property(PROPERTY_META, metaState));
  842. }
  843. mTokenizer->skipDelimiters(WHITESPACE);
  844. if (!mTokenizer->isEol()) {
  845. char ch = mTokenizer->nextChar();
  846. if (ch == ':') {
  847. break;
  848. } else if (ch == ',') {
  849. mTokenizer->skipDelimiters(WHITESPACE);
  850. token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
  851. continue;
  852. }
  853. }
  854. ALOGE("%s: Expected ',' or ':' after property name.",
  855. mTokenizer->getLocation().string());
  856. return BAD_VALUE;
  857. }
  858. // Parse behavior after the colon.
  859. mTokenizer->skipDelimiters(WHITESPACE);
  860. Behavior behavior;
  861. bool haveCharacter = false;
  862. bool haveFallback = false;
  863. bool haveReplacement = false;
  864. do {
  865. char ch = mTokenizer->peekChar();
  866. if (ch == '\'') {
  867. char16_t character;
  868. status_t status = parseCharacterLiteral(&character);
  869. if (status || !character) {
  870. ALOGE("%s: Invalid character literal for key.",
  871. mTokenizer->getLocation().string());
  872. return BAD_VALUE;
  873. }
  874. if (haveCharacter) {
  875. ALOGE("%s: Cannot combine multiple character literals or 'none'.",
  876. mTokenizer->getLocation().string());
  877. return BAD_VALUE;
  878. }
  879. if (haveReplacement) {
  880. ALOGE("%s: Cannot combine character literal with replace action.",
  881. mTokenizer->getLocation().string());
  882. return BAD_VALUE;
  883. }
  884. behavior.character = character;
  885. haveCharacter = true;
  886. } else {
  887. token = mTokenizer->nextToken(WHITESPACE);
  888. if (token == "none") {
  889. if (haveCharacter) {
  890. ALOGE("%s: Cannot combine multiple character literals or 'none'.",
  891. mTokenizer->getLocation().string());
  892. return BAD_VALUE;
  893. }
  894. if (haveReplacement) {
  895. ALOGE("%s: Cannot combine 'none' with replace action.",
  896. mTokenizer->getLocation().string());
  897. return BAD_VALUE;
  898. }
  899. haveCharacter = true;
  900. } else if (token == "fallback") {
  901. mTokenizer->skipDelimiters(WHITESPACE);
  902. token = mTokenizer->nextToken(WHITESPACE);
  903. int32_t keyCode = getKeyCodeByLabel(token.string());
  904. if (!keyCode) {
  905. ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
  906. mTokenizer->getLocation().string(),
  907. token.string());
  908. return BAD_VALUE;
  909. }
  910. if (haveFallback || haveReplacement) {
  911. ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
  912. mTokenizer->getLocation().string());
  913. return BAD_VALUE;
  914. }
  915. behavior.fallbackKeyCode = keyCode;
  916. haveFallback = true;
  917. } else if (token == "replace") {
  918. mTokenizer->skipDelimiters(WHITESPACE);
  919. token = mTokenizer->nextToken(WHITESPACE);
  920. int32_t keyCode = getKeyCodeByLabel(token.string());
  921. if (!keyCode) {
  922. ALOGE("%s: Invalid key code label for replace, got '%s'.",
  923. mTokenizer->getLocation().string(),
  924. token.string());
  925. return BAD_VALUE;
  926. }
  927. if (haveCharacter) {
  928. ALOGE("%s: Cannot combine character literal with replace action.",
  929. mTokenizer->getLocation().string());
  930. return BAD_VALUE;
  931. }
  932. if (haveFallback || haveReplacement) {
  933. ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
  934. mTokenizer->getLocation().string());
  935. return BAD_VALUE;
  936. }
  937. behavior.replacementKeyCode = keyCode;
  938. haveReplacement = true;
  939. } else {
  940. ALOGE("%s: Expected a key behavior after ':'.",
  941. mTokenizer->getLocation().string());
  942. return BAD_VALUE;
  943. }
  944. }
  945. mTokenizer->skipDelimiters(WHITESPACE);
  946. } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
  947. // Add the behavior.
  948. for (size_t i = 0; i < properties.size(); i++) {
  949. const Property& property = properties.itemAt(i);
  950. switch (property.property) {
  951. case PROPERTY_LABEL:
  952. if (key->label) {
  953. ALOGE("%s: Duplicate label for key.",
  954. mTokenizer->getLocation().string());
  955. return BAD_VALUE;
  956. }
  957. key->label = behavior.character;
  958. #if DEBUG_PARSER
  959. ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
  960. #endif
  961. break;
  962. case PROPERTY_NUMBER:
  963. if (key->number) {
  964. ALOGE("%s: Duplicate number for key.",
  965. mTokenizer->getLocation().string());
  966. return BAD_VALUE;
  967. }
  968. key->number = behavior.character;
  969. #if DEBUG_PARSER
  970. ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
  971. #endif
  972. break;
  973. case PROPERTY_META: {
  974. for (Behavior* b = key->firstBehavior; b; b = b->next) {
  975. if (b->metaState == property.metaState) {
  976. ALOGE("%s: Duplicate key behavior for modifier.",
  977. mTokenizer->getLocation().string());
  978. return BAD_VALUE;
  979. }
  980. }
  981. Behavior* newBehavior = new Behavior(behavior);
  982. newBehavior->metaState = property.metaState;
  983. newBehavior->next = key->firstBehavior;
  984. key->firstBehavior = newBehavior;
  985. #if DEBUG_PARSER
  986. ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
  987. mKeyCode,
  988. newBehavior->metaState, newBehavior->character,
  989. newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode);
  990. #endif
  991. break;
  992. }
  993. }
  994. }
  995. return NO_ERROR;
  996. }
  997. status_t KeyCharacterMap::Parser::finishKey(Key* key) {
  998. // Fill in default number property.
  999. if (!key->number) {
  1000. char16_t digit = 0;
  1001. char16_t symbol = 0;
  1002. for (Behavior* b = key->firstBehavior; b; b = b->next) {
  1003. char16_t ch = b->character;
  1004. if (ch) {
  1005. if (ch >= '0' && ch <= '9') {
  1006. digit = ch;
  1007. } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
  1008. || ch == '-' || ch == '+' || ch == ',' || ch == '.'
  1009. || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
  1010. symbol = ch;
  1011. }
  1012. }
  1013. }
  1014. key->number = digit ? digit : symbol;
  1015. }
  1016. return NO_ERROR;
  1017. }
  1018. status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
  1019. if (token == "base") {
  1020. *outMetaState = 0;
  1021. return NO_ERROR;
  1022. }
  1023. int32_t combinedMeta = 0;
  1024. const char* str = token.string();
  1025. const char* start = str;
  1026. for (const char* cur = str; ; cur++) {
  1027. char ch = *cur;
  1028. if (ch == '+' || ch == '\0') {
  1029. size_t len = cur - start;
  1030. int32_t metaState = 0;
  1031. for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
  1032. if (strlen(modifiers[i].label) == len
  1033. && strncmp(modifiers[i].label, start, len) == 0) {
  1034. metaState = modifiers[i].metaState;
  1035. break;
  1036. }
  1037. }
  1038. if (!metaState) {
  1039. return BAD_VALUE;
  1040. }
  1041. if (combinedMeta & metaState) {
  1042. ALOGE("%s: Duplicate modifier combination '%s'.",
  1043. mTokenizer->getLocation().string(), token.string());
  1044. return BAD_VALUE;
  1045. }
  1046. combinedMeta |= metaState;
  1047. start = cur + 1;
  1048. if (ch == '\0') {
  1049. break;
  1050. }
  1051. }
  1052. }
  1053. *outMetaState = combinedMeta;
  1054. return NO_ERROR;
  1055. }
  1056. status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
  1057. char ch = mTokenizer->nextChar();
  1058. if (ch != '\'') {
  1059. goto Error;
  1060. }
  1061. ch = mTokenizer->nextChar();
  1062. if (ch == '\\') {
  1063. // Escape sequence.
  1064. ch = mTokenizer->nextChar();
  1065. if (ch == 'n') {
  1066. *outCharacter = '\n';
  1067. } else if (ch == 't') {
  1068. *outCharacter = '\t';
  1069. } else if (ch == '\\') {
  1070. *outCharacter = '\\';
  1071. } else if (ch == '\'') {
  1072. *outCharacter = '\'';
  1073. } else if (ch == '"') {
  1074. *outCharacter = '"';
  1075. } else if (ch == 'u') {
  1076. *outCharacter = 0;
  1077. for (int i = 0; i < 4; i++) {
  1078. ch = mTokenizer->nextChar();
  1079. int digit;
  1080. if (ch >= '0' && ch <= '9') {
  1081. digit = ch - '0';
  1082. } else if (ch >= 'A' && ch <= 'F') {
  1083. digit = ch - 'A' + 10;
  1084. } else if (ch >= 'a' && ch <= 'f') {
  1085. digit = ch - 'a' + 10;
  1086. } else {
  1087. goto Error;
  1088. }
  1089. *outCharacter = (*outCharacter << 4) | digit;
  1090. }
  1091. } else {
  1092. goto Error;
  1093. }
  1094. } else if (ch >= 32 && ch <= 126 && ch != '\'') {
  1095. // ASCII literal character.
  1096. *outCharacter = ch;
  1097. } else {
  1098. goto Error;
  1099. }
  1100. ch = mTokenizer->nextChar();
  1101. if (ch != '\'') {
  1102. goto Error;
  1103. }
  1104. // Ensure that we consumed the entire token.
  1105. if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
  1106. return NO_ERROR;
  1107. }
  1108. Error:
  1109. ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
  1110. return BAD_VALUE;
  1111. }
  1112. } // namespace android