Linux Input 子系統Event Interface詳解__Linux

來源:互聯網
上載者:User
Linux Input子系統中,每個輸入裝置可以建立一個Device。例如:當插入USB Mouse,USB Keyboard,或者採用UInput建立Input Device時。在系統/dev/input/ 目錄下就會產生對應的Device。 如:/dev/input/event0, /dev/input/mouse0, /dev/input/misc等。

可以通過讀取這些Device擷取輸入裝置輸入的資訊。同時,也可以通過一系列ioctl()得到和設定(主要是得到)這些Device 的資訊。 這裡,我們主要分析此Event Interface 的ioctl().

0. 基礎資訊: 0.1:關鍵結構體input_event資訊: struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };
type: 裝置類型。可以設定為: #define EV_SYN          0x00    表示裝置支援所有的事件 #define EV_KEY          0x01    鍵盤或者按鍵,表示一個鍵碼   #define EV_REL          0x02    滑鼠裝置,表示一個相對的游標位置結果 #define EV_ABS          0x03    手寫板產生的值,其是一個絕對整數值  #define EV_MSC          0x04    其他類型  #define EV_LED          0x11    LED燈裝置 #define EV_SND          0x12    蜂鳴器,輸入聲音  #define EV_REP          0x14    允許重複按鍵類型  #define EV_PWR          0x16    電源管理事件  #define EV_FF_STATUS 0x17 #define EV_MAX 0x1f #define EV_CNT (EV_MAX+1)
code: 根據Type的不同而含義不同。 例如: Type為EV_KEY時,code表示鍵盤code或者滑鼠Button值。 取值範圍: #define EV_SYN 0x00 到: #define KEY_MIN_INTERESTING KEY_MUTE #define KEY_MAX 0x2ff #define KEY_CNT (KEY_MAX+1)

Type為EV_REL時,code表示操作的是哪個座標軸,如:REL_X,REL_Y。(因為滑鼠有x,y兩個軸向,所以一次滑鼠移動,會產生兩個input_event) 取值範圍: #define REL_X 0x00 #define REL_Y 0x01 #define REL_Z 0x02 #define REL_RX 0x03 #define REL_RY 0x04 #define REL_RZ 0x05 #define REL_HWHEEL 0x06 #define REL_DIAL 0x07 #define REL_WHEEL 0x08 #define REL_MISC 0x09 #define REL_MAX 0x0f #define REL_CNT (REL_MAX+1) Type為EV_ABS時,code表示絕對座標軸向。

value:根據Type的不同而含義不同。 例如: Type為EV_KEY時,value: 0表示按鍵抬起。1表示按鍵按下。(4表示持續按下等。)。 Type為EV_REL時,value: 表明移動的值和方向(正負值)。 Type為EV_ABS時,code表示絕對位置。

0.2: Device ID 結構體資訊: struct input_id { __u16 bustype; __u16 vendor; __u16 product; __u16 version; };
bustype:  一些枚舉類型。如  USB ,  PCI等。 取值範圍: #define BUS_PCI 0x01 #define BUS_ISAPNP 0x02 #define BUS_USB 0x03 #define BUS_HIL 0x04 #define BUS_BLUETOOTH 0x05 #define BUS_VIRTUAL 0x06
#define BUS_ISA 0x10 #define BUS_I8042 0x11 #define BUS_XTKBD 0x12 #define BUS_RS232 0x13 #define BUS_GAMEPORT 0x14 #define BUS_PARPORT 0x15 #define BUS_AMIGA 0x16 #define BUS_ADB 0x17 #define BUS_I2C 0x18 #define BUS_HOST 0x19 #define BUS_GSC 0x1A #define BUS_ATARI 0x1B #define BUS_SPI 0x1C
vendor, product,version: 廠商號,產品號,版本號碼。


1. 各類ioctl: 1.1:得到Driver Version: #define EVIOCGVERSION _IOR('E', 0x01,  int) int 暗示了ioctl()參數三能夠得到int值。
例: vesion = 0; ioctl(fd, EVIOCGVERSION, &vesion); printf("\nDriver Version:[0x%x]\n", vesion);

1.2:得到Device ID: #define EVIOCGID _IOR('E', 0x02, struct input_id) 從struct input_id暗示,ioctl參數三可以得到此結構體內容。 // 2. Device ID. memset(&Device_ID, 0, sizeof(struct input_id)); ioctl(fd, EVIOCGID, &Device_ID); printf("\nbustype:[%d]. vendor:[%d]. product:[%d]. version:[%d]\n", Device_ID.bustype, Device_ID.vendor, Device_ID.product, Device_ID.version);

1.3: 得到和設定Repeat速度: #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) 從unsigned int[2] 暗示,ioctl的第三個參數是個數組。
int rep[2]; ioctl(fd, EVIOCGREP, rep); printf("[0]= %d, [1] = %d\n", rep[0], rep[1]);
注意,其中一些Device不支援Get Set Repeat。此時,Ioctl會報錯。 另:參數說明:  rep[0] 表示在按鍵重複出現之前  delay 的時間;  rep[1] 表示按鍵重複出現的時間間隔。

1.4:得到ScanKey和KeyMap。 這個功能Sam沒有測試過。所以不具體討論。 #define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) #define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2])

1.5:得到DeviceName: #define  EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) 此處暗示ioctl參數二: EVIOCGNAME(len)
char name[256]= "Unknown"; ioctl(fd, EVIOCGNAME(sizeof(name)), name); printf("\nDevice Name:[%s]. \n", name);

1.6:得到裝置物理位置: #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) //get physical location 此處暗示參數二為: EVIOCGPHYS(len) 儘管裝置身份資訊和名字資訊通常很有用,但是它也許並沒有提供足夠的資訊告訴你當前在使用哪個裝置。例如,你當前有兩個完全相同的遙控杆,你需要確定每個使用哪個連接埠。這通常屬於拓撲資訊(  topology information ),可以使用  EVIOCGPHYS ioctl 擷取:
char physic[256]= "Unknown"; if(ioctl(fd, EVIOCGPHYS(sizeof(physic)), physic) < 0)  { perror("EVIOCGPHYS ioctl"); } else printf("Phys location is %s\n", physic); 結果通常為: Phys location is:  usb-hiusb-ehci-2.1/input1 Phys location is:  usb-hiusb-ehci-2.1/input2 涵義:  Usb 部分意味著這使用  usb 系統的一個物理拓撲。  2.1 表示了從  root hub 到  device 的路徑,這裡表示上行  hub 接在  root hub 的第  2 個連接埠上,裝置接在上行  hub 的第  1 個連接埠上。  Input0 表示這是裝置的第  1 個 event device  節點。

1.7: 得到唯一的ID: #define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) //get unique identifier  此處暗示ioctl()參數二: EVIOCGUNIQ(len)
char uniq[256]= "Unknown"; if(ioctl(fd, EVIOCGUNIQ(sizeof(uniq)), uniq) < 0)  { perror("EVIOCGUNIQ ioctl"); } else printf("UID is %s\n", uniq); 絕大多數裝置沒有這樣的唯一號,所以你使用該 ioctl將返回一個Null 字元串

1.8:得到全域key/button狀態,看其是否被按下或釋放: #define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) 此處暗示 ioctl()參數二是: EVIOCGKEY(len) 通過這個ioctl, 參數三中得到資訊。 它在  bit array 裡設定了每個  key/button 是否被釋放。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.