モニターの追加ほど、作業環境の生産性に劇的な変化をもたらすものはありません。オープンソースの Synergy パッケージには、追加のハードウェアを購入しなくても多くのモニターをリンクさせることができる、素晴らしい方法が用意されています。
複数画面による表示システムでは、従来の単一画面によるセットアップとは異なり、ユーザー・インターフェースに関して特別な考慮が必要です。この記事では、複数のモニターを使用する際に、どのモニターに入力フォーカスが置かれているかという情報を取得したり、入力フォーカスの切り換えに対処したりといったことができるように設計されたツールとコードについて説明します。X Window システムによる既存のフォーカス情報を Ghosd による表示と Synergy のデバッグ・レベル出力を利用して強化することで、たとえ 4200x3150 ピクセル以上が複数のモニターに表示されている場合であっても、複数画面のユーザーは入力フォーカスがどこにあるのかを正確に知ることができます。
Synergy は広範な種類のハードウェアやソフトウェアで動作するように設計されています。アニメーションによる視覚効果、またはアルファ・ブレンドを多用する視覚効果を Ghosd によって実現したい場合には特に、高速ネットワークを推奨します。
Synergy の基本的な機能はさまざまなオペレーティング・システムでサポートされていますが、この記事では Linux® サーバー上で Ghosd を使用することで、機能強化した OSD (on-screen display) を提供しています。Synergy の世界では、サーバーと言えば、マスターまたは共有のキーボードとマウスを持ち、主画面を持ち、そして Synergy のサーバー・ソフトウェアが実行されているコンピューターのことを指しています。他のコンピューターはすべて Synergy クライアントであり、そして Synergy のクライアント・ソフトウェアを実行します。この記事を読み進める上で必要なものは次の通りです。
- Synergy
- Synergy を利用すると、それぞれ独自のモニターを持ち、さまざまなオペレーティング・システムを実行する複数のコンピューターの間で、特別なハードウェアを使わずに 1 つのマウスとキーボードを共有することができます。
- X Window システム
- この記事で説明する結果を得るためには、Synergy のサーバーとクライアントで Linux® 用または Linux 互換 OS 用の X Window システム・サーバーが実行されている必要があります。Linux または UNIX® を実行するデスクトップ・コンピューターの大部分には X Window システムがインストールされているため、Linux マシンまたは UNIX マシンであれば既に X Window システムがインストールされていると考えても問題ありません。
- Pango
- Pango はテキストの配置や描画のためのライブラリーです。
- GLib ライブラリー
- Pango は GLib ライブラリーの V2.x シリーズに依存しています (GLib ライブラリーは GTK+ Project から入手することができます)。
- Cairo
- Cairo は 2D のグラフィック・ライブラリーであり、さまざまな出力機器をサポートしています。
- Ghosd
- Ghosd は効果的な方法で画面に情報を表示するためのライブラリーです。
- Perl
- Perl は安定したクロスプラットフォームのプログラミング言語です。
Ubuntu のユーザーの場合は、コマンド sudo apt-get install libgtk2.0-dev libpango1.0-dev libcairo2-dev perl synergy を使えば上記の大部分をインストールすることができます。
6 つの画面による Synergy のセットアップを考えてみてください (図 1)。この写真は、フォーカスのある画面とない画面とを識別する機能を示しています (この機能は後ほど示すコードの最終バージョンで実現されます)。例えば皆さんが複数画面のセットアップ作業から離れて数分間別の仕事をしてみると、どの画面のどこにカーソルを置いたかを忘れてしまいがちなことに気付くはずです。図 1 を見ると、フォーカスのあるモニターには緑色で何重かの四角が表示されており、他のモニターには赤い枠がフェードアウト効果付きで表示されています。この先では、この視覚効果を得るための方法を説明します。まず、フォーカスを追跡するための機能について説明します。
図 1. 6 つの画面による構成での視覚効果の例
「ダウンロード」セクションにあるファイルを調べ、Ghosd のソース・コード・アーカイブを探してください。Synergy サーバーとして使うつもりのマシンに Ghosd のソース・コードをダウンロードします。Ghosd のコード・アーカイブを、コマンド bzip2 -d ghosd-0.0.1.tar.bz2 -c | tar -xvf - を使って解凍します。おなじみのコマンド ./configure; make && make install を実行し、Ghosd のソース・ファイルとサンプル・ファイルをビルドします。ビルドとインストールが成功すると、第 1 の視覚効果、つまりフォーカスがある場所を示す (緑色の何重かの四角を表示する) ための作業準備が整ったことになります。
カレント・ディレクトリーを examples/ に変更し、コマンド mv animation.c original.animation.c を使って animation.c ファイルをリネームします。そして、animation.c という新しいファイルを作成し、そのファイルにリスト 1 のコードをコピーします。
リスト 1.
animation.c のヘッダー部分と round_rect 関数
// animation.c - modified ghosd example for Synergy focus designation
// borrows heavily from the ghosd animation.c example file
#include <stdio.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <time.h>
#include <cairo/cairo.h>
#include <ghosd/ghosd.h>
#define RADIUS 20
int sizeX = 1024;
int sizeY = 768;
int mode = 0; // 0 is alpha blended red border box, 1 is green boxes
typedef struct {
cairo_surface_t* foot;
float alpha;
} RenderData;
static void
round_rect(cairo_t *cr, int x, int y, int w, int h, int r) {
cairo_move_to(cr, x+r, y);
cairo_line_to(cr, x+w-r, y); /* top edge */
cairo_curve_to(cr, x+w, y, x+w, y, x+w, y+r);
cairo_line_to(cr, x+w, y+h-r); /* right edge */
cairo_curve_to(cr, x+w, y+h, x+w, y+h, x+w-r, y+h);
cairo_line_to(cr, x+r, y+h); /* bottom edge */
cairo_curve_to(cr, x, y+h, x, y+h, x, y+h-r);
cairo_line_to(cr, x, y+r); /* left edge */
cairo_curve_to(cr, x, y, x, y, x+r, y);
cairo_close_path(cr);
}
|
コンポーネントをインクルードし、変数を宣言した後、Ghosd の examples/animation.c ファイルの内容をそのまま借用して round_rect 関数を定義しています。round_rect 関数はフォーカスがあることを示す視覚効果とフォーカスがないことを示す視覚効果の両方に対して強調機能を提供します。次に、下記の renderFocus 関数を追加します。
リスト 2.
renderFocus 関数
static void
renderFocus(Ghosd *ghosd, cairo_t *cr, void* data) {
RenderData *rdata = data;
// draw three squares to indicate focus
cairo_set_line_width( cr, 20);
cairo_set_source_rgba(cr, 0, 1, 0, rdata->alpha);
cairo_new_path(cr);
round_rect(cr, 10, 10, 380, 380, RADIUS);
cairo_stroke(cr);
cairo_set_source_rgba(cr, 0, 1, 0, rdata->alpha);
cairo_new_path(cr);
round_rect(cr, 40, 40, 320, 320, RADIUS);
cairo_stroke(cr);
cairo_set_source_rgba(cr, 0, 1, 0, rdata->alpha);
cairo_new_path(cr);
round_rect(cr, 70, 70, 260, 260, RADIUS);
cairo_stroke(cr);
cairo_set_source_surface(cr, rdata->foot, 0,0);
}//renderFocus
|
ある画面にフォーカスが移ると、renderFocus 関数はその画面の描画スペース上の一部の領域に、角の丸い 3 重の四角を描画します。リスト 3 は renderFocus 関数を呼び出すためのメイン・プログラム・ロジックです。
リスト 3.
animation.c のメイン・ロジック
int main(int argc, char* argv[]) {
Ghosd *ghosd;
RenderData data = {0};
struct timeval tv_nextupdate;
const int STEP = 50;
float dalpha = 0.10;
if( argc == 4 )
{
sizeX = atoi( argv[1] );
sizeY = atoi( argv[2] );
mode = atoi( argv[3] );
}
ghosd = ghosd_new();
if( mode == 0 )
{
// create a small canvas and draw the green focus boxes
data.foot = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 400,400);
data.alpha = 1;
ghosd_set_position(ghosd, (sizeX/2)-200, (sizeY/2)-200, 400, 400);
ghosd_set_render(ghosd, renderFocus, &data);
ghosd_render(ghosd);
ghosd_show(ghosd);
ghosd_main_iterations(ghosd);
}//if focus mode
// ghosd_flash is not ideal for this example, so fade out quickly and exit
for (;;)
{
gettimeofday(&tv_nextupdate, NULL);
tv_nextupdate.tv_usec += STEP*1000;
ghosd_main_until(ghosd, &tv_nextupdate);
data.alpha -= dalpha;
if (data.alpha <= 0.3) { return(0); }
ghosd_render(ghosd);
}//for each step fade out
}//main
|
このメイン・ループも Ghosd の examples/animation.c ファイルから大幅に借用しており、400x400 でアルファ・ブレンドした領域を作り出します。そしてこの領域は画面の解像度にかかわらず画面の中心に配置され、各描画パスの間に renderFocus 関数が呼び出されるように指定されています。
ghosd_flash にはテキストのフェードイン、フェードアウトに便利なインターフェースが用意されていますが、この記事での視覚効果には単純なフェードアウトの方が適切です。そこで for ループによってパスごとにアルファ・ブレンドの量を減らすことで効果的なフェードアウトを行い、そしてプログラムが終了します。
このファイルをビルドするためには、make コマンドを実行し、続いてコマンド ./animation 1400 1050 0 を実行します。画面の解像度が 1400x1050 だとすると、画面の中央に緑色で何重かの四角が表示されるはずです。
視覚効果が作成できたら、今度は Synergy の構成を利用して、現在フォーカスのある画面上にその視覚効果を表示します。Synergy にはこの作業に最適な何種類ものデバッグ・レベル出力が用意されているため、比較的容易に作業を行うことができます。
processSynergy.pl というファイルを、まずリスト 4 に示す内容から作成します。
リスト 4. processSynergy.pl 変数のメイン・ループ
#!/usr/bin/perl -w
# processSynergy.pl - read Synergys DEBUG2 events
use strict;
my %disp = (); # record display geometries, focus states
my $delay = 5; # time in seconds
my $inTimeout = 0; # timeout mode switcher
my $osdOn = 0; # on screen display switcher
my $lastTime = time; # monitor last activity
while( my $line = <STDIN> )
{
$line =~ s/"//g;
if( $line =~ /404: received client / )
{
# client connection geometry recording an initial setup
my @parts = split " ", $line;
my $name = $parts[4];
$disp{$name}{mode} = 1;
$disp{$name}{X} = (split "x", $parts[7])[0];
$disp{$name}{Y} = (split "x", $parts[7])[1];
print "$name geometry $parts[7]\n";
|
このプログラムは変数を宣言した後 (大部分の変数は後でフォーカスのタイムアウトをチェックするために使われます)、STDIN での Synergy イベントをリッスンするループに入ります。最初の if 文はクライアントの接続に関するメッセージを処理し、また各モニターの情報を %disp hash に追加します。リスト 5 は「フォーカス切り換え」メッセージをリッスンします。
リスト 5. フォーカス切り換えのチェック
}elsif( $line =~ / switch from / )
{
# track changes of focus between clients
my $name = (split " ", $line)[6];
$disp{$name}{mode} = 0;
# set all other displays to inactive
map{ $disp{$_}{mode} = 1 if( $_ ne $name ) } keys %disp;
$lastTime = time; $inTimeout = 0;
print "switch to $name\n";
my $res = "export DISPLAY=$name:0; ";
$res .= "./animation $disp{$name}{X} $disp{$name}{Y} $disp{$name}{mode} &";
system($res);
}#if switch screen catch
}#while line in
|
Synergy がモニター間でのフォーカスの切り換えを追跡すると、そのメッセージが processSynergy.pl プログラムによって読み取られます。すべてのモニターに関する情報 (この情報も後でフォーカスのタイムアウトをチェックするために使われます) を含むデータ構造を更新した後、クライアントを接続した時に記録された解像度を使ってアニメーション・プログラムが呼び出されます。
フォーカス追跡用の視覚効果を作成するために、Synergy サーバーとしてセットアップされたマシンでコマンド synergys -f -c configFile --debug DEBUG2 2>&1 | perl processSynergy.pl を実行します。場合によると、各クライアントに接続して xhost + SynergyServer を発行する必要があるかもしれません (「SynergyServer」はアニメーション・プログラムが実行されるマシンの名前です)。
さまざまなウィンドウにマウスを移動し、フォーカス追跡用の視覚効果がモニター全体にわたって機能すること、そしてその表示が次第にフェード・アウトされることを確認します。
フォーカスがないことを示すための簡単で効果的な 1 つの方法として、画面のスナップショットをアルファ・ブレンドしたものの周囲に赤い枠線を表示する方法があります。図 1 はこの一例を示しています。複数画面の構成でのフォーカス表示機能を使って、フォーカスがないことを示す視覚効果を作成するためには、リスト 6 に示すコードを animation.c の 57 行目に追加します。
リスト 6.
renderBox 関数
static void
renderBox(Ghosd *ghosd, cairo_t *cr, void* data) {
RenderData *rdata = data;
// draw a red box around a alpha blended center
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_new_path(cr);
round_rect(cr, 0,0, sizeX,sizeY, RADIUS);
cairo_fill(cr);
cairo_set_line_width( cr, 10);
cairo_set_source_rgba(cr, 1, 0, 0, 1.0);
cairo_new_path(cr);
round_rect(cr, 0,0, sizeX, sizeY, RADIUS);
cairo_stroke(cr);
cairo_set_source_surface(cr, rdata-<foot, 0,0 );
}//renderBox
|
この場合も Ghosd の examples/animation.c ファイルの影響を大いに受け、renderBox 関数はアルファ・ブレンドしたフルスクリーンの四角を描画し、続いてその四角の周囲に赤い枠線を描画します。この関数を適切に呼び出すためには、リスト 7 に示すコードを 106 行目に挿入します。
リスト 7. 赤い四角の枠を描画するための論理分岐
}else
{
// create a full screen box, and draw the red box with faded center
data.foot = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, sizeX, sizeY);
data.alpha = 1;
ghosd_set_position(ghosd, 0, 0, sizeX, sizeY );
ghosd_set_render(ghosd, renderBox, &data);
ghosd_render(ghosd);
ghosd_show(ghosd);
ghosd_main_iterations(ghosd);
|
こうした特定の視覚効果は、processSynergy.pl プログラムによって強制終了されるまで持続するように設計されています。117 行目でコードを次のように変更します。
リスト 8. 変更前の
render ループ
for (;;)
{
gettimeofday(&tv_nextupdate, NULL);
tv_nextupdate.tv_usec += STEP*1000;
ghosd_main_until(ghosd, &tv_nextupdate);
data.alpha -= dalpha;
if (data.alpha <= 0.3) { return(0); }
ghosd_render(ghosd);
}//for each step fade out
|
このコードを次のように変更します。
リスト 9. 新しい
render ループ
for (;;)
{
ghosd_main_until(ghosd, &tv_nextupdate);
ghosd_render(ghosd);
}//continuous render until program killed
|
このファイルをビルドするには、make コマンドを実行し、続いてコマンド ./animation 1400 1050 1 を実行します。画面の解像度が 1400x1050 だとすると、フェードアウトした画面の周囲が赤い枠線で囲われているはずです。Ctrl+c を押すと、この視覚効果を終了することができます。
processSynergy.pl を変更してフォーカスのタイムアウトをチェックする
どの画面にフォーカスがあるのか、また入力が停止されたのはいつかを追跡するために、processSynergy.pl に次のような変更を加えます。まず 47 行目から 49 行目を削除し、リスト 10 のコードで置き換えます。
リスト 10. 動きとキーをチェックするための論理分岐 (ハートビートのための論理分岐)
}elsif( $line =~ / MotionNotify / || $line =~ / KeyPress / ||
$line =~ /event: Buton/ )
{
# reset time on keyboard and mouse events
$lastTime = time; $inTimeout = 0;
}elsif( $line =~ / writef\(CALV\)/ )
{
# check for timeouts at each hearbeat
next unless ( (time - $lastTime) > $delay && $inTimeout == 0);
$inTimeout = 1;
$osdOn =1;
for my $key ( keys %disp )
{
my $res = "export DISPLAY=$key:0; ";
$res .= "./animation $disp{$key}{X} $disp{$key}{Y} $disp{$key}{mode} &";
system($res);
}#for each display name
print "timer exceeded\n";
}#if client
|
マウスまたはキーボードによる新しいイベントがあるたびに、(最初の elsif 分岐の処理によって) lastTime 変数がリセットされます。2 番目の elsif 分岐はクライアントからサーバーに送信される CALV「ハートビート」を探します。最後の動きがあってから一定の秒数が経過すると、それぞれの視覚効果が、対応する画面に表示されます。processSynergy.pl に対する変更の最後として、リスト 11 に示すコードを 71 行目に追加します。
リスト 11.
destroy アニメーション・プロセスの動作
if( $inTimeout == 0 && $osdOn == 1)
{
# destroy on screen display process
system("ps -aef | grep animation | perl -lnae '`kill -9 \$F[1]`'");
$osdOn = 0;
print "terminate osd\n";
}#if on screen display is visible
|
この方法は、少なくとも 1 台のクライアントから CALV ハートビートで接続されている必要があることに注意してください。ネットワークが利用できなくなった場合、あるいは他の理由でCALV メッセージが存在しない場合には、フォーカス表示機能が正しく動作しない可能性があります。
これでフォーカス表示機能とタイムアウト検出機能は完成しましたが、この機能を使うためには Synergy サーバーとしてセットアップされたマシンでコマンド synergys -f -c configFile --debug DEBUG2 2>&1 | perl processSynergy.pl を実行します。
この場合も、もし視覚効果が適切に表示されない場合には、それぞれのクライアントに接続して xhost + SynergyServer を発行する必要があるかもしれません。キーボードまたはマウスが何も操作されない時間が「delay」で指定される秒数 (この場合は 5 秒) を超えると、現在フォーカスのある画面には何重かの緑色の四角が表示される一方、フォーカスされていない画面には、アルファ・ブレンドされて赤い枠の付いた四角が表示されます。
Synergy による出力モニター・コードと Ghosd による視覚効果を利用すると、フォーカスを追跡することができ、また一定時間の経過後、現在どの画面にフォーカスがあるかを示す視覚的な手掛かりを提供することができます。こうすることによって、他の仕事から戻って作業を再開する場合、いくつもある画面の中からカーソルを見つけるための時間を節約することができます。
別の例として、フォーカス表示機能にアニメーションを追加し、より目を引く表示にする方法を考えてみてください (ただし利用するライブラリーでのメモリー・リークに注意してください)。また、ターミナル・セッションを Synergy による現在のフォーカス情報とリンクさせ、現在どの画面に注目しているかを示す更新情報をリモート・システムに提供することも考えてみてください。何らかの視覚効果を考える場合、Ghosd と、Synergy によるデバッグ情報を活用して表示を行うことができます。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample code | os-ghosd-synergyFocus.zip | 3KB | HTTP |
学ぶために
- Synergy の使い方に関して Ubuntu の資料を参照してください。
- 今回の記事は、IBM developerWorks の記事「Ghosd や Perl を使用して、装飾付きのオンスクリーン表示を作成する」に紹介された手法の一部を基にしています。
- この記事で説明した結果を得るためには、Linux 用の、あるいは Linux 互換 OS 用の X Window システム・サーバーが Synergy のサーバーとクライアントで実行されている必要があります。
- developerWorks podcasts では、ソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
- developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
- IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。
製品や技術を入手するために
- Synergy をダウンロードしてください。Synergy を利用すると、それぞれ独自のモニターを持ち、さまざまなオペレーティング・システムを実行する複数のコンピューターの間で、特別なハードウェアを使わずに 1 つのマウスとキーボードを共有することができます。
- テキストを配置したり描画したりするためのライブラリー、Pango をダウンロードしてください。
- GTK+ Project から GLib ライブラリーをダウンロードしてください。
- さまざまな出力機器をサポートする 2D グラフィック・ライブラリー、Cairoをダウンロードしてください。
- 効果的な方法で画面に情報を表示するためのライブラリー、Ghosd をダウンロードしてください。Ghosd のホームページには詳しい資料が用意されています。
- 安定したクロスプラットフォームのプログラミング言語、Perl をダウンロードしてください。
- 皆さんの次期オープンソース開発プロジェクトを IBM ソフトウェアの試用版を使って革新してください。ダウンロード、あるいは DVD で入手することができます。
- IBM 製品の試用版をダウンロードし、DB2® や Lotus®、Rational®、Tivoli®、WebSphere® などが提供するアプリケーション開発ツールやミドルウェア製品をお試しください。
議論するために
- developerWorks blogs から developerWorks のコミュニティーに加わってください。
