]>

# KDE デーモン

Simon
Hausmann

    hausmann@kde.org

26/06/1999
1.00.00

日本語翻訳：レーザーファイブ (info@laser5.co.jp)

このドキュメントは KDE デーモンが提供するサービスや使用方法についての解説です。ですから KDE で CORBAサーバ
をお使いの場合や、アプリケーションで Kサービス
のデータににアクセスするといったスマートな方法に興味があるようでしたら、このドキュメントを読み、
kdedを使ってみたくなることでしょう。

KDE
Daemon
CORBA
MICO

## はじめに

kded という名前の KDEデーモンは KDEデスクトップ環境の主要デーモンです。これは次の三つのサービスを提供します。

- KDE トレーダ (
  KTrader)。これは　KDE レジストリに対して使いやすく、強力なインターフェースを提供します。

- KDE アクティベータ (
  KActivator) 。これは KDE の基本となるサービスである CORBA へのアクセスを世界で一番シンプルにします;-)。

- KDE ネーミングサービス (
  KNaming)。これは CORBA オブジェクトに対して単純で使いやすいネーミングサービスを提供します。

## アプリケーション上の KDEデーモンの使用

kded のサービスを利用する前に、KDE におけるその立場とそれ自体の用途について知っておく必要があります、その上でサービスがアクセスされるようになります。

kded がクライアントとやりとりするのに CORBA を使用する際、(クライアントとしての)アプリケーションは以下のようにする必要があります。

- kded ライブラリ、
  libkdedへのリンク

- libmicoへのリンク

- MICO
  ORB
  の初期化

最初の二点については全てのクライアントに対して求められます。三つ目は特定のクライアントに対してのみです。普通次の中から選択しなければなりません：

- アプリケーションがすでに KOM
  を使用しているなら、
  KOMApplication (いつでも必要となるような) を使用した方が良いでしょう。

- KOM
  を使いたくないなら、 ORBAを手動で初期化します:`CORBA::ORB_ptr orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );`この構造及び似たような構造を用いる際、同時に KDE/Qt クラスを利用している場合は CORBA サーバ
  としては動作することができない という点に注意して下さい。これは ORB
  が独自のイベントループを必要とし、更にメインとなる Qt イベントループも要するということに関係しています。現在は KDE オブジェクトモデルの一部として
  KOMApplication だけが、両イベントループを統合するのに必要な機能を供給し、それ故、KDE アプリケーション作成が CORBA オブジェクトに受け渡されます。

kdedは CORBA を広く用いますが、API はシンプルさを保ち、複雑な CORBA スタッフの影響は受けません。実際、
kded について話をする場合、API は
kdedサーバではなく、KDEデーモンライブラリを意味します。このライブラリはサーバの全体的な機能に加えて(クライアントに対する)サーバへのインターフェースも含まれます。これは
kded を使用するアプリケーションが
kded サーババイナリの存在に依存することを強要されるべきではない、もしくはサーバの稼働状況に全く依存すべきでないという考え方に由来するものです。クライアントアプリケーションを起動する時、次の三つの状況が考えられます：

- kded が起動しておらず、パスに
  kded サーバが存在しない。この場合、
  libkded はアプリケーションのプロセス上で自動的に
  kded のローカルな要請を起動します。

- kded は起動していないが
  kded サーバは利用可。ここで
  libkded は実行可能な kded を稼働し、接続します。

- kded は既に動いている:-)。kde が動くという事実は X Root Window の特定のプロパティで指示されます。
  kded はその IOR
  (Interoperable Object Reference) をこのプロパティに受け渡します。また、これは kded
  インスタンスが X ディスプレイに明記されており、それゆえ KDE セッションにも明記されていることを保証するものです。

要約すると、libkded
は、たとえアプリケーションが稼働している環境がどのようなものであろうと常に kded
のサービスがクライアントアプリケーションに対して利用可能な状態にしているのです:-)。そしてこのことに気を遣わなくても、次の三つのコマンドライン引数
のうちの一つを自分のアプリケーションに追加することで libkded
の動作を随意にコントロールすることが出来ます:

- >"-kdedlocal" - この引数は常に libkded
  に kdedのプロセス-ローカルインスタンスやそのサービスを起動させます。

- "-kdedremote" - この引数は、稼働している kded
  インスタンスをローカルな方を起動する前に、libkded
  に探させます。

- "-kdedior ior&lowbar;here" - この引数は与えられた IOR
  によって指定される kded サーバ
  に libkded
  を接続させます。

実際の kded
インターフェースとそのサービスは、kded&lowbar;instance.h に定義されている`
Kdedインスタンス`クラスです。ですから kded
を使用したいなら(だからこんなものを読んでいるのだとは思いますが)、忘れずにそのためのインスタンスを一つ作成しておいてください。好ましい方法は`main()`の最初に次の行を追加することです：`KdedInstance( argc, argv, _a_reference_to_the_orb_here_ )；` KOMApplication
をアプリケーションオブジェクトとして使用しているなら(この行の前にインスタンスを作成することを忘れないでください)、ORB
に関して`komapp&lowbar;orb`を明記します。

このクラスのインスタンスが常にただ一つだけなら、どこからでもクラスの`
self()`スタティックメソッドで簡単にアクセスすることが出来ます。プログラム中の
KdedInstance引数をパスする必要はありません。

`
KdedInstance`についての更に詳しい情報として、`
kded&lowbar;instance.h`を読みたくなるかも知れません。これは素晴らしくよくまとめられています。

## Kトレーダ

『はじめに』の章で既に説明されているように、Kトレーダ
はレジストリへのアクセス権を付与します。"レジストリって何？"と思うかも知れません。このドキュメントが単に kded
/libkded
のためのものなら、こう答えるしかなかったでしょう。"詳しくは`
libkio`のドキュメントをご覧ください" :-&rcub; レジストリについてはただ一つ、Kトレーダ
は完全な、肥大したレジストリをロードします。`
libkio`のおかげで、ロード済みのレジストリは"本当の"レジストリである以下の標準的なディレクトリ内の .desktop
ファイルとともに sync に常駐しています。

- applnk

- mimelnk

- services

- servicetypes

Kトレーダ
とそのAPI についてですが、`
Kdedインスタンス`と同様にインスタンスがたった一つだけ存在します。違いはそのインスタンスを割り当てる心配をしなくても良く、単に`
Kdedインスタンス`の`ktrader()`メソッドをコールすることで Kトレーダ
の効果を得られます。そして返って来たリファレンスの削除について考える必要すらないのです。簡単に使えて幸せになれるのです:-)。(kded
は使いやすいように設計されています。)

Kトレーダ
API は二つのメソッドしか含んでいないきわめてシンプルなものです;-)。しかしこれらのメソッドについて説明する前に、Kトレーダ
戻り値データについて知る必要があります。簡単にいえば、Kサービス
オブジェクトのリストを常に受け取ることになるでしょう。詳しくいうと、返されるリストは`
QValueList`で、エントリは`Kサービス
`オブジェクトへの`
KSharedPtr`のエントリです( FIXME: KSharedPtr は Qt.... AFAIK の一部になるので、間もなく QSharedPtr に名前が変わります)。これらの二つのクラスについては Qt に関係しているドキュメントをご覧ください。この二つのテンプレートクラスを使う最大のメリットは、あらゆることが簡単になり、メモリ消費量が最小限に押えられるということです。Kサービス
オブジェクトを保持するための`
KTrader::ServicePtr`変数を使う限り、そしてプログラム中のリストを無視する`
KTrader::OfferList`を使う限り、ポインタやそのポインタを開放したりリストを削除する心配する必要はありません。ですから Kトレーダ
を使用する場合は、常にこれら二つのタイプを使うことを念頭においてください。

二つのメソッドについて

`
KTrader::listServices()`は KDE 全体で利用可能なサービスのリストを返します(これ以上の説明は不要だと思うのですが・・・)。

`
KTrader::query()`はキーとなるメソッドです。これは得ようとしている情報を与えつつレジストリデータベース内の検索を実行します。最初の引数は、履行すべきサービスを返すサービスタイプの名称です。"サービスタイプ"という言葉がよく分からない場合は、"マインタイプ"に置き換えてみてください。全てではありませんが、大抵の場合はそれで分かるはずです。

二番目の引数はサービスが履行しなければならない追加制約です。

三番目の引数はリターンサービスをソート後の設定表現です。表現の値は数字でな ければなりません。

これら二つの表現の文法は標準的な CORBAトレーダ 言語と同じです(これは構文解析コードが MICO
の COS
トレーダからきているからです)。この言語はあまり難しいものではなく、私としてはその説明のためにこのドキュメントを大きくしたくありません。詳しくは CORBA の文献を参照してください。知っておかなければならないことはただ一つ： Kサービス
オブジェクトのプロパティとの比較は常に行われているということです。このプロパティは標準的なエントリ(ネーム, サービスタイプ, RepoId...)に加え、サービスタイプの宣言で明記され Kサービス
に読込まれるエントリのことです。

説明はそれくらいにして、実際的なサンプルコードを見てみることにしましょう。

      ...
      //get a reference to the KTrader
      KTrader *trader = KdedInstance::self()->ktrader();

      ...
      //will return a list of all services which implement the servicetype
      //named "text/plain"
      KTrader::OfferList offers = trader->query( "text/plain" );

      ...
      //will return a list of all services which implement the servicetype
      //named "image/gif" and which have the AllowAsDefault property set true
      KTrader::OfferList offers = trader->query( "image/gif", "AllowAsDefault == TRUE" );

      ...
      //will return KSpread ;-)
      KTrader::OfferList offers = trader->query( "KOfficeDocument", "(Exec == 'kspread') and (Path != '/opt/gnome/bin')" );

      ...
      //will return a list of all services which implement the servicetype
      //named "BlahFoo" and which will be sorted (from lowest to highest) by
      //the value of the property "Price" , declared in the servicetype
      //declaration of BlahFoo.
      KTrader::OfferList offers = trader->query( "BlahFoo", QString::null, "min Price" );

Kトレーダ
は、サービスに対して`
libkio`をとうため、常に特定のサービスタイプにあわせて、ユーザーの好みによってソートされたサービスを返すということを覚えておいてください。これらの設定は"profilerc"ファイルに明記することができます。

### Kトレーダサービスプロバイダ

この節は`
libkio`に精通している必要があります。 これはアプリケーションに Kラン
を使おうとしている人全員に対していえることです。

Kラン
は、マインタイプ <->アプリケーションバインドを決定するために、完全にロードされたレジストリを要求します。完全にロードされたレジストリとは、`
KServiceTypeFactory`と Kサービスファクトリを要するということです。この二つは両方とも適正な`
KServiceType``
Kサービス`オブジェクトをロードします。Kサービスタイプ情報は多くのメモリを必要としませんが、Kサービス
オブジェクトは大量のメモリを要します。これが kded
で既に行われているなら、この情報をロードするのはばかげているとは思わないでしょ？ 全くその通りですよね;-)。

私達が必要としていることは、Kサービスプロファイル
を直接使用する代わりに、Kサービス
データに対して Kラン
に Kトレーダ
について問わせることです。幸運にも Kラン
はこれを行える程柔軟なので、`
krun.h`に定義され、Kラン
に用いられる Kサービスプロバイダ
を再実行するだけです。Kトレーダ
がこれを行ってくれます :-)。だから`
ktrader.h`の最後を見てみましょう。

つまり次の行は、アプリケーション内で Kラン
にkded
を呼び出させるのです：

      ...
      //place this somewhere BEFORE the first usage of KRun, preferable somewhere
      //in main()
      KTraderServiceProvider serviceProvider;
      ...

これで、
Kdedインスタンスを使用するためにしなければならないこと以外の全てが終わりました。

## Kアクティベータ

話が CORBA を通してサービスを提供するアプリケーションに及ぶとしばしば出て来る問題は、サービスのスタートとアクセスの方法です。ファイルシステム内のファイルのどこかにオブジェクトの IOR
を、アプリケーションに書かせればいいでしょう。もしくは同様の方法、まさにハックですが ;-)。それならKアクティベータ
を使った方が良いでしょう。なぜならこれは必要があれば自動的にサーバをスタートさせる、あるいは既に動いているサーバを使用できるようにするからです。これは、MICO
に提供される BOA/POA
へのメディエータといった救済機能や IMR
で実行されます。幸運にも IMR エントリやメディエータを扱う必要はありません。

サーバを起動するのに Kアクティベータ
を使用する前に、サーバのサービスについて登録しておかなければなりません。考えられる方法は二つありますが、後者の方法を強くお勧めします。

- Kアクティベータ
  に関する二つの方法を使って、手動でサーバのサービスを記録し、抹消する。

- スマートな手法を取り、必要な情報を.desktop
  ファイルに入力します。幸運にも、Kサービス
  はレポジトリ ID やアクティブモードなどの必要なプロパティをサポートしています。

二番目として、記入が反映されるディレクトリに Kレジストリ
を置くことで、.desktop
ファイルが有効になるということは重要です。例えばアプリケーションが applnk ツリーに既に .desktop
ファイルを持っているようなら、そこに必要なものを加えるだけで構いません。また、それには "services" (system-wide かまたは user-local)というディレクトリがもっとも適しています。この方法で CORBA サービスの情報を準備するなら、Kアクティベータ
は自動的にそれを見つけ出し、IMR に自動的にそれを記録します。これは Kアクティベータ
が直ちにに有効になり、それ故クライアントアプリケーションにもすぐに反映することを意味します。Kレジストリ
がそのように凄いものなので :-)、kded
が起動していればランタイムにこの作業を全部行うことが出来るのです。.desktop
ファイルを適切なディレクトリに置くと、Kアクティベータ
は直ちに IMR をアップデートします。これは .desktop
ファイルの削除及び変更にも当てはまります。この操作で、Kアクティベータ
が IMR を調整します。これがなかなか良い方法だということが理解できますか。 :-))

CORBA サービスを記録する方法を知ることが出来た今、それにアクセスする方法も知りたいことでしょう。`activateService()`がここで役立つでしょう。単にサービスの名称、サーバオブジェクトのレポジトリ ID、そしてオブジェクトのタグを通すだけです。するとオブジェクトリファレンス関数を返します。これで全部です。:-)

Kアクティベータ
は、サービスのアクティブモードに依存しているため、既に稼働しているサーバにリファレンスを返すか、新しいインスタンスを起動するかのどちらかを行います。

返されたオブジェクトリファレンスについて一つ注意すべきこと : これは仮想リファレンスです。つまりこのリファレンスに対して最初のコールがなされればそのサーバオブジェクトが起動し、したがって、要すれば自分自身のサーバを一歩送らせて起動します。しかしそれは単なる補助的な情報で、それについて扱い、知る必要は全くありません。単にオブジェクトリファレンス関数で幸せになればいいのです :-)。

サンプルはいかがですか？

コマンドライン"--server"は CORBA サーバ
モードでアプリケーションを起動するものとすると、 .desktop
ファイルがどのようにするかの例です。

    Name=MyApp
    Exec=fooblah
    CORBAExec=fooblah --server
    X-KDE-RepoIds=IDL:Foo/Blah:1.0#MyFoo
    X-KDE-ActivationMode=shared

Kアクティベータ
がこのファイルを読み込むと、サービスを記録し、次のようなことが出来るようになります :

      ...
      KActivator *activator = KdedInstance::self()->kactivator();
      ...
      CORBA::Object_var obj = activator->activateServer( "MyApp", "IDL:Foo/Blah:1.0", "MyFoo );
      ...

上の例は、新しい fooblah インスタンスを開始するか、既に稼働済みのインスタンスに接続するかのどちらかです。

詳しい情報は kdelibs/corba/tutorials/kded のサンプルをご覧ください。そこにあるサンプルアプリケーションは`registerService`を用いて手動でサーバを登録します。

注意してほしいこと : Kアクティベータ
により、稼働しているサーバにリファレンスを返させるためサーバが kded
で起動しなければなりません。ほかのところで "fooblah" を実行するとKアクティベータ
にそれを用いません。これはたとえば Kデスクトップ環境
のような持続性サーバにとっては問題です。しかし解決策もあります。KDEネーミングサービスについての次の章をお読みください :-)。

## Kネーミング

TKDEネーミングサービス、Kネーミング
はとても単純なサービスですが、非常に役に立ち、しかも場合によっては持続的な CORBA サーバ
に CORBA クライアントを接続させるのに大変素晴らしい解決策となります。

Kネーミング
を使えば、CORBA オブジェクトに自由に選択可能な名称を付けることが出来ます。更に kded
はシステム(セッション)全体で有効なため、オブジェクトは kded
に接続できるどのクライアントに対しても利用可能になります。

ここで説明することはあまりありません :-&rcub; 。ですから`
knaming.h`内の Kネーミング
API をご覧になることを提案します。

kdelibs/corba/tutorials/kded にサンプルコードがあります。ここでは実際的な短いサ ンプルを紹介します :

バックグラウンドデスクトップアイコンを提供する素晴らしいアプリケーションである Kデスクトップ環境
について考えてみましょう。これは CORBA を通していくつかの機能を提供します。何を言っているのかを知るために kdesktop.idl をご覧ください。Kデスクトップ環境
の問題は : システム上このサービスを他のアプリケーションに対してどのように提供するか ? ということです。IOR
をいくつかのファイルに書くというのは IMHO を完全に解決しているとはいえませんし、Kデスクトップ環境
は kded
ではなく、KDEスタートアップの startkde スクリプトで起動するため、Kアクティベータ
を使用するというのも無理です。ですからより良い方法を考え、Kデスクトップ環境
に対して、Kネーミング
にそのオブジェクトを登録させることにします。このことは次の行で行われています :

      ...
      KNaming *knaming = KdedInstance::self()->knaming();
      naming->bind( "KDesktop", kdesktop_object_here );
      ...

嘘をついていました ;) : Kネーミング
は実際には"Kデスクトップ環境
"にではなく、"IDL:KDesktopIf:1.0"にバインドします。しかしネーミングに関しては約束ごとが無いために、IMHO という読みやすい名前にしました :-)。(David 気にしないでね :] )。私は個人的に、タグの付いたレポジトリ ID とは逆の人間が読みやすい名前が好きなのです ;)。

Kネーミング
とKデスクトップ環境
に戻りましょう : 例えば kfmclient のようなどんなクライアントアプリケーションでも Kデスクトップ環境
に接続することができます。次のような感じになります :

      ..
      KNaming *knaming = KdedInstance::self()->knaming();
      ...
      CORBA::Object_var obj = knaming->resolve( "KDesktop" );
      KDesktopIf_var kdesky = KDesktopIf::_narrow( obj );
      kdesky->selectAll(); //let's confuse the user by selecting all icons ;-)
      ...