2015年9月24日 星期四

[轉] Android2.3觸摸屏功能詳解

Android2.3觸摸屏功能詳解

手機設備上常用觸摸屏進行用戶操作,非常方便快捷,而且正好有個項目上用到這個設備,所以就花時間研究了一下。好了,還是老規則:大體瞭解概念先,細節線索找代碼:
InputReader.cpp 中有針對單點觸摸SingleTouchInputMapper及多點觸摸MultiTouchInputMapper的處理代碼,這兩個類都繼承自TouchInputMapper,由syncTouch處理最終的觸摸屏動作的發送。
1、首先瞭解一下觸摸屏中的幾個參數概念:
「接觸」一詞用來描述一個物體直接碰到另一個物體的表面。
單點觸摸的參數解析:
ABS_XABS_Y分別對應觸摸屏的xy坐標
ABS_PRESSURE是壓力值,一般觸摸屏也只是分是否有按下去,按下去的話值會大於多少,沒有按的話值小於多少
ABS_TOOL_WIDTH 觸摸工具的寬度
多點觸摸的參數解析:
ABS_MT_POSITION_X 接觸面的形心的X坐標值 
ABS_MT_POSITION_Y 接觸面的形心的Y坐標值 
 ABS_MT_TOUCH_MAJORABS_MT_WIDTH_MAJOR 分別被用來提供手指的大小和觸摸面積大小 
TOUCH 和 WIDTH參數給出了個,想想如果一個手指按在玻璃上,透過玻璃你將看到兩個區域,一個是手指與玻璃接觸的區域,用 ABS_MT_TOUCH_MAJOR描述,一個是手指本身大小的區域,ABS_MT_WIDTH_MAJOR描述, 手指與玻璃接觸的面積要小於手指本身的大小,通過這兩個參數,可以換算出手指的壓力。也可通過 ABS_MT_PRESSURE參數直接提供手指的壓力。
  除了 MAJOR這個參數,還可以提供一個 MINOR參數,手指可以被認為是一個橢圓,MAJOR和 MINOR可以認為是這個橢圓的長軸和短軸,橢圓的中心可以被 ORIENTATION這個參數描述。
ABS_MT_PRESSURE
  接觸工具對接觸面的壓力大小,可以用來代替上面的四個參數。
ABS_MT_ORIENTATION
  描述隨圓的轉動趨勢,這是一個抽相值,O值表示接觸面在平行與觸摸屏的Y軸,向左是負值,向右是正值,如果完全平行於X軸,則上向返回最大值。如果接觸面是圓形,則可以忽略這個參數。如果內核不能獲得這個參數有有效值,但可以區分接觸面的長短軸,這個功能還是可以被部份支持,在一些設備中, ABS_MT_ORIENTATION 的值只能是 0和1。
ABS_MT_TOOL_TYPE描述接觸工具類型(手指,觸控筆等 ),很多內核驅動無法區分此參數如手指及筆,如果是這樣,該參數可以不用,協議目前支持MT_TOOL_FINGERMT_TOOL_PEN兩種類型。
ABS_MT_BLOB_ID形狀集ID,集合幾個點以描述一個形狀,很多驅動沒有形狀屬性,此參數可以不用。
ABS_MT_TRACKING_ID描述了從接觸開始到釋放的整個過程的集合,如果設備不支持,此參數可是不用。
計算方法:
  一些設備將觸摸面作為一個矩形上報,可以通過下面這些公式來計算出協議中所需要的信息。
ABS_MT_TOUCH_MAJOR := max(X, Y)
ABS_MT_TOUCH_MINOR := min(X, Y)
ABS_MT_ORIENTATION  := bool(X > Y)
ABS_MT_ORIENTATION的取值範圍為0至1,用來標識矩形接觸面偏向X軸或Y軸的程度。
觸摸軌跡
僅有少數設備可以明觸的標識真實的 trackingID,多數情況下 trackingID只能來標識一次觸摸動作的過程。
手勢
多點觸摸指定的應用是創建手勢動作, TOUCH和 WIDTH參數經常用來區別手指的壓力和手指間的距離,另外 MINOR類的參數可以用來區別設備的接觸面的大小(點接觸還是面接觸),ORIENTATION可以產生旋轉事件。
以上的含義從http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt 翻譯而來,可以自行下載
2、代碼入手
第一部分:直接寫/dev/input/eventX接點實現
單點觸摸事件發送序列:
EV_KEY (BTN_TOUCH) 發送是否在按下或彈出(0或者1
ABS_X 
ABS_Y
ABS_PRESSURE
ABS_TOOL_WIDTH
代碼演示:
event.type  = EV_KEY;
event.code  = BTN_TOUCH;
mDown = (istEvent->pointers[0].abs_pressure > 0)?1:0 ;
Event.value  = mDown;
write(fd,&event,sizeof(event)) ;
/* 觸摸屏鍵按下坐標定位  */
event.type  = EV_ABS;
    event.code  = ABS_X;
    event.value = istEvent->pointers[0].abs_x;
    write(fd,&event,sizeof(event)) ;
event.type  = EV_ABS;
    event.code  = ABS_Y;
    event.value = istEvent->pointers[0].abs_y;
    write(fd,&event,sizeof(event)) ;
    /* 觸摸屏接觸面的壓力大小 */
event.type  = EV_ABS;
    event.code  = ABS_PRESSURE;
    event.value = istEvent->pointers[0].abs_pressure;
    write(fd,&event,sizeof(event)) ;
event.type   = EV_ABS;
event.code   = ABS_TOOL_WIDTH;
event.value  = istEvent->pointers[0].abs_touch_major;
/* 結束完整幀數據,發送同步信號 */
    event.type  = EV_SYN; 
    event.code  = SYN_REPORT;
    event.value = 0;
    write(fd, &event, sizeof(event));
    
    Ok,非常簡單,對比inputreader.cpp中的代碼,注意process代碼:
void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_KEY:  //一定要注意發送這個event,否則觸摸事件不會發送出去,直接丟棄
        switch (rawEvent->scanCode) {
        case BTN_TOUCH:
            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
            mAccumulator.btnTouch = rawEvent->value != 0;
            // Don't sync immediately.  Wait until the next SYN_REPORT since we might
            // not have received valid position information yet.  This logic assumes that
            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete 
            // packet.
            break;
        }
        break;
...
}
void SingleTouchInputMapper::sync(nsecs_t when) {
...
    if (mDown) {  // 這就是上面為何要發送的原因
        mCurrentTouch.pointerCount = 1;
        mCurrentTouch.pointers[0].id = 0;
        mCurrentTouch.pointers[0].x = mX;
        mCurrentTouch.pointers[0].y = mY;
        mCurrentTouch.pointers[0].pressure = mPressure;
        mCurrentTouch.pointers[0].touchMajor = 0;
        mCurrentTouch.pointers[0].touchMinor = 0;
        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
        mCurrentTouch.pointers[0].orientation = 0;
        mCurrentTouch.idToIndex[0] = 0;
        mCurrentTouch.idBits.markBit(0);
}
...
}
多點觸摸事件發送序列:
ABS_MT_TOUCH_MAJOR
ABS_MT_PRESSURE
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上報第一個點
ABS_MT_TOUCH_MAJOR
ABS_MT_PRESSURE
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上報第二個點
... //以上順序組織多點touch event即可
SYN_REPORT         //最後發送的完整包動作
代碼演示:
for(pointIndex=0;pointIndex<imtEvent->pointnums;pointIndex++)
{
/* 觸摸屏鍵按下坐標定位  */
event.type  = EV_ABS;
event.code  = ABS_MT_POSITION_X;
event.value = imtEvent->pointers[pointIndex].abs_x;
write(fd,&event,sizeof(event)) ;
event.type  = EV_ABS;
event.code  = ABS_MT_POSITION_Y;
event.value = imtEvent->pointers[pointIndex].abs_y;
write(fd,&event,sizeof(event)) ;
    /* 觸摸屏接觸面的壓力大小 */
event.type  = EV_ABS;
    event.code  = ABS_MT_PRESSURE;
    event.value = imtEvent->pointers[pointIndex].abs_pressure;
    write(fd,&event,sizeof(event)) ;
/* 觸摸屏接觸面積大小 */
event.type   = EV_ABS;
event.code   = ABS_MT_TOUCH_MAJOR;
event.value  = imtEvent->pointers[pointIndex].abs_touch_major;
event.type  = EV_SYN;
event.code  = SYN_MT_REPORT;
event.value = 0;
write(fd,&event,sizeof(event)) ;
}
/* 結束完整幀數據,發送同步信號 */
event.type  = EV_SYN;
event.code  = SYN_REPORT;
event.value = 0;
write(fd,&event,sizeof(event)) ;
Ok,只要深入研究下inputreader.cpp的代碼即可輕鬆解決這些問題,更擴展的功能擴大及縮小,以及旋轉的功能都可以搞定。
對於多點觸摸的功能,首先在linux內核的input輸入模型需要支持,這個在linux/input.h可以見到,多點觸摸功能依賴於以下幾個主要的軟件位:
#define ABS_MT_TOUCH_MAJOR 0x30/* Major axis of touching ellipse */ 
#define ABS_MT_TOUCH_MINOR 0x31/* Minor axis (omit if circular) */ 
#define ABS_MT_WIDTH_MAJOR 0x32/* Major axis of approaching ellipse */ 
#define ABS_MT_WIDTH_MINOR 0x33/* Minor axis (omit if circular) */ 
#define ABS_MT_ORIENTATION 0x34/* Ellipse orientation */ 
#define ABS_MT_POSITION_X 0x35/* Center X ellipse position */ 
#define ABS_MT_POSITION_Y 0x36/* Center Y ellipse position */ 
#define ABS_MT_TOOL_TYPE 0x37/* Type of touching device */ 
#define ABS_MT_BLOB_ID 0x38/* Group a set of packets as a blob */
第二部分:利用linux input輸入模型發送
主要函數介紹:
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_ABS, code, value);
}
static inline void input_mt_sync(struct input_dev *dev)
{
input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
}
static inline void input_sync(struct input_dev *dev)
{
input_event(dev, EV_SYN, SYN_REPORT, 0);
}
代碼示例:
設定初始參數(支持單點觸摸及多點觸摸):
    set_bit(EV_SYN, ts->input_dev->evbit);
    set_bit(EV_KEY, ts->input_dev->evbit);
    set_bit(EV_ABS, ts->input_dev->evbit);
    set_bit(BTN_TOUCH,ts->input_dev->keybit);
    
    max_x = 1280;
    max_y = 720;
    
    input_set_abs_params(ts->input_dev, ABS_X, 0, max_x, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_Y, 0, max_y, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
    input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); 
    input_register_device(ts->input_dev);    
按下時:
for(i=0;i<finger;i++){
    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
    input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100);
    input_report_abs(ts->input_dev, ABS_MT_POSITION_X, ts->x[i]);
    input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->y[i]);
    input_mt_sync(ts->input_dev);
    ts->upsend=0;
}
input_sync(ts->input_dev);
彈起時:
    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
    input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);
    input_mt_sync(ts->input_dev);
    input_sync(ts->input_dev);

SPI

 Linux SPI總線和設備驅動架構
http://blog.csdn.net/droidphone/article/details/23367051
http://blog.csdn.net/droidphone/article/details/23932447
http://blog.csdn.net/droidphone/article/details/24353293
http://blog.csdn.net/droidphone/article/details/24663659


Linux下spi驅動開發
http://blog.csdn.net/hongtao_liu/article/details/6580611
http://blog.csdn.net/hongtao_liu/article/details/6737321

[轉] tp的A模式和B模式 ( Linux輸入子系統:多點觸控協議)

http://m.blog.csdn.net/blog/liwei405499/42015469

2015年9月23日 星期三

[轉] 作業系統。linux 各種解壓縮方法

.tar 
解壓:tar xvf FileName.tar 
壓缩:tar cvf FileName.tar DirName 
(注:tar是包裹(把多個檔案合成一個),不是壓缩!) 
--------------------------------------------- 
.gz 
解壓1:gunzip FileName.gz 
解壓2:gzip -d FileName.gz 
壓缩:gzip FileName 
.tar.gz 
解壓:tar zxvf FileName.tar.gz 
壓缩:tar zcvf FileName.tar.gz DirName 
--------------------------------------------- 
.bz2 
解壓1:bzip2 -d FileName.bz2 
解壓2:bunzip2 FileName.bz2 
壓缩: bzip2 -z FileName 
.tar.bz2 
解壓:tar jxvf FileName.tar.bz2 
壓缩:tar jcvf FileName.tar.bz2 DirName 
--------------------------------------------- 
.bz 
解壓1:bzip2 -d FileName.bz 
解壓2:bunzip2 FileName.bz 
壓缩:未知 
.tar.bz 
解壓:tar jxvf FileName.tar.bz 
壓缩:未知 
--------------------------------------------- 
.Z 
解壓:uncompress FileName.Z 
壓缩:compress FileName 
.tar.Z 
解壓:tar Zxvf FileName.tar.Z 
壓缩:tar Zcvf FileName.tar.Z DirName 
--------------------------------------------- 
.tgz 
解壓:tar zxvf FileName.tgz 
壓缩:未知 
.tar.tgz 
解壓:tar zxvf FileName.tar.tgz 
壓缩:tar zcvf FileName.tar.tgz FileName 
--------------------------------------------- 
.zip 
解壓:unzip FileName.zip 
壓缩:zip FileName.zip DirName 
--------------------------------------------- 
.rar 
解壓:rar a FileName.rar 
壓缩:rar e FileName.rar 


rar請到:http://www.rarsoft.com/download.htm 下載! 
解壓後請将rar_static拷貝到/usr/bin目錄(其他由$PATH環境變數指定的目錄也可以): 
[root@www2 tmp]# cp rar_static /usr/bin/rar 
--------------------------------------------- 
.lha 
解壓:lha -e FileName.lha 
壓缩:lha -a FileName.lha FileName 

lha請到:http://www.infor.kanazawa-it.ac.jp/~ishii/lhaunix/下載! 
解壓後請将lha拷贝到/usr/bin目錄(其他由$PATH環境變數指定的目錄也可以): 
[root@www2 tmp]# cp lha /usr/bin/ 
--------------------------------------------- 
.tar .tgz .tar.gz .tar.Z .tar.bz .tar.bz2 .zip .cpio .rpm .deb .slp .arj .rar .ace .lha .lzh .lzx .lzs .arc .sda .sfx .lnx .zoo .cab .kar .cpt .pit .sit .sea 
解壓:sEx x FileName.* 
壓缩:sEx a FileName.* FileName 

sEx只是調用相關程序,本身並無壓缩、解壓功能,請注意!\r 
sEx請到:http://sourceforge.net/projects/sex下載! 
解壓后請将sEx拷贝到/usr/bin目錄(其他由$PATH環境變數指定的目錄也可以): 

2015年9月20日 星期日

[轉] Intent中的四個重要屬性——Action、Data、Category、Extras

Intent中的四個重要屬性——Action、Data、Category、Extras

  Intent作為聯繫各Activity之間的紐帶,其作用並不僅僅只限於簡單的數據傳遞。通過其自帶的屬性,其實可以方便的完成很多較為複雜的操作。例如直接調用撥號功能、直接自動調用合適的程序打開不同類型的文件等等。諸如此類,都可以通過設置Intent屬性來完成。
  Intent主要有以下四個重要屬性,它們分別為:
    Action:Action屬性的值為一個字符串,它代表了系統中已經定義了一系列常用的動作。通過setAction()方法或在清單文件AndroidManifest.xml中設置。默認為:DEFAULT。
    Data:Data通常是URI格式定義的操作數據。例如:tel:// 。通過setData()方法設置。
    Category:Category屬性用於指定當前動作(Action)被執行的環境。通過addCategory()方法或在清單文件AndroidManifest.xml中設置。默認為:CATEGORY_DEFAULT。
    Extras:Extras屬性主要用於傳遞目標組件所需要的額外的數據。通過putExtras()方法設置。
  四個屬性各自的常用值如下所示:
  Action:
      ACTION_MAIN:Android Application的入口,每個Android應用必須且只能包含一個此類型的Action聲明。 
    ACTION_VIEW:系統根據不同的Data類型,通過已註冊的對應Application顯示數據。
    ACTION_EDIT:系統根據不同的Data類型,通過已註冊的對應Application編輯示數據 
    ACTION_DIAL打開系統默認的撥號程序,如果Data中設置了電話號碼,則自動在撥號程序中輸入此號碼 
    ACTION_CALL:直接呼叫Data中所帶的號碼 
    ACTION_ANSWER:接聽來電 
    ACTION_SEND:由用戶指定發送方式進行數據發送操作
    ACTION_SENDTO:系統根據不同的Data類型,通過已註冊的對應Application進行數據發送操作 
    ACTION_BOOT_COMPLETED:Android系統在啟動完畢後發出帶有此Action的廣播(Broadcast) 
    ACTION_TIME_CHANGEDAndroid系統的時間發生改變後發出帶有此Action的廣播(Broadcast) 
    ACTION_PACKAGE_ADDEDAndroid系統安裝了新的Application之後發出帶有此Action的廣播(Broadcast) 
    ACTION_PACKAGE_CHANGEDAndroid系統中已存在的Application發生改變之後(如應用更新操作)發出帶有此Action的廣播(Broadcast) 
    ACTION_PACKAGE_REMOVED:卸載了Android系統已存在的Application之後發出帶有此Action的廣播(Broadcast)  
  Category:
      CATEGORY_DEFAULTAndroid系統中默認的執行方式,按照普通Activity的執行方式執行 
    CATEGORY_HOME:設置該組件為Home Activity
    CATEGORY_PREFERENCE:設置該組件為Preference 
    CATEGORY_LAUNCHER:設置該組件為在當前應用程序啟動器中優先級最高的Activity,通常為入口ACTION_MAIN配合使用 
    CATEGORY_BROWSABLE設置該組件可以使用瀏覽器啟動 
    CATEGORY_GADGET設置該組件可以內嵌到另外的Activity
  Extras:
      EXTRA_BCC:存放郵件密送人地址的字符串數組。 
    EXTRA_CC:存放郵件抄送人地址的字符串數組
    EXTRA_EMAIL:存放郵件地址的字符串數組 
    EXTRA_SUBJECT:存放郵件主題字符串 
    EXTRA_TEXT存放郵件內容 
    EXTRA_KEY_EVENTKeyEvent對象方式存放觸發Intent的按鍵  
    EXTRA_PHONE_NUMBER存放調用ACTION_CALL時的電話號碼   
   Data:
      tel://:號碼數據格式,後跟電話號碼。 
    mailto://:郵件數據格式,後跟郵件收件人地址
    smsto://:短息數據格式,後跟短信接收號碼
    content://:內容數據格式,後跟需要讀取的內容。 
    file://:文件數據格式,後跟文件路徑
    market://search?q=pname:pkgname:市場數據格式,在Google Market裡搜索包名為pkgname的應用
    geo://latitude, longitude:經緯數據格式,在地圖上顯示經緯度所指定的位置