通过前面的章节,我们已经已经知道怎么编写触摸屏的驱动程序,但是编写之后我们并不能直接使用,在最初移植的时候,编写完程序之后,在安卓的应用层,把上报的数据当做鼠标来处理了,特别的不方便。所以我们需要为我们的触摸屏驱动增加配置文件。
通过前面的小节我们可以知道,android中的输入系统会监测/dev/input目录,当有输入设备接入时,该目录下会生成设备节点,然后输入系统_Reader线程会根据设备节点的name找到对应的配置文件,分别为*idc,*kcm,*kl文件,该些内容在前面都有讲解过。其查找顺序如下: 在我们的android系统中,使用的是第三个,即system/usr/idc/。我们首先在源码编写SDK/device/rockchip/rk3399/qytech_azalea/gslx680.idc文件,内容如下:
touch.deviceType = touchScreen
touch.orientationAware = 1
告诉android系统,该为一个触摸屏设备。除此之外我们还要修改evice/rockchip/rk3399/qytech_azalea.mk文件,做以下修改(增加+好所表示的代码):
PRODUCT_COPY_FILES += \
device/rockchip/rk3399/rk3399_all/ddr_config.xml:system/etc/ddr_config.xml \
device/rockchip/rk3399/rk3399_all/video_status:system/etc/video_status \
+ device/rockchip/rk3399/qytech_azalea/gslx680.idc:system/usr/idc/gslx680.idc \
device/rockchip/common/resolution_white.xml:/system/usr/share/resolution_white.xml
然后重新编译烧写即可。
那么为什么非要添加这个配置文件呢?有没有办法不添加这个配置文件? touch.deviceType可以设置为多种类型: touch.deviceType = touchScreen | touchPad | pointer | default
touchScreen : 触摸屏, 覆盖在显示器上, 可以直接操作各种图标
touchPad : 触摸板, 不是覆盖在显示器上, 需要在LCD上显示一个光标以便定位
pointer : 跟touchPad类似, 多一些手势功能("Indirect Multi-touch Pointer Gestures")
default : 由系统自己确定
我们根据touch.deviceType 这个线索,在源码中查看一下,看看看他在什么地方被引用,在InputReader.cpp文件中,可以看到如下:
/*从品质文件之中尝试一下,看是否能够获得touch.deviceType这个属性*/
if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
deviceTypeString)) {
/*如果获取的属性为"touchScreen"*/
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
} else if (deviceTypeString == "touchPad") { /*如果获取的属性为"touchPad"*/
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
} else if (deviceTypeString == "touchNavigation") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
} else if (deviceTypeString == "pointer") {
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
} else if (deviceTypeString != "default") {
ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
}
}
我们可以看到,从配置文件获得"touch.deviceType"属性之后,其会赋值给mParameters.deviceType,那么除了在该处mParameters.deviceType被赋值为Parameters::DEVICE_TYPE_TOUCH_SCREEN,其他的地方有赋值吗?我们在源码中搜索DEVICE_TYPE_TOUCH_SCREEN,可以在该文件中找到:
if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
// The device is a touch screen.
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
他会查看输入设备有没有一些属性,如果这个属性为INPUT_PROP_DIRECT,他就会执行:
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
在EventHub.cpp中,我们可以找到hasInputProperty()函数的定义:
bool EventHub::hasInputProperty(int32_t deviceId, int property) const {
if (property >= 0 && property propBitmask);
}
}
return false;
}
可以看到,他是device->propBitmask中,看下有没有property属性,我们搜索propBitmask:
ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask);
可以看到通过ioctl,传递给内核一个EVIOCGPROP的指令,我们在内核源码中搜索EVIOCGPROP,他内核接收到怎么指令之后,会做出什么处理。在内核evdev.c文件中,我们可以看到:
case EVIOCGPROP(0):
return bits_to_user(dev->propbit, INPUT_PROP_MAX,size, p, compat_mode);
我们需要设置dev->propbit,其可选择设置如下:
#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
#define INPUT_PROP_DIRECT 0x01 /* direct input devices 直接操作图标*/
#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
#define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
我们需去设置INPUT_PROP_DIRECT,在内核中搜索INPUT_PROP_DIRECT,可以找到很多文件对他的应用,看内核中是如何使用,其实在我们的触摸屏源码也存在:
// __set_bit(INPUT_PROP_DIRECT, input_device->propbit);
只是被注释掉了,只需要取消注释,重新编译源码,即使没有那个配置文件,我们也能正常的操作屏幕了。
现在我们回过头看看,andriod系统中是如何使用INPUT_PROP_DIRECT,在andriod源码的EventHub.cpp文件中,回到:
ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask);
当有输入设备接入时,android系统的Reader线程,会调用一系列的ioctrl,获取设备相关的信息,如果存在EVIOCGPROP属性,他被读取到device->propBitmask中,在InputReader.cpp文件中:
if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
// The device is a touch screen.
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
就会设置mParameters.deviceType,如果没有找个这个配置文件,会设置默认值:
} else {
// The device is a touch pad of unknown purpose.
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
}
可以理解为我们使用的鼠标。这样该小节就讲解完成了