音声と xdotool でキーボードとマウスのアクションをトリガーする

音声入力と xdotool ライブラリーを組み合わせ、キー入力を取得する

xdotool は、プログラマーがキー入力やマウス・アクションをエミュレートする場合に便利な命令ライブラリーです。キーボードやマウスがない場合や、通常の入力方法を使用することが物理的に不可能なユーザーのためのアクセシビリティーに対応する場合、xdotool は特に力を発揮します。この記事の目的は 2 つあります。1 つは Linux デスクトップ環境での xdotool の使い方を紹介すること、そしてもう 1 つは、通常はハードウェア入力によって行われるアクションを音声入力でトリガーすることです。最終的な例では、自動生成されるダイアログ・マネージャー・コードに xdotool 用のコード・フラグメントを挿入し、そのコード・フラグメントを格納するために XML を使用します。

Colin Beckingham, Writer and Researcher, Freelance

Colin Beckingham はカナダのオンタリオ州東部に住むフリーランスの研究者であり、ライターであり、プログラマーでもあります。キングストンの Queen's University で学位を取得している彼は、園芸、競馬、教育、行政サービス、小売業、旅行/観光業などにも関わってきました。彼はデータベース・アプリケーションの作成者であり、数え切れないほどの新聞記事や雑誌記事、オンライン記事を執筆しており、また Linux でのオープンソース・プログラミングや VoIP、音声制御アプリケーションも研究しています。



2011年 10月 14日

私達の中には、キーボードとマウスによる入力を当然のものと思っている人がいます。つまりキーボードで文字を入力すると、その文字はウィンドウに表示され、一連の文字を入力して Return キーを押すと、ローカルあるいはネットワーク接続されたリモートで何らかのアクションが実行されます。キーボードやマウスを使った入力に、これ以上望むことが何かあるのでしょうか?しかし、キーボードやマウスがない場合や、キーボードやマウスを使用できない場合、そして 1 つのウィンドウでキー入力を行い、その入力によって別のデスクトップ上の別のウィンドウで何かをさせたい場合はどうすればよいのでしょう?あるいは、ウィンドウを作成してリサイズし、そのウィンドウ内でブラウザーを開いて、ある URL にナビゲートし、その Web ページ内のリンクを Tab キーで次々に移動し、最終的に 1 つのリンクをクリックするというすべての動作を、キーボードもマウスも使わずに音声認識ソフトウェアを利用して声で操作したいという場合はどうすればよいのでしょう?こうした動作のためにはキーボードとマウスのエミュレーションが必要になります。

よく使われる頭文字語

  • CDATA: Character DATA
  • URL: Uniform Resource Locator
  • XML: Extensible Markup Language

システム・コールを利用して、これらすべてのタスクを実行することは確かに可能ですが、それではおそらく不便です。そうしようとすると、大部分の開発者が通常使用するレベルよりも下位レベルのコーディングが必要となるからです。音声認識ソフトウェアでは記録されている音声パターンを容易に利用できるように、他のライブラリーを利用することで、Linux デスクトップのウィンドウ機能を利用できるようになります。そこに xdotool が登場します。

xdotool

xdotool (「参考文献」のリンクを参照) はウィンドウ環境への命令の送信を補助する関数のライブラリーです。xdotool は入力されるストリングをリモート・ウィンドウに送信することや、そのウィンドウをリサイズすること、個々のキー入力やキー入力の組み合わせを送信すること、さらにはマウスの右ボタンをダブルクリックすることもできます。しかもリモート・アプリケーションは、それらが間接的に操作されていること (あるいは音声で間接的に操作されていること) を認識しません。xdotool の Web サイトには、make を使用してインストールするための具体的な説明があります。

xdotool コマンドの送信方法は単純です。構文としては、単純に xdotool の後にオプションと引数を続けます。

xdotool search --name 'mytest'

この例では、xdotool は mytest というタイトルを持つウィンドウを検索し、それらのウィンドウの ID 番号を返します。この ID 番号を記録しておくと、後で使用することができます。何らかの基準を持たずにウィンドウを検索すると、意味のない数が延々と続く長いリストが作成される羽目になるので注意してください。

キーやキー入力の組み合わせに使用する名前に関するヒントは xdotool の Web サイトにあります。1 つの小さな落とし穴として、tab は直感的に思えますが、私のシステムでは Tab でないと動作しません。

ターミナル・ウィンドウから 1 度に 1 つずつ xdotool コマンドを発行することは可能ですが、xdotool のインスタンスが終了するたびに内部変数が一部失われるため、1 度 xdotool を呼び出した後、いくつかのオプションと引数を連結した方がより効率的です。

おそらく、以上で説明した内容についての感覚をつかむ最も良い方法は、実際の例を見てみることです。


コンソールを自動化する

リスト 1 は、1 つのターミナル・ウィンドウ (work と呼ぶことにします) を使用して別のターミナル・ウィンドウ (mytest) を開き、この mytest にキー入力を送信するテストを示しています。コマンドは PHP のスクリプトで作成されていますが、これはあくまでも、何が起きているかがわかるようにプロセスの処理速度を遅くするためです。PHP 以外にも、Perl や Python、その他皆さんがお気に入りのスクリプト・エンジンを使用することができます。このスクリプトはいくつものキー入力を定義し、現在実行中のターミナル・ウィンドウに「Trying A (A を試しています)」と表示し (ここで、A はキーを表します)、そのキーを別のターミナル・ウィンドウにも送信します。アクティビティーは両方のターミナル・ウィンドウに同時に表示されます。コードの実行が速すぎて何が起きているかを理解できない場合には、定義されている WAIT 定数の値を大きくしてください。

リスト 1. 2 つのターミナル・ウィンドウを同時に使用する
<?php
// script to test xdotool functionality
define('WAIT',200000);
$charrarray = setca();
$execcmd = "xdotool search --name 'mytest'";
exec($execcmd,$out);
$windowid = $out[0];
if ($windowid) {
  echo "Found window ID ".$windowid."\n";
} else {
  exec('konsole -p LocalTabTitleFormat=mytest');
  $execcmd = "xdotool search --name 'mytest'";
  exec($execcmd,$out);
  $windowid = $out[0];
  // die("Cannot find the window\n");
}
// now activate the window
$execcmd = "xdotool windowactivate --sync $windowid";
exec($execcmd,$out);
// test keys
foreach ($charrarray as $k=>$char) {
  echo "Trying $char \n";
  send_key($k);
}
// functions
function send_string($string) {
  $execcmd = "xdotool type $string";
  exec($execcmd,$out);
  usleep(WAIT);
}
function send_key($key) {
  $execcmd = "xdotool key $key";
  exec($execcmd,$out);
  usleep(WAIT);
}
function send_return() {
  $execcmd = "xdotool key Return";
  exec($execcmd,$out);
  usleep(WAIT);
}
function setca() {
$ca = array(
   "Up" => 'up',
   "Down" => 'down',
   "ampersand" => '&',
   "apostrophe" => '\'',
   "Left" => 'L',
   "Right" => 'R',
   "asciicircum" => '^',
   "asciitilde" => '~', 
   "asterisk" => '*',   
   "at" => '@',
   "backslash" => '\\',
   "bar" => '|',
   "braceleft" => '{',
   "braceright" => '}',
   "bracketleft" => '[',
   "bracketright" => ']',
   "colon" => ':',
   "comma" => ',',
   "dollar" => '$',
   "equal" => '=', 
   "exclam" => '!',
   "grave" => '`', 
   "greater" => '>',
   "less" => '<',   
   "minus" => '-',  
   "numbersign" => '#',
   "parenleft" => '(', 
   "parenright" => ')',
   "percent" => '%',   
   "period" => '.',    
   "plus" => '+',      
   "question" => '?',  
   "quotedbl" => '"',  
   "semicolon" => ';', 
   "space" => ' ',
   "BackSpace" => 'bs',
   "Tab" => '\t', 
   "underscore" => '_',
   "slash" => '/', 
   "eacute" => 'eac', 
   "ccedilla" => 'cced', 
   "udiaeresis" => 'uum', 
   "idiaeresis" => 'ïdi', 
   "Home" => '<',
   "End" => '>',
   "Return" => '\n'
);
return $ca;
}
?>

このスクリプトでは、まずグローバル・スコープを持つ WAIT 定数を定義します。この定数によって関数の実行速度が遅くなり、何が起きているかがわかるようになります。続いて、テスト対象のキー入力を配列に追加します。もちろん、完全なリストはリスト 1 よりもはるかに長くなります。このサンプルには、多くの標準的な文字に加え、いくつか見慣れない文字の組み合わせが含まれています。次に xdotool は mytest というタイトルのウィンドウを検索します。見つからない場合には、PHP はウィンドウのタイトルを指定するパラメーターを持つ konsole 命令を実行し、そのウィンドウを作成します。

exec('konsole -p LocalTabTitleFormat=mytest');

新しいウィンドウを作成した後、xdotool による検索を再び行い、そのウィンドウの ID を番号として持つグローバル変数を設定します。こうすることで、その後のコマンドは確実に適切な宛先に送信されるようになります。ウィンドウが用意されると、スクリプトはそのウィンドウをアクティブにし、テスト対象である文字列の配列に対してループ処理を開始します。スクリプトは各ループで、特定の 1 文字を試しているという内容を作業コンソールに出力した後、その文字をターゲット・ウィンドウに表示します。

xdotool の引数とオプションの組み合わせが適切であることを確認できると、xdotool のチェーニング機能とスクリプト作成機能を利用することで、省略形式のメリットが得られるようになります。完全に診断を制御する必要があるけれども、何を使えばよいかがわからない場合、この PHP によるベースが役に立ちます。


テキスト・ブラウザーを自動化する

リスト 1 はキーの名前をテストできるという意味で生産的ですが、インターネットから情報を取得できるようになると、さらに生産的になります。リスト 2 の例は、新しいウィンドウを開いて Lynx テキスト・ブラウザーのインスタンスを起動し、www.ibm.com という Web サイトにナビゲートします。

リスト 2. Lynx を自動化する
<?php
// script to test xdotool functionality
// first get the window to launch lynx
define('WAIT',200000);
$winname = 'mylynx';
$execcmd = "xdotool search --name $winname";
exec($execcmd,$out);
$windowid = $out[0];
if ($windowid) {
  echo "Found window ID ".$windowid."\n";
} else {
  exec("konsole -p LocalTabTitleFormat=$winname");
  exec($execcmd,$out);
  $windowid = $out[0];
  // die("Cannot find the window\n");
}
// now activate the window
$execcmd = "xdotool windowactivate --sync $windowid";
exec($execcmd,$out);
$execcmd = "xdotool getactivewindow windowsize --sync 750 750";
exec($execcmd,$out);
// start sending stuff
send_string("lynx");
send_return(); // opens lynx browser
send_key("g"); // get URL prompt
send_string("www.ibm.com"); 
send_return(); // send a URL
function send_string($string) {
  $execcmd = "xdotool type $string";
  exec($execcmd,$out);
  usleep(WAIT);
}
function send_key($key) {
  $execcmd = "xdotool key $key";
  exec($execcmd,$out);
  usleep(WAIT);
}
function send_return() {
  $execcmd = "xdotool key Return";
  exec($execcmd,$out);
  usleep(WAIT);
}
?>

リスト 2 のコードはリスト 1 と似ています。少し処理を遅らせるための待機期間を定義した後、(上記の mytest との混同を避けるために) mylynx というウィンドウを検索し、そのウィンドウの ID を後で使用できるように保存し、そのウィンドウをアクティブにしてリサイズし、そのウィンドウの中で Lynx のインスタンスを初期化しています。続いて、URL が次に来ることを Lynx に伝える g のキー入力をそのウィンドウに送信し、その後に www.ibm.com というストリングと Return キーを続けて送信しています。これで www.ibm.com の Web サイトが開き、さらなるコマンド (TabReturn など) を受信できるようになり、この Web サイトをナビゲーションできるようになります。

なぜ自動化の対象とするアプリケーションとして Lynx を選んだのでしょう。他のブラウザーやアプリケーションを自動化しようとすると、自動化されたキー入力の一部が無視される場合があります。この問題の根源はクロスサイト・スクリプティングに対する防御にあります。Lynx は、例えば Mozilla Firefox に比べ、エミュレートされたキー入力を若干多く許容するようです。皆さんの好みは私とは異なるかもしれません。


音声で自動化する

すべてが動作するようになり、間接的なキー入力を使用した自動操作がいかに容易であるかを理解できると、他の機器から入力することはできないのだろうか、という考えが浮かんできます。それを実現する 1 つの方法が音声です。適切な学習を行った音声モデルを使用した音声認識プロセスは、言葉による命令を理解することができ、xdotool を使用してコマンドを実行することができます。xdotool と VoxForge 音声モデルを使用した既製のアプリケーションが必要な場合には、Ubuntu に含まれている kiku (詳細な情報へのリンクは「参考文献」を参照) について調べてみてください。


xdotool とダイアログ・マネージャー

リスト 3 のサンプル・コードはダイアログ・マネージャーで xdotool を使用する方法を示しています。

リスト 3. ダイアログ・マッパーで xdotool を使用する
<?php
...
function process($major,$minor) {
global $globalcontext;
  switch ($major) {
    case 'CONTEXT':
      switch ($minor) {
	case 'SOFTWARE':
	  $globalcontext = $minor;
	  echo "Set global context to software\n";
	break;
	default:
	  echo "Defaulted out $minor\n";
	break;
      }
    break;
    case 'BROWSER':
      $ooc = ($globalcontext == 'SOFTWARE') ? true : false ;
      if ($ooc) {
	switch ($minor) {
	  case 'OPEN':
	    echo "Open browser\n";
	    browser_open();
	  break;
	  case 'CLOSE':
	    echo "Close browser\n";
	    browser_close();
	  break;
	  case 'LOCATION':
	    echo "Go to URL\n";
	    browser_location();
	  break;
	  default:
	    echo "Defaulted out $minor\n";
	  break;
	}
      } else {
	// OOC
	echo "Recognized but out of context\n";
      }
    break;
    default:
	  echo "Defaulted out $major\n";
    break;
  }
}
function browser_open() {
global $windowid;
  $winname = 'mylynx';
  $execcmd = "xdotool search --name $winname";
  exec($execcmd,$out);
  $windowid = $out[0];
  if ($windowid) {
    echo "Found window ID ".$windowid."\n";
  } else {
    exec("konsole -p LocalTabTitleFormat=$winname");
    $execcmd = "xdotool search --name $winname";
    exec($execcmd,$out);
    $windowid = $out[0];
    echo "Using windowid $windowid";
    // die("Cannot find the window\n");
  }
  // now activate the window
  $execcmd = "xdotool windowactivate --sync $windowid";
  exec($execcmd,$out);
  $execcmd = "xdotool getactivewindow windowsize --sync 800 800";
  exec($execcmd,$out);
  // start sending stuff
  send_string("lynx");
  send_return(); // opens lynx browser
}
...
  ?>

リスト 3 は 2 つの関数を示しています。最初の関数は process() であり、この関数は 2 つの引数を想定しています。これらの引数は音声認識プロセスから返されるストリングです。これらのストリングを取得するプロセスの詳細は VoxForge または Sphinx のチュートリアルを参照してください (「参考文献」のリンクを参照)。この場合、想定されるストリングは CONTEXT SOFTWAREBROWSER OPEN という命令が含まれる文法から抽出されます。

このプロセスを追い、CONTEXT SOFTWARE と読み上げられたことを音声認識プロセスが認識した場合に何が起こるかを考えてみてください。メジャー・ストリングは CONTEXT であり、マイナー・ストリングは SOFTWARE です。Process() 関数はコンテキストが格納されているグローバル変数へのアクセスを宣言し、そして switch 文の中でコンテキスト変数を SOFWARE に設定します。この変数はグローバルです。そのため、後でメジャー・ストリングとマイナー・ストリングのセットとしての BROWSER OPEN を音声認識プロセスが認識すると switch 文でそれを処理しますが、switch 文では最初にそのコンテキストが適切かどうかを検証します。なぜコンテキストを使用するかというと、音声認識プロセスから不適切な結果が返された場合、その不適切な結果を破棄するためです。例えば、コンテキストが SOCCER の場合、SOCCER のコンテキストでブラウザーを開くことは適切でないと考えられる場合には、ブラウザーは開きません。

コンテキストが適切な場合には、BROWSER OPEN コマンドによって browser_open() 関数が呼び出されます。この browser_open() 関数のコードがリスト 2 に使用されたものと基本的に同じであることは、すぐに理解できると思います。

コンテキスト管理が複雑になればなるほど、そのコンテキスト管理構造を忠実に再現するルールとして他の場所で定義されたルールに従う switch 文を作り出す手法が必要になります。これらのルールを定義する方法には何通りもの方法があります。1 つの方法は、Speech Recognition Grammar Specification と Semantic Interpretation for Speech Recognition による構造を使用する方法です (詳細については「参考文献」のリンクを参照)。それよりも少し単純な方法として、必要なコード・フラグメント (xdotool 命令を含む) を XML 構造に格納する方法があります。


XML を使用してコンテキストとコード・フラグメントを格納する

リスト 4 の XML ファイルには、架空のダイアログ・マネージャーのビルディング・ブロックの詳細が記述されています。フラットで編集可能な XML ファイルのメリットとして、すべてのコンテキストと関数を同じファイルの中に表現することができます。コンテキストと関数はダイアログ・マネージャーの複雑な switch 文のコードから分離されているため、コンテキスト構造を容易に見たり編集したりすることができます。このデータには、マウス・カーソルがどこにあっても左クリックを実行する 1 つの xdotool 命令が含まれています。このコマンドはすべてのコンテキストで有効であるため、このコマンドには ctxt 属性がありません。

リスト 4. XML ストア
<?xml version="1.0" encoding="UTF-8"?>
<snips>
  <context>
    <func>click_left</func> 
    <func ctxt="software">browser_open</func>    
    <func ctxt="software">browser_location</func>    
    <func ctxt="software">browser_close</func>    
    <func ctxt="hardware">cpu_temperature</func>    
    <func ctxt="hardware">fan_speed</func>    
  </context>
  <snip fn="click_left">
<![CDATA[
function click_left() {
  exec('xdotool click 1');
}
]]>
  </snip>
  <snip fn="cpu_temperature">
<![CDATA[
function cpu_temperature() {
  $g = 0;
}
]]>
  </snip>
  <snip fn="fan_speed">
<![CDATA[
function fan_speed() {
  $g = 1;
}
]]>
  </snip>
  <snip fn="browser_open">
<![CDATA[
function browser_open() {
  $f = 0;
}
]]>
  </snip>
  <snip fn="browser_location">
<![CDATA[
function browser_location() {
  $f = 1;
}
]]>
</snip>
  <snip fn="browser_close">
<![CDATA[
function browser_close() {
  $f = 2;
}
]]>
</snip>
</snips>

このコードでは、ルート要素は snips です。この要素には以下の 2 つのタイプの子があります。

  • コンテキスト情報を持つ context 要素
  • コード・フラグメントを含む、いくつかの snip 要素

context 要素には func 要素が含まれており、各 func 要素には、要素の値としての関数の名前と、その関数が有効となるコンテキストを含む ctxt 属性があります。つまり、コンテキストが software に設定された場合には、関数 fan_speed は有効になりません。しかし関数 click_left にはコンテキストがないため、関数 click_left はどこででも有効です。コード・スニペットは CDATA セグメントに格納されます。こうすることで、XML パーサーは必ず CDATA セクションの構文解析をスキップし、内部に含まれるコードとは無関係に CDATA セクションを受け付けます。

ここまで来れば、あとはダイアログ・データを拡張して独自のスクリプトにするためのスクリプトを作成するだけです。それがリスト 5 の PHP コードです。

リスト 5. ダイアログ・マネージャー生成プログラム
<?php
// pull DM structure from an xml file
$xml = simplexml_load_file('snipstor.xml');
// get the contexts
// generate the main switch
echo "function process(\$major,\$minor) {\n";
echo "global \$globalcontext;\n";
echo "  switch (\$major) {\n";
$majtmp = "";
$mintmp = "";
foreach ($xml->context->func as $mjmn) {
  list($major,$minor) = explode("_",$mjmn);
  //echo "$major,$minor\n";
  if ($major != $majtmp) {
    if ($majtmp != "") echo "      default:
      echo \"Failed \$minor\";
      break;
      }\n    } else {
      echo 'OOC';\n    }\n";
    echo "  case '$major':\n";
    if ($minor != $mintmp) {
      $test = ($mjmn['ctxt']) ? "\$globalcontext == '".$mjmn['ctxt']."'" : 'true' ;
      echo "    if ($test) {\n";
      echo "      switch (\$minor) {\n";
      $mintmp = $minor;
    }
    echo "      case '$minor':
        $mjmn();
      break;\n";
    $majtmp = $major;
  } else {
    echo "      case '$minor':
      break;\n";
  }
}
echo "      default:
      echo \"Failed \$minor\";
      break;
      }\n    } else {
      echo 'OOC';\n    }\n";
echo "  default:
    echo \"Failed \$major\";
  break;
  }\n";
echo "}\n";
// generate the code snippets
echo "// functions\n";
foreach ($xml->snip as $snipfn) {
  echo trim($snipfn);
  echo "\n";
}
?>

リスト 5 のコードでは、ダイアログ・マネージャーに追加することができる PHP コードを作成しています。まず、snipstor.xml というファイルに格納されたリスト 4 のダイアログ・マネージャーの構造を SimpleXML 変数の中に読み込みます。次に、context 要素の中にある関数名を読み取り、これらの名前からメジャー・コンポーネントとマイナー・コンポーネントを抽出し、それらのコンポーネントを使用して、ダイアログ・マネージャーのフローを制御する switch 文を作成します。このスクリプトはコードを作成する中で、そのコマンドが有効となるコンテキストを (ctxt 属性から) 検索します。そして switch case 文に適用される可能性があるどんなコンテキストでも扱えるように if 条件文を挿入します。コンテキストがある場合には、そのコンテキストは実行時に評価される式として挿入されます。コンテキストがない場合には、CDATA に含まれている文が必ずプログラムによって実行されるように、単純に true を挿入します (つまりそのコマンドはすべてのコンテキストで有効です)。最後に、このスクリプトは switch case 文に必要なコード・ライブラリーを出力します。

リスト 4 に含まれるデータに対してリスト 5 のコードを実行した結果をリスト 6 に示します。

リスト 6. 結果として生成されたダイアログ・マネージャーの抜粋
function process($major,$minor) {
global $globalcontext;
  switch ($major) {
  case 'click':
    if (true) {
      switch ($minor) {
      case 'left':
        click_left();
      break;
      default:
      echo "Failed $minor";
      break;
      }
    } else {
      echo 'OOC';
    }
  case 'browser':
    if ($globalcontext == 'software') {
      switch ($minor) {
      case 'open':
        browser_open();
      break;
      case 'location':
      break;
      case 'close':
      break;
      default:
      echo "Failed $minor";
      break;
      }
    } else {
      echo 'OOC';
    }
  case 'cpu':
    if ($globalcontext == 'hardware') {
      switch ($minor) {
      case 'temperature':
        cpu_temperature();
      break;
      default:
      echo "Failed $minor";
      break;
      }
    } else {
      echo 'OOC';
    }
  case 'fan':
    if ($globalcontext == 'hardware') {
      switch ($minor) {
      case 'speed':
        fan_speed();
      break;
      default:
      echo "Failed $minor";
      break;
      }
    } else {
      echo 'OOC';
    }
  default:
    echo "Failed $major";
  break;
  }
}
// functions
function click_left() {
  exec('xdotool click 1');
}
function cpu_temperature() {
  $g = 0;
}
function fan_speed() {
  $g = 1;
}
function browser_open() {
  $f = 0;
}
function browser_location() {
  $f = 1;
}
function browser_close() {
  $f = 2;
}

この出力は、出発点であったリスト 3 と似ています。CDATA の実際の内容は有効なコードですが、単純にするために省略してあります。OOC とは単に Out of Context (コンテキスト外) を省略しただけです。このメッセージが表示されるのは、音声認識プロセスが有効な音声を認識したものの、その音声は snipstor.xml ファイルの構造に従うと意味をなさない場合です。この例をもっと意味のあるものにするには、browser_open() 関数の CDATA セクションをリスト 3 の browser_open() 関数のコードで置き換えます。


まとめ

この記事からわかるように、xdotool はウィンドウ・システムを呼び出すための便利なライブラリーです。音声認識プロセスと組み合わせると、ダイアログ・マネージャーによる制御の下で、音声を使って xdotool コマンドを実行することができます。そして最後に、コンテキストが複雑な場合、ダイアログ・マネージャーは非常に複雑で扱いにくいものになる可能性があるため、xdotool 命令を含むコード・フラグメントを便宜上 XML の CDATA セクションに格納して使用することで、一貫性のある効果的な方法でダイアログ・マネージャーを生成することができます。

参考文献

学ぶために

製品や技術を入手するために

  • xdotool: xdotool をダウンロードし、xdotool の設定方法や、xdotool を使用してキーボード入力やマウス・アクティビティーをシミュレートする方法、ウィンドウの移動方法やリサイズ方法などを学んでください。
  • kiku: kiku 音声認識プロセスとダイアログ・マネージャーについて学ぶとともに、音声認識プロセスを使用してオペレーティング・システムを制御する方法についても学んでください。
  • Lynx ソース・ディストリビューション・ディレクトリー: Lynx Web ブラウザーをダウンロードし、ユーザー・ガイドとヘルプ・ページで Lynx Web ブラウザーについて学んでください。
  • IBM 製品の評価版: IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、および WebSphere が提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Linux, Open source
ArticleID=764895
ArticleTitle=音声と xdotool でキーボードとマウスのアクションをトリガーする
publish-date=10142011