入力をとらえる

ライフゲームでは、プログラム上で指定した初期値から動きつづけるプログラムでしたが、実際に遊べるゲームを作るには、ユーザからの入力をとらえる必要があります。


ユーザ空間からキーボードやマウスの入力をとらえるには、/dev/経由で読み出したりする必要がありますが、Systemtapならカーネル内部で発生したイベントを直接読み取ることが可能です。

キーボードやマウスなどの入力デバイスのイベントは、2.6カーネルではdrivers/input/input.cのinput_event()関数が受け取っています。この関数をプローブすれば、入力イベントを取得できるというわけです。

probe kernel.function("input_event") {
  type = $type
  code = $code
  value = $value
  printf("type:%d code:%x value:%x\n", type, code, value)
}

typeはイベントの種類(キー、マウス移動、など)を、codeはイベントの内容(キーボードのどのボタンか、マウスがどちらに動いたか、など)を、valueはイベントの値(キーが押下されたかどうか、マウスの移動量、など)を示しています。
これらの詳しい値については、include/linux/input.hに記述があります。

キーボードとマウスを具体的にとらえるプローブの定義は、以下のようになります。

probe keyboard = kernel.function("input_event"){
  if ($type != 1 || $code >= 256) next;
  code = $code
  down = $value
}

probe mouse.move =  kernel.function("input_event") {
  if($type != 2) next #EV_REL
  if($code == 0) dx = value
  else if($code == 1) dy = value
  else if($code == 8) dz = value
}

probe mouse.btn = kernel.function("input_event") {
  if ($type != 1 || ($code & 0xfe0) != 0x100) next #EV_KEY
  button = $code & 0xf
  down = $value
}
  • keyboardプローブは、キーコードの値がcodeに、押下状態がdownに入るようになっています。
  • mouse.moveプローブは、マウスのx,y,z(zはホイール)移動量がdx,dy,dzに入るようになっています。
  • mouse.btnプローブは、ボタンの番号(0=左、1=右、2=真ん中、その他マウスの種類に応じます)がbutton、押下状態がdownに入るようになっています。

これで、基本的な入力はカバーできるようになりました。