MultiTouchInputMapper

  • 格式:doc
  • 大小:486.50 KB
  • 文档页数:10

1.MultiTouchInputMapper1.1数据传递框架简单点讲,驱动层上报的数据在InputReadThread线程读取及处理,并加入到Dispatcher的队列中,最终由InputDispatcherThread传递处理给对应的Activity。

1.2驱动数据上报非电容式的多点触摸屏,基本很少见,即使有对于中间层的处理也不会变化,都是用触摸IC来上报触摸数据,换句话说,要触摸IC支持多点上报机制,才可以支持多点触摸。

注:Android在上层有保留每一个按键的状态(位置,按下等),在驱动层只需要上报数据,由Android上层来出。

首先,看下触摸屏驱动是怎么上报数据的。

一个完整的多点触摸数据是按照以下顺序来上报点的数据ABS_MT_TOUCH_MAJOR 触摸压力ABS_MT_POSITION_X 触摸X坐标(并不一定是触摸屏上的X坐标)ABS_MT_POSITION_Y 触摸Y坐标(并不一定是触摸屏上的Y坐标)ABS_MT_WIDTH_MAJOR 触摸接触面积,一般为1EV_SYN(SYN_MT_REPORT) 单点的触摸结束标记每一点的数据以一个的SYN_MT_REPORT标记为结束。

当所有点都结束时,上报一个EV_SYN(SYN_REPORT)事件表示一个触摸点数据上报结束。

input_sync 与input_mt_sync的区别在于上报的code不一样1.3A ndroid 数据处理Android对于各种各样的数据都在InputMapper的派生类处理,例如对点触摸数据在MultiTouchInputMapper中进行处理。

1.3.1MultiTouchInputMapper 实现class MultiTouchInputMapper : public TouchInputMapper {public:MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);virtual ~MultiTouchInputMapper();virtual void reset(); // 清空所有点的数据virtual void process(const RawEvent* rawEvent); // 转换裸数据protected:virtual void configureRawAxes(); //获取驱动城对各种标记位的设置private:struct Accumulator { //存放多点触摸的数据enum {FIELD_ABS_MT_POSITION_X = 1,FIELD_ABS_MT_POSITION_Y = 2,FIELD_ABS_MT_TOUCH_MAJOR = 4,FIELD_ABS_MT_TOUCH_MINOR = 8,FIELD_ABS_MT_WIDTH_MAJOR = 16,FIELD_ABS_MT_WIDTH_MINOR = 32,FIELD_ABS_MT_ORIENTATION = 64,FIELD_ABS_MT_TRACKING_ID = 128,FIELD_ABS_MT_PRESSURE = 256,};uint32_t pointerCount;struct Pointer {uint32_t fields;int32_t absMTPositionX;int32_t absMTPositionY;int32_t absMTTouchMajor;int32_t absMTTouchMinor;int32_t absMTWidthMajor;int32_t absMTWidthMinor;int32_t absMTOrientation;int32_t absMTTrackingId;int32_t absMTPressure;inline void clear() {fields = 0;}} pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checksinline void clear() {pointerCount = 0;pointers[0].clear();}} mAccumulator;void initialize();void sync(nsecs_t when); //上报驱动数据};1.3.2process所有的触摸数据储存在MultiTouchInputMapper中的mAccumulator变量中。

其中mAccumulator.pointers表示触摸点的数据mAccumulator.pointerCount 表示当前第几个触摸点在process函数流程中很简单处理两个不同的事件EV_ABS,EV_SYN。

当事件为EV_ABS时,存储当前的事件相关值至mAccumulator.pointers中当事件为EV_SYN,CODE为SYN_MT_REPORT是,累加当前的点数统计值mAccumulator.pointerCount。

当时间为EV_SYN,CODE为SYN_REPORT时,上报当前的所有数据。

1.3.3Sync在Sync函数里对原来存储在mAccumulator里的数据做了处理,转存到了mCurrentTouch,最终调用syncTouch上报数据。

1.3.4TouchInputMapper::syncTouchsyncTouch做了三件事:●准备数据(过滤一下点数据,漂移的吗?)●consumeOffScreenTouches根据当前屏幕的信息(长宽,旋转)重新计算当前点的信息及事件,dispatchTouches上报触摸事件给Activity。

●最后更新上次Touch的信息。

1.3.5TouchInputMapper::consumeOffScreenTouches在TouchInputMapper::configureSurfaceLocked完成了各种输入数据的范围及一些特定的设置,例如在触摸屏中通过获取驱动层的屏幕信息,及输入的坐标信息,用来计算驱动上报点的数据与屏幕上点的对应关系(缩放比例)1.3.6TouchInputMapper::dispatchTouches根据上次触摸点的位置信息来区分各种不同的事件,常用事件有以下几种:多点的数据上报事件。

基本的代码框架:1.4L inux驱动层接口分析多点触摸屏驱动与Android Framework之间的数据的传递需要注意两点,第一,输入设备属性的设置;第二,多点触摸数据的上报。

1.4.1输入设备属性设置# 设置输入设备absbit事件中,所支持的上报事件属性。

set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);set_bit(ABS_MT_POSITION_X, input_dev->absbit);set_bit(ABS_MT_POSITION_Y, input_dev->absbit);set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);# 设置各种事件的最大值,其中ABS_MT_POSITION_X, ABS_MT_POSITION_Y设置的值在Android里备用来计算与屏幕之间的缩放关系。

input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);1.4.2多点触摸数据的上报按照参考示例的流程上报即可,在每个多点数据之间的上报,都要插入一个input_mt_sync(data->input_dev);在最终完成所有点数据的上报则插入input_sync(data->input_dev),以区分两个连续的输入事件。

switch(event->touch_point) {case 5:input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,event->pressure);input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->y5);input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->x5);input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);input_mt_sync(data->input_dev);case 4:input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->y4);input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->x4);input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);input_mt_sync(data->input_dev);case 3:input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->y3);input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->x3);input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);input_mt_sync(data->input_dev);case 2:input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->y2);input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->x2);input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);case 1:input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->y1);input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->x1);input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);input_mt_sync(data->input_dev);default:break;}input_sync(data->input_dev);2.FT5X06相关代码驱动源码位置:drivers\input\touchscreen\ft5x06_ts.c。