最近一段時間在搞android的觸控螢幕校正,想把心得記下來與大家分享,廢話不多說,開始講解.
註:調試使用的是偉研科技(www.gzweiyan.com)210開發板,android版本 2.2 ,核心是2.6.32
一、修改核心驅動
修改觸控螢幕驅動(kernel/drivers/input/touchscreen/s3c-ts.c)
-input_set_abs_params(ts->dev, ABS_X, X_COOR_MIN, X_COOR_MAX, X_COOR_FUZZ, 0);<br /> -input_set_abs_params(ts->dev, ABS_Y, Y_COOR_MIN, Y_COOR_MAX, Y_COOR_FUZZ, 0);<br />+input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0);<br />+input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF, 0, 0);<br />-input_set_abs_params(ts->dev, ABS_MT_POSITION_X, X_COOR_MIN,X_COOR_MAX, 0, 0);<br />-input_set_abs_params(ts->dev, ABS_MT_POSITION_Y, Y_COOR_MIN,Y_COOR_MAX, 0, 0);<br /> +input_set_abs_params(ts->dev, ABS_MT_POSITION_X, 0, 0xFFF, 0, 0);<br /> +input_set_abs_params(ts->dev, ABS_MT_POSITION_Y, 0, 0xFFF, 0, 0);<br /> if(m_status == 1){<br /> input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_X, m_lx);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_Y, m_ly);<br /> +input_report_abs(ts->dev, ABS_PRESSURE, 1);<br /> printk("X1:%d Y1:%d/n",m_lx,m_ly);<br /> input_mt_sync(ts->dev);<br /> input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_X, press_x);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_Y, press_y);<br /> + input_report_abs(ts->dev, ABS_PRESSURE, 1);<br /> input_mt_sync(ts->dev);<br /> }<br /> else {<br /> input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_X, x);<br /> input_report_abs(ts->dev, ABS_MT_POSITION_Y, y);<br /> + input_report_abs(ts->dev, ABS_PRESSURE, 1);<br /> printk("X2:%d Y2:%d/n",x,y);<br /> input_mt_sync(ts->dev);<br /> }<br />#if 1<br /> + input_report_abs(ts->dev, ABS_PRESSURE, 0);<br />#endif /* !CONFIG_ANDROID */
這樣做的目的是根據使核心不使用限定好的座標範圍,x,y的座標範圍還原成0-4095
二、修改property_service.c(android2_2/system/core/init/property_service.c)
在property_perms增加
{ "ts.config.calibrate" , AID_SYSTEM, 0 }
這樣做的目的是為可以了後面使用觸控螢幕校正程式可以對ts.config.calibrate這個系統屬性進行操作,後面會說到.
三、修改InputDevice.java(android2_2/frameworks/base/services/java/com/android/server/InputDevice.java)
在generateAbsMotion函數中增加
String prop = SystemProperties.get("ts.config.calibrate");<br /> if (prop!=null)<br /> {<br /> if (prop.equalsIgnoreCase("start")){<br /> Slog.d("XXW prop", prop);<br /> Slog.d("XXW", "prop.equalsIgnoreCase start");<br /> device.tInfo = null;<br /> }<br /> else if (prop.equalsIgnoreCase("done")){<br /> Slog.d("XXW prop", prop);<br /> Slog.d("XXW", "prop.equalsIgnoreCase done");<br /> readCalibrate();<br /> device.tInfo=tInfo;<br /> SystemProperties.set("ts.config.calibrate", "end");<br /> }<br /> else{<br /> Slog.i("XXW prop", prop);<br /> Slog.i("XXW", "prop.equalsIgnoreCase else");<br /> }<br /> }
這裡使用到系統屬性ts.config.calibrate,當系統判斷為現在處於觸控螢幕校正模式的時候(也就是ts.config.calibrate值為start的時候),不對驅動傳遞上來的座標值進行轉換.
上面第二點在在property_perms增加{ "ts.config.calibrate" , AID_SYSTEM, 0 }是為了系統有許可權可以設定/讀取這個屬性
增加函數
static void readCalibrate(){<br /> //xxw added<br /> Slog.i("XXW","readCalibrate!");<br /> TransformInfo t = null;<br /> try {<br /> FileInputStream is = new FileInputStream(CALIBRATION_FILE);<br /> byte[] mBuffer = new byte[64];<br /> int len = is.read(mBuffer);<br /> is.close();<br /> if (len > 0) {<br /> int i;<br /> for (i = 0 ; i < len ; i++) {<br /> if (mBuffer[i] == '/n'||mBuffer[i] == 0) {<br /> break;<br /> }<br /> }<br /> len = i;<br /> }<br /> StringTokenizer st = new StringTokenizer( new String(mBuffer, 0, 0, len));<br /> t = new TransformInfo ();<br /> t.x1 = Integer.parseInt( st.nextToken() );<br /> t.y1 = Integer.parseInt( st.nextToken() );<br /> t.z1 = Integer.parseInt( st.nextToken() );<br /> t.x2 = Integer.parseInt( st.nextToken() );<br /> t.y2 = Integer.parseInt( st.nextToken() );<br /> t.z2 = Integer.parseInt( st.nextToken() );<br /> t.s = Integer.parseInt( st.nextToken() );<br /> } catch (java.io.FileNotFoundException e) {<br /> Slog.i("XXW", "FileNotFound!");<br /> } catch (java.io.IOException e) {<br /> Slog.i("XXW", "IOException");<br /> }<br /> tInfo = t;<br /> Slog.i("XXW","readCalibrate done!");<br /> }
修改InputDevice函數
InputDevice(int _id, int _classes, String _name,<br /> AbsoluteInfo _absX, AbsoluteInfo _absY,<br /> AbsoluteInfo _absPressure, AbsoluteInfo _absSize) {<br /> id = _id;<br /> classes = _classes;<br /> name = _name;<br /> absX = _absX;<br /> absY = _absY;<br /> absPressure = _absPressure;<br /> absSize = _absSize;<br /> readCalibrate();<br />
編譯後產生services.jar,須替換android檔案系統裡面的system/framwork裡面的services.jar
四、修改觸控螢幕校正程式 修改onTouchEvent(CalibrationTest.java) CalibrationTest.java這裡是我使用的觸控螢幕校正程式,我的屏的解析度為800*480,所以改成 mResultPts[(STEP -1) * mPtsLength] = event.getX()*4095/(800-1); mResultPts[(STEP -1) * mPtsLength + 1] = event.getY()*4095/(480-1); 修改AndroidManifest.xml 增加 android:sharedUserId="android.uid.system" <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="touchscreen.test" android:sharedUserId="android.uid.system"> 修改 Android.mk增加 LOCAL_CERTIFICATE := platform
五、修改init.rc增加#create tslib mkdir /data/system/tslib/ 0777 chmod 0666 /data/system/tslib/pointercal觸控螢幕校正看來起貌似簡單,但要改的東西確實太多,我自己也是摸索了好幾天才搞定的,呵呵!