inux drive中input子系統上報信息,調用函數linux
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value),app
input子系統最終調用copy_to_user(buffer, event, sizeof(struct input_event))將信息上報給上層,event爲struct input_event類型結構體, 中間會有一些處理將 type,code,value值打包成input_event類型的數據。底層上報該結構體給上層。函數
struct input_event {code
struct timeval time;事件
__u16 type;ip
__u16 code;ci
__s32 value;input
};it
struct timeval {io
__kernel_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
typedef long __kernel_time_t;
typedef int __kernel_suseconds_t;
對於按鍵
type爲事件類型,按鍵爲EV_KEY,在include/linux/input.h中,
#define EV_KEY 0x01
code爲按鍵的值,value用於標記按鍵是按下仍是彈起,1是按下,0是彈起。
按下和彈起事件只需上報一次。
對於touch
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value) 爲input_event的封裝,函數以下
input_event(dev, EV_ABS, code, value);
type爲EV_ABS, #define EV_ABS 0X03,
code的值,根據上報屬性的不一樣,分別以下:
(多點觸摸)
#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 */
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
ABS_MT_TOUCH_MAJOR和ABS_MT_PRESSURE實現一個應該就能夠了。
(單點觸摸)input.h中列舉了不少屬性,但只需實現如下幾種便可。
#define ABS_X 0x00
#define ABS_Y 0x01
#define ABS_Z 0x02 (通常沒必要實現)
#define ABS_PRESSURE 0x18
下面一個BTN_TOUCH爲點擊事件,單點觸摸中須要上報點擊事件
#define BTN_TOUCH 0x14a
touch點上報機制
多點觸摸
value爲對應屬性的值,如code爲ABS_MT_POSITION_X,則value的值爲就爲x軸座標。
當把一個點的信息發送完畢之後,還需加上input_mt_sync(注意:即便只有一個點也須要加上),這個函數轉換成input_event事件爲
input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
其中#define EV_SYN 0x00, #define SYN_MT_REPORT 2,
則type爲0x00,code爲2,value爲0。
接着再上報第二個點,第二個點上報結束,依舊要上報input_mt_sync,直至最後一次報點結束,加上input_sync,轉換成input_event事件爲
input_event(dev, EV_SYN, SYN_REPORT, 0);
其中#define EV_SYN 0x00,#define SYN_REPORT 0,
則type爲0x00,code爲0,value爲0。至此報點結束。
點須要一直上報。
Linux 驅動中的例子
input_report_abs(ssd2531_data.input, ABS_MT_TRACKING_ID, 1);
input_report_abs(ssd2531_data.input, ABS_MT_TOUCH_MAJOR, PRESS_STATUS);
input_report_abs(ssd2531_data.input, ABS_MT_POSITION_X, X_COOR);
input_report_abs(ssd2531_data.input, ABS_MT_POSITION_Y, Y_COOR);
input_mt_sync(ssd2531_data.input);
單點觸摸
單點上報同多點上報差很少,只是不須要input_mt_sync了,上報過程當中須要
input_event(dev, EV_KEY, BTN_TOUCH, 0/1 ); value爲1,表明按下,value爲0表明擡起。code值爲BTN_TOUCH, #define BTN_TOUCH 0x14a;
一樣最後結束須要input_sync。
linux驅動的例子‘
input_report_abs(ts.input, ABS_X, ts.xp);
input_report_abs(ts.input, ABS_Y, ts.yp);
input_report_key(ts.input, BTN_TOUCH, 1);
input_sync(ts.input);
input_event結構體中,有一個成員爲struct timeval time;用來記錄此刻的牆上時間。