From 1fbaae8d8e39ecfb9c7bb335c5476e13b3553a57 Mon Sep 17 00:00:00 2001 From: Simo Kinnunen Date: Wed, 12 Feb 2014 00:09:18 +0900 Subject: [PATCH] Add utility for turning keymaps into characters mappings. --- lib/util/keyutil.js | 117 ++++++++++++++++++++++++++++++++++++- test/fixt/Virtual.kcm.json | 20 +++---- 2 files changed, 126 insertions(+), 11 deletions(-) diff --git a/lib/util/keyutil.js b/lib/util/keyutil.js index 5c30d9cf..b90efcdb 100644 --- a/lib/util/keyutil.js +++ b/lib/util/keyutil.js @@ -3,7 +3,9 @@ var util = require('util') var adb = require('adbkit') var Promise = require('bluebird') -module.exports.parseKeyCharacterMap = function(stream) { +var keyutil = module.exports = Object.create(null) + +keyutil.parseKeyCharacterMap = function(stream) { var resolver = Promise.defer() , state = 'type_t' , keymap = { @@ -413,6 +415,7 @@ module.exports.parseKeyCharacterMap = function(stream) { if ((char >= '0' && char <= '9') || (char >= 'a' && char <= 'f')) { lastBehavior.value += parseInt(char, 16) + lastBehavior.value = String.fromCharCode(lastBehavior.value) state = 'filter_behavior_literal_end' return true } @@ -455,3 +458,115 @@ module.exports.parseKeyCharacterMap = function(stream) { stream.removeListener('end', endListener) }) } + +keyutil.namedKey = function(name) { + var key = adb.Keycode['KEYCODE_' + name] + if (key === void 0) { + throw new Error(util.format('Unknown key "%s"', name)) + } + return key +} + +keyutil.buildCharMap = function(keymap) { + var charmap = Object.create(null) + + keymap.keys.forEach(function(key) { + key.rules.forEach(function(rule) { + var combination = { + key: keyutil.namedKey(key.key) + , modifiers: [] + , complexity: 0 + } + + var shouldHandle = rule.modifiers.every(function(modifier) { + switch (modifier.type) { + case 'label': + return false // ignore + case 'base': + return true + case 'shift': + case 'lshift': + combination.modifiers.push(adb.Keycode.KEYCODE_SHIFT_LEFT) + combination.complexity += 10 + return true + case 'rshift': + combination.modifiers.push(adb.Keycode.KEYCODE_SHIFT_RIGHT) + combination.complexity += 10 + return true + case 'alt': + case 'lalt': + combination.modifiers.push(adb.Keycode.KEYCODE_ALT_LEFT) + combination.complexity += 20 + return true + case 'ralt': + combination.modifiers.push(adb.Keycode.KEYCODE_ALT_RIGHT) + combination.complexity += 20 + return true + case 'ctrl': + case 'lctrl': + combination.modifiers.push(adb.Keycode.KEYCODE_CTRL_LEFT) + combination.complexity += 20 + return true + case 'rctrl': + combination.modifiers.push(adb.Keycode.KEYCODE_CTRL_RIGHT) + combination.complexity += 20 + return true + case 'meta': + case 'lmeta': + combination.modifiers.push(adb.Keycode.KEYCODE_META_LEFT) + combination.complexity += 20 + return true + case 'rmeta': + combination.modifiers.push(adb.Keycode.KEYCODE_META_RIGHT) + combination.complexity += 20 + return true + case 'sym': + combination.modifiers.push(adb.Keycode.KEYCODE_SYM) + combination.complexity += 10 + return true + case 'fn': + combination.modifiers.push(adb.Keycode.KEYCODE_FUNCTION) + combination.complexity += 30 + return true + case 'capslock': + combination.modifiers.push(adb.Keycode.KEYCODE_CAPS_LOCK) + combination.complexity += 30 + return true + case 'numlock': + combination.modifiers.push(adb.Keycode.KEYCODE_NUM_LOCK) + combination.complexity += 30 + return true + case 'scrolllock': + combination.modifiers.push(adb.Keycode.KEYCODE_SCROLL_LOCK) + combination.complexity += 30 + return true + } + }) + + if (!shouldHandle) { + return + } + + rule.behaviors.forEach(function(behavior) { + switch (behavior.type) { + case 'literal': + if (!charmap[behavior.value]) { + charmap[behavior.value] = [combination] + } + else { + charmap[behavior.value].push(combination) + + // Could be more efficient, but we only have 1-4 combinations + // per key, so we don't really care. + charmap[behavior.value].sort(function(a, b) { + return a.complexity - b.complexity + }) + } + break + } + }) + }) + }) + + return charmap +} diff --git a/test/fixt/Virtual.kcm.json b/test/fixt/Virtual.kcm.json index aaec4819..600556ac 100644 --- a/test/fixt/Virtual.kcm.json +++ b/test/fixt/Virtual.kcm.json @@ -179,7 +179,7 @@ "behaviors": [ { "type": "literal", - "value": 231 + "value": "ç" } ] }, @@ -195,7 +195,7 @@ "behaviors": [ { "type": "literal", - "value": 199 + "value": "Ç" } ] } @@ -322,7 +322,7 @@ "behaviors": [ { "type": "literal", - "value": 769 + "value": "́" } ] } @@ -563,7 +563,7 @@ "behaviors": [ { "type": "literal", - "value": 770 + "value": "̂" } ] } @@ -861,7 +861,7 @@ "behaviors": [ { "type": "literal", - "value": 771 + "value": "̃" } ] } @@ -1159,7 +1159,7 @@ "behaviors": [ { "type": "literal", - "value": 223 + "value": "ß" } ] } @@ -1286,7 +1286,7 @@ "behaviors": [ { "type": "literal", - "value": 776 + "value": "̈" } ] } @@ -1895,7 +1895,7 @@ "behaviors": [ { "type": "literal", - "value": 770 + "value": "̂" } ] } @@ -2348,7 +2348,7 @@ "behaviors": [ { "type": "literal", - "value": 768 + "value": "̀" } ] }, @@ -2364,7 +2364,7 @@ "behaviors": [ { "type": "literal", - "value": 771 + "value": "̃" } ] }