wiki:epics/powermate-event

Version 1 (modified by obina, 12 years ago) (diff)

--

/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が発生するらしいので、これは後で 確認したい。