




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android多点触摸的实现1.6patch(一)第一章摘要在Linux内核支持的基础上,Android在其2.0源码中加入多点触摸功能。由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。第二章软件位在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:.#define SYN_REPORT 0#define SYN_CONFIG 1#define SYN_MT_REPORT 2.#define ABS_MT_TOUCH_MAJOR0x30/* Major axis of touching ellipse */#define ABS_MT_TOUCH_MINOR0x31/* Minor axis (omit if circular) */#define ABS_MT_WIDTH_MAJOR0x32/* Major axis of approaching ellipse */#define ABS_MT_WIDTH_MINOR0x33/* Minor axis (omit if circular) */#define ABS_MT_ORIENTATION0x34/* Ellipse orientation */#define ABS_MT_POSITION_X0x35/* Center X ellipse position */#define ABS_MT_POSITION_Y0x36/* Center Y ellipse position */#define ABS_MT_TOOL_TYPE0x37/* Type of touching device */#define ABS_MT_BLOB_ID 0x38/* Group a set of packets as a blob */在Android中对应的软件位定义在RawInputEvent.java中:.public class RawInputEvent . public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;. public static final int ABS_MT_TOUCH_MAJOR = 0x30; public static final int ABS_MT_TOUCH_MINOR = 0x31; public static final int ABS_MT_WIDTH_MAJOR = 0x32; public static final int ABS_MT_WIDTH_MINOR = 0x33; public static final int ABS_MT_ORIENTATION = 0x34; public static final int ABS_MT_POSITION_X = 0x35; public static final int ABS_MT_POSITION_Y = 0x36; public static final int ABS_MT_TOOL_TYPE = 0x37; public static final int ABS_MT_BLOB_ID = 0x38;.public static final int SYN_REPORT = 0; public static final int SYN_CONFIG = 1;public static final int SYN_MT_REPORT = 2;.在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。在Android代码的EventHub.cpp中,单点屏和多点屏由如下代码段来判定:int EventHub:open_device(const char *deviceName)if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)& test_bit(ABS_MT_POSITION_X, abs_bitmask)& test_bit(ABS_MT_POSITION_Y, abs_bitmask) device-classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;/ LOGI(It is a multi-touch screen!); /single-touch?else if (test_bit(BTN_TOUCH, key_bitmask)& test_bit(ABS_X, abs_bitmask) & test_bit(ABS_Y, abs_bitmask) device-classes |= CLASS_TOUCHSCREEN;/ LOGI(It is a single-touch screen!);.我们知道,在触摸屏驱动中,通常在probe函数中会调用input_set_abs_params给设备的input_dev结构体初始化,这些input_dev的参数会在Android的EventHub.cpp中被读取。如上可知,如果我们的触摸屏想被当成多点屏被处理,只需要在驱动中给input_dev额外增加以下几个参数即可:input_set_abs_params(mcs_data.input, ABS_MT_POSITION_X, pdata-abs_x_min, pdata-abs_x_max, 0, 0);input_set_abs_params(mcs_data.input, ABS_MT_POSITION_Y, pdata-abs_y_min, pdata-abs_y_max, 0, 0);input_set_abs_params(mcs_data.input, ABS_MT_TOUCH_MAJOR, 0, 15, 0, 0); /相当于单点屏的ABX_PRESSUREinput_set_abs_params(mcs_data.input, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0); /相当于单点屏的ABS_TOOL_WIDTH注:为了让我们的驱动代码支持所有的Android版本,无论是多点屏还是单点屏,一般都会保留单点屏的事件,如ABS_TOUCH, ABS_PRESSURE, ABS_X, ABS_Y等。另外,由于在Android2.0前支持多点的frameworks大多是用HAT0X,HAT0Y来实现的,所以一般也会上报这2个事件。第三章同步方式由于多点触摸技术需要采集到多个点,然后再一起处理这些点,所以在软件实现中需要保证每一波点的准确性和完整性。因此,Linux内核提供了input_mt_sync(struct input_dev * input)函数。在每波的每个点上报后需要紧跟一句input_mt_sync(), 当这波所有点上报后再使用input_sync()进行同步。例如一波要上报3个点:/* 上报点1*/.input_mt_sync(input);/* 上报点2*/.input_mt_sync(input);/* 上报点3*/.input_mt_sync(input);input_sync(input);注:即使是仅上报一个点的单点事件,也需要一次input_my_sync。在Android的KeyInputQueue.java中,系统创建了一个线程,然后把所有的Input事件放入一个队列:public abstract class KeyInputQueue Thread mThread = new Thread(InputDeviceReader) public void run() android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY); try RawInputEvent ev = new RawInputEvent(); while (true) InputDevice di; / block, doesnt release the monitor readEvent(ev);if (ev.type = RawInputEvent.EV_DEVICE_ADDED) synchronized (mFirst) di = newInputDevice(ev.deviceId); mDevices.put(ev.deviceId, di); configChanged = true; else if (ev.type = RawInputEvent.EV_DEVICE_REMOVED) synchronized (mFirst) Log.i(TAG, Device removed: id=0x + Integer.toHexString(ev.deviceId); di = mDevices.get(ev.deviceId); if (di != null) mDevices.delete(ev.deviceId); configChanged = true; else Log.w(TAG, Bad device id: + ev.deviceId); else di = getInputDevice(ev.deviceId); / first crack at it send = preprocessEvent(di, ev); if (ev.type = RawInputEvent.EV_KEY) di.mMetaKeysState = makeMetaState(ev.keycode, ev.value != 0, di.mMetaKeysState); mHaveGlobalMetaState = false; if (di = null) continue; if (configChanged) synchronized (mFirst) addLocked(di, SystemClock.uptimeMillis(), 0, RawInputEvent.CLASS_CONFIGURATION_CHANGED, null); if (!send) continue; synchronized (mFirst) . if (type = RawInputEvent.EV_KEY & (classes&RawInputEvent.CLASS_KEYBOARD) != 0 & (scancode RawInputEvent.BTN_LAST) /* 键盘按键事件 */ . else if (ev.type = RawInputEvent.EV_KEY) /* 下面是EV_KEY事件分支,只支持单点的触摸屏有按键事件, * 而支持多点的触摸屏没有按键事件,只有绝对坐标事件*/ if (ev.scancode = RawInputEvent.BTN_TOUCH & (classes&(RawInputEvent.CLASS_TOUCHSCREEN |RawInputEvent.CLASS_TOUCHSCREEN_MT) = RawInputEvent.CLASS_TOUCHSCREEN) /* 只支持单点的触摸屏的按键事件 */ else if (ev.scancode = RawInputEvent.BTN_MOUSE & (classes&RawInputEvent.CLASS_TRACKBALL) != 0) /* 鼠标和轨迹球 */ . else if (ev.type = RawInputEvent.EV_ABS & (classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) /* 下面才是多点触摸屏上报的事件 */ if (ev.scancode = RawInputEvent.ABS_MT_TOUCH_MAJOR) di.mAbs.changed = true; di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_PRESSURE = ev.value; else if (ev.scancode = RawInputEvent.ABS_MT_POSITION_X) di.mAbs.changed = true; di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_X = ev.value; else if (ev.scancode = RawInputEvent.ABS_MT_POSITION_Y) di.mAbs.changed = true; di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_Y = ev.value; else if (ev.scancode = RawInputEvent.ABS_MT_WIDTH_MAJOR) di.mAbs.changed = true; di.mAbs.mNextDatadi.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_SIZE = ev.value; /* 上面这段就是多点触摸屏要用到的事件上报部分; * 使用一个数组mNextData来保存,其中di.mAbs.mAddingPointerOffset * 是当前点的偏移量,在每个点中还在MotionEvent中定义了X,Y,PRESSURE * SIZE等偏移量,多点触摸屏的压力值由绝对坐标事件ABS_MT_TOUCH_MAJOR确定。 */ else if (ev.type = RawInputEvent.EV_ABS & (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) /* 这里是对单点触摸屏上报坐标事件的新的处理方法,同样使用了数组来保存 */ if (ev.scancode = RawInputEvent.ABS_X) di.mAbs.changed = true; di.curTouchValsMotionEvent.SAMPLE_X = ev.value; else if (ev.scancode = RawInputEvent.ABS_Y) di.mAbs.changed = true; di.curTouchValsMotionEvent.SAMPLE_Y = ev.value; else if (ev.scancode = RawInputEvent.ABS_PRESSURE) di.mAbs.changed = true; di.curTouchValsMotionEvent.SAMPLE_PRESSURE = ev.value; di.curTouchValsMotionEvent.NUM_SAMPLE_DATA + MotionEvent.SAMPLE_PRESSURE = ev.value; else if (ev.scancode = RawInputEvent.ABS_TOOL_WIDTH) di.mAbs.changed = true; di.curTouchValsMotionEvent.SAMPLE_SIZE = ev.value; di.curTouchValsMotionEvent.NUM_SAMPLE_DATA + MotionEvent.SAMPLE_SIZE = ev.value; . /* 下面是关键的同步处理方法 */ if (ev.type = RawInputEvent.EV_SYN & ev.scancode = RawInputEvent.SYN_MT_REPORT & di.mAbs != null) /* 在这里实现了对SYN_MT_REPORT事件的处理, * 改变了di.mAbs.mAddingPointerOffset的值,从而将 * 新增的点的参数保存到下一组偏移量的位置。 */ . final int newOffset = (num lastNumPointers) if (lastNumPointers = 0) /上次触屏上没有按键,新值又大,说明有按键按下 action = MotionEvent.ACTION_DOWN; mDownTime = curTime; else /有新点按下,分配给新点ID号 action = MotionEvent.ACTION_POINTER_DOWN | (upOrDownPointer MotionEvent.ACTION_POINTER_ID_SHIFT); else /新动作比原来pointer数量少 if (numPointers = 1) /原来只有1个点按下,所以现在的动作是全部按键up action = MotionEvent.ACTION_UP; else /原来有多点按下,现在是ACTION_POINTER_UP动作, action = MotionEvent.ACTION_POINTER_UP | (upOrDownPointer MotionEvent.ACTION_POINTER_ID_SHIFT); currentMove = null; else /前后触屏pointer个数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 河南省南阳完全学校2024~2025学年 高三第三次调研测试数学试卷附解析
- 2025届江苏省扬州市仪征市中考二模数学试卷
- 2024年山东省烟草专卖局(公司)笔试试题
- 2024年惠州龙门县招聘乡镇党建指导员真题
- 2024河南公务员考试行测真题(省直)
- 鞍山市立山区事业单位招聘笔试真题2024
- 石大学前儿童保育学课外必读:幼儿园游戏安全防护
- 2025年人工智能培训师试题
- 初一学生数学元认知策略水平的现状及其培养研究
- 自动化运输与货物标签识别技术-洞察阐释
- 2025年江西报业传媒集团招聘题库带答案分析
- 公司退货流程管理制度
- 矿产品销售合作合同范本
- 江苏省常州市联盟学校2022-2023学年高一下学期期末联考数学试题(学生版)
- 零售药店采购员岗位培训考核试题(带答案)
- 2025年成都市中考历史试题卷(含答案)
- 中国盐业集团有限公司所属企业招聘笔试题库2025
- DB23-T2326-2019-紫椴种质资源调查及评价技术规程-黑龙江省
- (人教2024版)英语七下期末全册分单元总复习课件(新教材)
- 2025年中考生物考前必背全册知识点梳理(全国)七年级上册
- 2025年二年级语文期末复习计划
评论
0/150
提交评论