android系统触摸屏虚拟按键.doc_第1页
android系统触摸屏虚拟按键.doc_第2页
android系统触摸屏虚拟按键.doc_第3页
android系统触摸屏虚拟按键.doc_第4页
android系统触摸屏虚拟按键.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

此文档收集于网络,如有侵权,请联系网站删除 虚拟按键(VirtualKey)是Eclair版本开始增加的新特性。VirtualKey的功能是利用触摸屏,模拟按键发生的事件,这样就可以利用触摸屏的边缘,实现一些可以自定义的按键效果。在Android系统中,触摸屏设备发送的是RawInputEvent(原始输入事件),而按键发送的是KeyEvent(按键事件)。KeyEvent直接发送给应用程序层,RawInputEvent在Android的Java框架中被转换成MotionEvent发送给应用程序层。在Android系统中虚拟按键的实现方法是:在某种情况下,将RawInputEvent转换成KeyEvent。frameworks/base/services/Java/com/android/server目录中的InputDevice.Java文件负责处理虚拟按键的主要文件。虚拟按键的处理相对简单,需要根据以下文件对虚拟按键的内容进行配置:/sys/board_properties/virtualkeys.devicename在InputDevice.Java文件中通过readVirtualKeys,对进行消息的转化。根据配置文件将RawInputEvent转换成按键相关的内容。virtualkeys.devicename是虚拟按键的适配文件,需要在目标文件系统的/sys/board_properties/目录中。虚拟按键配置文件的格式如下所示:0x1:扫描码:X:Y:W:H:0x1:例如,在MSM的mahimahi平台上查看虚拟按键的配置文件如下所示:#cat/sys/board_properties/virtualkeys.synaptics-rmi-touchscreen0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55由此可见,其中定义了4个区域的虚拟按键,它们的Y坐标相同,可见4个按键的矩形区域位于水平的一排。其转换的扫描码分别为158,139,102,217,分别对应于BACK(返回),MENU(菜单),HOME(主界面),SEARCH(搜索)这4个按键。另外一个系统的虚拟按键的配置文件如下所示:$cat/sys/board_properties/virtualkeys.qtouch-touchscreen0x01:139:90:936:116:104:0x01:102:252:936:116:104:0x01:158:402:936:116:104其转换的扫描码分别为:139,102,158,分别对应于MENU(菜单),HOME(主界面),BACK(返回)这3个按键。提示:使用虚拟按键转换成为的是按键的扫描码,不是按键码,因此依然需要经过按键布局文件的转化才能得到按键码。(二)如果按照韩超和梁泉的Android系统级深入开发移植与调试的第八章描述虚拟按键的实现过程如下:1.硬件分析我所使用的触摸屏分辨率是1158*768,可视区域大小是1024*768(这也是LCD屏的大小),在触摸屏两侧总有5个按键。2.触摸屏按键驱动的修改既然可视区域在触摸屏中间部位,因此需要在触摸屏驱动中修改input_set_abs_params()函数中的参数1. input_set_abs_params(input_dev,ABS_MT_POSITION_X,61,1085,0,0);2. input_set_abs_params(input_dev,ABS_MT_POSITION_Y,0,SCREEN_MAX_Y,0,0);其中61是可视区域左侧x轴左边坐标,1085是右侧的。3.Android框架层Android上层通过读取触摸屏坐标并经过转算后来识别定义好的虚拟按键,代码位于frameworks/base/services/java/com/android/server/KeyInputQueue.java中:static class Virtualkey是负责按键定位的方法;private void readVirtualKeys(String deviceName)负责读取sys文件,这是最重要的代码,也是与底层sys文件系统沟通的桥梁,它会读取/sys/board_properties/virtualkeys.deviceName文件,deviceName一定要与触摸屏设备名称一致,不然会找不到指定的sys文件。4.sys文件系统前面讲到了readVirtualKeys会读取sys文件,这个sys文件就是定义虚拟按键的坐标以及键值,它的协议格式是一段字符串,每个按键有六项分别用冒号分割,按键按键之间也是用冒号分割,标准格式是:键类型:键值:按键区域中心x坐标:按键区域中心y坐标:按键区域宽:按键区域高加载触摸屏以及创建sys文件的代码:cppview plaincopy1. #ifdefVIRTUAL_KEYS2. staticssize_tvirtual_keys_show(structkobject*kobj,3. structkobj_attribute*attr,char*buf)4. 5. if(1)6. returnsprintf(buf,7. _stringify(EV_KEY):_stringify(KEY_VOLUMEUP):1030:370:30:308. :_stringify(EV_KEY):_stringify(KEY_VOLUMEDOWN):1030:470:30:309. :_stringify(EV_KEY):_stringify(KEY_BACK):1030:18:30:3010. :_stringify(EV_KEY):_stringify(KEY_HOME):1030:136:30:3011. :_stringify(EV_KEY):_stringify(KEY_MENU):1030:236:30:3012. n);13. else14. 15. 16. staticstructkobj_attributevirtual_keys_attr=17. .attr=18. .name=virtualkeys.xxxx,19. .mode=S_IRUGO,20. ,21. .show=&virtual_keys_show,22. ;23. staticstructattribute*properties_attrs=24. &virtual_keys_attr.attr,25. NULL26. ;27. staticstructattribute_groupproperties_attr_group=28. .attrs=properties_attrs,29. ;30. staticvoidvirtual_keys_init(void)31. 32. intret;33. structkobject*properties_kobj;34. properties_kobj=kobject_create_and_add(board_properties,NULL);35. if(properties_kobj)36. ret=sysfs_create_group(properties_kobj,37. &properties_attr_group);38. if(!properties_kobj|ret)39. pr_err(failedtocreateboard_propertiesn);40. 41. #endif42. 其中.name = virtualkeys.xxxx的xxxx就是触摸屏设备名称,也就是前面说到的deviceName,virtual_keys_init()函数可以在触摸屏probe函数中调用。另外,我将可视区域左侧的两侧按键移到了右侧实现,因此五个按键区域中心x坐标都是一样,这部分要在触摸屏驱动增加x轴坐标调整,这部分我就不再说明。以上步骤完成后可以使用 cat /sys/board_properties/virtualkeys.deviceName查看虚拟按键的配置文件,并试试按下触摸屏上按键是否有反应,如果坐标不正确还要进行耐心地校准。具体的可以去HTC网站(/devcenter/downloads)上下载HTC手机的linux源码,HTC很多款手机的BACK,MENU,HOME,SEARCH电容屏虚拟按键都是采用这种方式实现的。(三)但是我用的是四线电阻触摸屏,用上面的方式好像没有任何反应,所以我采用最直接的方式用input_event发送按键消息,就是在触摸屏处理芯片TSC2007驱动中当读到一定范围内的触摸事件就发送按键消息:这种方式只要修改TSC2007驱动的几个地方:1.定义全局局部变量用于记录是否有虚拟按键按下cppview plaincopy1. staticintbackkeydown=0;2. staticinthomekeydown=0;3. staticintmenukeydown=0;2.在prope函数中添加cppview plaincopy1. set_bit(EV_SYN,input_dev-evbit);2. set_bit(KEY_HOME,input_dev-keybit);3. /set_bit(KEY_SEARCH,input_dev-keybit);4. set_bit(KEY_BACK,input_dev-keybit);5. set_bit(KEY_MENU,input_dev-keybit);3.在中断处理work里面添加按键按下消息cppview plaincopy1. if(tc.y=81)&(tc.y=2711)&(tc.x=1891)&(tc.x=1088)&(tc.x=1143)22. 23. if(menukeydown=0)24. 25. input_event(input,EV_KEY,KEY_MENU,1);26. menukeydown=1;27. /printk(menukeydownn);28. 29. 30. 4.在tsc2007_send_up_event函数中添加按键释放消息cppview plaincopy1. if(backkeydown=1)2. 3. backkeydown=0;4. input_event(input,EV_KEY,KEY_BACK,0);5. /printk(backkeyupn);6. 7. if(homekeydown=1)8. 9. homekeydown=0;10. input_event(input,EV_KEY,KEY_HOME,0);11. /printk(homekeyupn);12. 13. if(menukeydown=1)14. 15. menukeydown=0;16. input_event(input,EV_KEY,KEY_MENU,0);17. /printk(menukeyupn);18. 整个修改后的TSC2007驱动如下:cppview plaincopy1. /*2. *drivers/input/touchscreen/tsc2007.c3. *4. *Copyright(c)2008MtekVisionCo.,Ltd.5. *KwangwooLee6. *7. *Usingcodefrom:8. *-ads7846.c9. *Copyright(c)2005DavidBrownell10. *Copyright(c)2006NokiaCorporation11. *-corgi_ts.c12. *Copyright(C)2004-2005RichardPurdie13. *-omap_ts.hc,ads7846.h,ts_osk.c14. *Copyright(C)2002MontaVistaSoftware15. *Copyright(C)2004TexasInstruments16. *Copyright(C)2005DirkBehme17. *18. *Thisprogramisfreesoftware;youcanredistributeitand/ormodify19. *itunderthetermsoftheGNUGeneralPublicLicenseversion2as20. *publishedbytheFreeSoftwareFoundation.21. */22. #include23. #include24. #include25. #include26. #include27. #include28. #defineTS_POLL_DELAY1/*msdelaybetweensamples*/29. #defineTS_POLL_PERIOD1/*msdelaybetweensamples*/30. #defineTSC2007_MEASURE_TEMP0(0x04)31. #defineTSC2007_MEASURE_AUX(0x24)32. #defineTSC2007_MEASURE_TEMP1(0x44)33. #defineTSC2007_ACTIVATE_XN(0x84)34. #defineTSC2007_ACTIVATE_YN(0x94)35. #defineTSC2007_ACTIVATE_YP_XN(0xa4)36. #defineTSC2007_SETUP(0xb4)37. #defineTSC2007_MEASURE_X(0xc4)38. #defineTSC2007_MEASURE_Y(0xd4)39. #defineTSC2007_MEASURE_Z1(0xe4)40. #defineTSC2007_MEASURE_Z2(0xf4)41. #defineTSC2007_POWER_OFF_IRQ_EN(0x02)42. #defineTSC2007_ADC_ON_IRQ_DIS0(0x12)43. #defineTSC2007_ADC_OFF_IRQ_EN(0x22)44. #defineTSC2007_ADC_ON_IRQ_DIS1(0x32)45. #defineTSC2007_12BIT(0x01)46. #defineTSC2007_8BIT(0x11)47. #defineMAX_12BIT(1client,cmd);79. if(dataclient-dev,i2cioerror:%dn,data);81. returndata;82. 83. /*Theprotocolandrawdataformatfromi2cinterface:84. *SAddrWrACommASAddrRdADataLowADataHighNAP85. *WhereDataLowhasD11-D4,DataHighhasD3-D04;88. dev_dbg(&tsc-client-dev,data:0x%x,val:0x%xn,data,val);89. returnval;90. 91. staticvoidtsc2007_read_values(structtsc2007*tsc,structts_event*tc)92. 93. /*y-stillon;turnononlyy+(andADC)*/94. tc-y=tsc2007_xfer(tsc,READ_Y);95. /*turny-off,x+on,thenleaveinlowpower*/96. tc-x=tsc2007_xfer(tsc,READ_X);97. /*turny+off,x-on;welluseformula#1*/98. tc-z1=tsc2007_xfer(tsc,READ_Z1);99. tc-z2=tsc2007_xfer(tsc,READ_Z2);100. /printk(x=%d,y=%dn,tc-x,tc-y);101. /*Preparefornexttouchreading-powerdownADC,enablePENIRQ*/102. tsc2007_xfer(tsc,PWRDOWN);103. 104. staticu32tsc2007_calculate_pressure(structtsc2007*tsc,structts_event*tc)105. 106. u32rt=0;107. /*rangefiltering*/108. if(tc-x=MAX_12BIT)109. tc-x=0;110. if(likely(tc-x&tc-z1)111. /*computetouchpressureresistanceusingequation#1*/112. rt=tc-z2-tc-z1;113. rt*=tc-x;114. rt*=tsc-x_plate_ohms;115. rt/=tc-z1;116. rt=(rt+2047)12;117. 118. returnrt;119. 120. staticvoidtsc2007_send_up_event(structtsc2007*tsc)121. 122. structinput_dev*input=tsc-input;123. dev_dbg(&tsc-client-dev,UPn);124. if(backkeydown=1)125. 126. backkeydown=0;127. input_event(input,EV_KEY,KEY_BACK,0);128. /printk(backkeyupn);129. 130. if(homekeydown=1)131. 132. homekeydown=0;133. input_event(input,EV_KEY,KEY_HOME,0);134. /printk(homekeyupn);135. 136. if(menukeydown=1)137. 138. menukeydown=0;139. input_event(input,EV_KEY,KEY_MENU,0);140. /printk(menukeyupn);141. 142. input_report_key(input,BTN_TOUCH,0);143. input_report_abs(input,ABS_PRESSURE,0);144. input_sync(input);145. 146. staticvoidtsc2007_work(structwork_struct*work)147. 148. structtsc2007*ts=149. container_of(to_delayed_work(work),structtsc2007,work);150. structts_eventtc;151. u32rt;152. /*153. *NOTE:Wecantrelyonthepressuretodeterminethependown154. *state,eventhoughthiscontrollerhasapressuresensor.155. *Thepressurevaluecanfluctuateforquiteawhileafter156. *liftingthepenandinsomecasesmaynotevensettleatthe157. *expectedvalue.158. *159. *Theonlysafewaytocheckforthepenupconditionisinthe160. *workfunctionbyreadingthepensignalstate(itsaGPIO161. *andIRQ).Unfortunatelysuchcallbackisnotalwaysavailable,162. *inthatcasewehaverelyonthepressureanyway.163. */164. if(ts-get_pendown_state)165. if(unlikely(!ts-get_pendown_state()166. tsc2007_send_up_event(ts);167. ts-pendown=false;168. gotoout;169. 170. dev_dbg(&ts-client-dev,penisstilldownn);171. 172. tsc2007_read_values(ts,&tc);173. rt=tsc2007_calculate_pressure(ts,&tc);174. if(rtMAX_12BIT)175. /*176. *Samplefoundinconsistentbydebouncingorpressureis177. *beyondthemaximum.Dontreportittouserspace,178. *repeatatleastoncemorethemeasurement.179. */180. dev_dbg(&ts-client-dev,ignoredpressure%dn,rt);181. gotoout;182. 183. if(rt)184. structinput_dev*input=ts-input;185. if(tc.y=81)&(tc.y=2711)&(tc.x=1891)&(tc.x=1088)&(tc.xpendown)216. dev_dbg(&ts-client-dev,DOWNn);217. input_report_key(input,BTN_TOUCH,1);218. ts-pendown=true;219. 220. input_report_abs(input,ABS_X,tc.x);221. input_report_abs(input,ABS_Y,tc.y);222. input_report_abs(input,ABS_PRESSURE,rt);223. input_sync(input);224. dev_dbg(&ts-client-dev,point(%4d,%4d),pressure(%4u)n,225. tc.x,tc.y,rt);226. elseif(!ts-get_pendown_state&ts-pendown)227. /*228. *Wedonthavecallbacktocheckpendownstate,sowe229. *havetoassumethatsincepressurereportedis0the230. *penwasliftedup.231. */232. tsc2007_send_up_event(ts);233. ts-pendown=false;234. 235. out:236. if(ts-pendown)237. schedule_delayed_work(&ts-work,238. msecs_to_jiffies(TS_POLL_PERIOD);239. else240. enable_irq(ts-irq);241. 242. staticirqreturn_ttsc2007_irq(intirq,void*handle)243. 244. structtsc2007*ts=handle;245. if(!ts-get_pendown_state|likely(ts-get_pendown_state()246. disable_irq_nosync(ts-irq);247. schedule_delayed_work(&ts-work,248. msecs_to_jiffies(TS_POLL_DELAY);249. 250. if(ts-clear_penirq)251. ts-clear_penirq();252. returnIRQ_HANDLED;253. 254. staticvoidtsc2007_free_irq(structtsc2007*ts)255. 256. free_irq(ts-irq,ts);257. if(cancel_delayed_work_sync(&ts-work)258. /*259. *Workwaspending,thereforeweneedtoenable260. *IRQheretobalancethedisable_irq()doneinthe261. *interrupthandler.262. */263. enable_irq(ts-irq);264. 265. 266. staticint_devinittsc2007_probe(structi2c_client*client,267. conststructi2c_device_id*id)268. 269. structtsc2007*ts;270. structtsc2007_platform_data*pdata=pdata=client-dev.platform_data;271. structinput_dev*input_dev;272. interr;273. if(!pdata)274. dev_err(&client-dev,platformdataisrequired!n);275. return-EINVAL;276. 277. if(!i2c_check_functionality(client-adapter,278. I2C_FUNC_SMBUS_READ_WORD_DATA)279. return-EIO;280. ts=kzalloc(sizeof(structtsc2007),GFP_KERNEL);281. input_dev=input_allocate_device();282. if(!ts|!input_dev)283. err=-ENOMEM;284. gotoerr_free_mem;285. 286. ts-client=client;287. ts-irq=client-irq;288. ts-input=input_dev;289. INIT_DELAYED_WORK(&ts-work,tsc2007_work);290. ts-model=pdata-model;291. ts-x_plate_ohms=pdata-x_plate_ohms;292. ts-get_pendown_state=pdata-get_pendown_state;293. ts-clear_penirq=pdata-c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论