在TP的driver中,报虚拟按键的方法常见的有两种:
1.直接报键值(kernel的)
2.报一个坐标,上层通过KL的解析来判定是哪个键。
下面说下第二种:
TP的kl被存放在/sys/board_properties/virtualkeys.devicename中,pull出来后可以看看内容:
0x01:139:100:900:40:60:0x01:158:400:900:40:60
可以发现就是在驱动代码中写的范围,分别是中心点X,中心点Y,宽度和高度,其实就是一个矩形区域,以X,Y为中心点,分别延伸 w/2, h/2。
4.0上对此kl的解析是在virtualkeymap.cpp中:
do {
String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
if (token != "0x01") {
LOGE("%s: Unknown virtual key type, expected 0x01.",
mTokenizer->getLocation().string());
return BAD_VALUE;
}
VirtualKeyDefinition defn;
bool success = parseNextIntField(&defn.scanCode)
&& parseNextIntField(&defn.centerX)
&& parseNextIntField(&defn.centerY)
&& parseNextIntField(&defn.width)
&& parseNextIntField(&defn.height);
if (!success) {
LOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
mTokenizer->getLocation().string());
return BAD_VALUE;
}
0X01是标志位,接下来的一位是scancode,再接下来就是xywh。
需要注意的是实际的范围是[x-w/2,x+w/2] ,[y-h/2,y+h/2].
2.3.5上是在inputmanager.java中getVirtualKeyDefinitions方法中解析的:
try {
FileInputStream fis = new FileInputStream(
"/sys/board_properties/virtualkeys." + deviceName);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr, 2048);
String str = br.readLine();
if (str != null) {
String[] it = str.split(":");
if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "***** VIRTUAL KEYS: " + it);
final int N = it.length-6;
for (int i=0; i<=N; i+=6) {
if (!"0x01".equals(it[i])) {
Slog.w(TAG, "Unknown virtual key type at elem #" + i + ": " + it[i] + " for device " + deviceName);
continue;
}
try {
VirtualKeyDefinition key = new VirtualKeyDefinition();
key.scanCode = Integer.parseInt(it[i+1]);
key.centerX = Integer.parseInt(it[i+2]);
key.centerY = Integer.parseInt(it[i+3]);
key.width = Integer.parseInt(it[i+4]);
key.height = Integer.parseInt(it[i+5]);
if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
+ key.scanCode + ": center=" + key.centerX + "," + key.centerY + " size=" + key.width + "x"
+ key.height);
keys.add(key);
} catch (NumberFormatException e) {
Slog.w(TAG, "Bad number in virtual key definition at region "
+ i + " in: " + str + " for device " + deviceName, e);
}
}
}
br.close(); } catch (FileNotFoundException e) {
Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
} catch (IOException e) {
Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
}
return keys.toArray(new VirtualKeyDefinition[keys.size()]);
}
实际是在inputread中使用:
TouchInputMapper::configureVirtualKeysLocked()方法中会计算出每个虚拟按键对应的矩形范围,并将scancode转换成keycode。