= /dev/inputについて = Linuxではキーボード・マウス等のデバイスを/dev/input以下にある デバイスファイル経由で操作することができます。 まずは利用可能なデバイスの一覧を表示するには {{{ ~% cat /proc/bus/input/devices I: Bus=0011 Vendor=0001 Product=0001 Version=ab54 N: Name="AT Translated Set 2 keyboard" P: Phys=isa0060/serio0/input0 H: Handlers=kbd event0 B: EV=120013 B: KEY=4 2000000 3802078 f840d001 f2ffffdf ffefffff ffffffff fffffffe B: MSC=10 B: LED=7 I: Bus=0011 Vendor=0002 Product=0001 Version=0000 N: Name="PS/2 Generic Mouse" P: Phys=isa0060/serio4/input0 H: Handlers=mouse0 event1 B: EV=7 B: KEY=70000 0 0 0 0 0 0 0 0 B: REL=3 I: Bus=0003 Vendor=054c Product=0270 Version=0110 N: Name="SONY SONY Mouse" P: Phys=usb-0000:00:1d.0-1/input0 H: Handlers=mouse1 event2 B: EV=f B: KEY=70000 0 0 0 0 0 0 0 0 B: REL=103 B: ABS=100 0 }}} これをみると、 {{{ event0 : キーボード event1 : PS/2 マウス....これはノートPCのタッチパッドのこと event2 : 外付けUSBマウス(Sony製) }}} の3つのデバイスが接続されていて、それぞれのイベントを取得 できることが分かります。 rootになってから {{{ # cat /dev/input/event1 | od -t x1 }}} とやってやり、イベントコードを取得してみます。 この状態でマウスパッドをたたくと {{{ 0000000 cc 80 c7 44 84 81 05 00 01 00 10 01 01 00 00 00 0000020 cc 80 c7 44 8c 81 05 00 00 00 00 00 00 00 00 00 0000040 cc 80 c7 44 ed f6 07 00 01 00 10 01 00 00 00 00 0000060 cc 80 c7 44 f4 f6 07 00 00 00 00 00 00 00 00 00 }}} マウスを動かすと {{{ 0000000 11 81 c7 44 4f 5e 04 00 02 00 01 00 01 00 00 00 0000020 11 81 c7 44 59 5e 04 00 00 00 00 00 00 00 00 00 0000040 11 81 c7 44 96 10 08 00 02 00 01 00 01 00 00 00 0000060 11 81 c7 44 a2 10 08 00 00 00 00 00 00 00 00 00 }}} 等と表示されます。 イベントコードは /usr/src/kernels/2.6.9-34.0.2.EL-i686/include/linux/input.h で定義されており、 {{{ struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; }; }}} の形になっているので、先ほどのデータは {{{ 0000000 11 81 c7 44 4f 5e 04 00 02 00 01 00 01 00 00 00 0000020 11 81 c7 44 59 5e 04 00 00 00 00 00 00 00 00 00 ======================= ===== ===== =========== time type code value }}} となっていることが分かる。当然ですがLittle Endianですね。 おまけ: {{{ int main (int argc, char *argv[]) { printf("sizeT : %d\n", sizeof(struct timeval)); printf("u16 : %d\n", sizeof(__u16)); printf("u32 : %d\n", sizeof(__s32)); return 0; } }}} input.hファイルにtype,codeについて書いてあり、 {{{ /* * Event types */ #define EV_SYN 0x00 #define EV_KEY 0x01 #define EV_REL 0x02 }}} となっているので、キーボード入力はEV_KEY, マウスはEV_RELというタイプ。 さて、次にPowerMateを挿してみましょう。 {{{ ~% cat /proc/bus/input/devices I: Bus=0003 Vendor=077d Product=0410 Version=0321 N: Name="Griffin PowerMate" P: Phys= H: Handlers=event3 B: EV=17 B: KEY=1 0 0 0 0 0 0 0 0 B: REL=80 B: MSC=2 }}} event3を監視します。 {{{ [root@obinalx obina]# cat /dev/input/event3 | od -t x1 右回し 0000000 1d 8c c7 44 dd 5b 09 00 02 00 07 00 01 00 00 00 0000020 1d 8c c7 44 df 5b 09 00 00 00 00 00 00 00 00 00 左回し 0000040 1f 8c c7 44 71 4d 06 00 02 00 07 00 ff ff ff ff 0000060 1f 8c c7 44 73 4d 06 00 00 00 00 00 00 00 00 00 ボタン Press 0000100 21 8c c7 44 f8 33 0a 00 01 00 00 01 01 00 00 00 0000120 21 8c c7 44 fa 33 0a 00 00 00 00 00 00 00 00 00 ボタン Release 0000140 23 8c c7 44 ed d4 09 00 01 00 00 01 00 00 00 00 0000160 23 8c c7 44 f0 d4 09 00 00 00 00 00 00 00 00 00 }}} type,code,valueのところだけ16進表記にすると {{{ type=0x0002, code=0x0007, value=1 type=0x0000, code=0x0000, value=0 type=0x0002, code=0x0007, value=-1 type=0x0000, code=0x0000, value=0 type=0x0001, code=0x0100, value=1 type=0x0000, code=0x0000, value=0 type=0x0001, code=0x0100, value=0 type=0x0000, code=0x0000, value=0 }}} type,code,value全て0が返ってきている行はEV_SYNなので、今は気にしないことにする。 {{{ 右回し : type=2, code=7, value=1 左回し : type=2, code=7, value=-1 ボタン Press : type=1, code=256, value=1 ボタン Release ; type=1, code=256, value=0 }}} (前述の通り、type=2はEV_REL, type=1はEV_KEY) codeは {{{ EV_REL に対しては #define REL_DIAL 0x07 EV_KEY に対しては #define BTN_MISC 0x100 }}} PowerMateを操作したときのイベントはEV_RELとEV_KEYのみ。 どうやら プログラム側からLED設定を変える場合にはEV_MSCが発生するらしいので、これは後で 確認したい。