背景の透明化

X Window版サーバ

幸い、window構造体(windowstr.h)のborderClipまたはclipListが、あるウィンドウのうち、他のウィンドウに隠されていない領域を保持しているので、どこのウィンドウを透明化するのかさえ分かれば、透明にすべき領域を得るのは簡単にできます。

問題は、どうやって透明化するウィンドウを得るかです。TWMのような古典的ウィンドウマネージャでは、ルートウィンドウを透明化すればよいです。しかし、GNOMEやKDEなどの今どきのウィンドウマネージャ(あるいはデスクトップ環境)では、ルートウィンドウとは別のデスクトップウィンドウを持っており、そのデスクトップウィンドウを透明化すべきです。

MetaVNCでは、ちょっとトリッキーな方法でデスクトップウィンドウを検出しています。具体的にはguessBackGroundWinClip?()という関数(xc/programs/Xserver/hw/vnc/rfbserver.c)で実装してます。 ウィンドウサイズがスクリーンサイズに一致し、どこか1箇所以上他のウィンドウに隠されているようなウィンドウを探します。

この方法は万能でなく、Fedora 7のデフォルトのGDMのログイン画面だとうまくいきません。(ツールチップが表示されたとき、他の領域が透明になってしまう。) そのため、version 0.6.5以降では、透明化するウィンドウを決めるためのポリシーをオプションで選べるようになっています。

詳細はxc/programs/Xserver/hw/vncあたりのコードを見てもらえば分かると思います。

MS-Windows 2000/XP版サーバ

MS-Windows版では以下の方法で透過領域を得てます。

  1. 可視ウィンドウのリストがメタウィンドウマネージャにより管理されてます。
  2. デスクトップ領域から、上記リストのウィンドウの領域を引けば、透過領域が得られます。

メタウィンドウマネージャ

メタウィンドウマネージャには、ウィンドウの管理とアプリケーションの起動等の機能があります。

X Window版サーバ

windowmonitorというプログラムをメタウィンドウマネージャの一部として使っています。

  1. libwnckというライブラリでウィンドウの監視・制御、およびアイコンの取得
  2. メニュー項目は$XDG_DATA_DIRSのapplicationsディレクトリ以下を探して取得(http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html参照)
  3. メニューのアイコンは$XDG_DATA_DIRSのiconsディレクトリ以下を探して取得(http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html参照)

MS-Windows 2000/XP版サーバ

  1. オリジナルのvnchooks.dllに対し、ウィンドウの変化を通知するよう拡張しました。(WH_CALLWNDPROCを使う)
  2. vnchooks.dllではコンソールウィンドウの変化は検出できないため、ポーリングしています。(vncDesktop::checkUpdates()からvncWindowMonitor?::pollConsoleWindows?を定期的に呼び出しています。)
  3. vncWindowMonitor?が可視ウィンドウとタスクバーに表示すべきウィンドウのリストを管理します。コンソールウィンドウのリストとコンソールウィンドウのポーリング処理もここで実行します。
  4. vncLauncherはアプリケーションメニューの読み込みおよび起動処理を担当します。サービスとして起動されている場合、サービスからアプリケーションを起動すると実行権限がログインユーザにならないため、実際の起動処理はサービスヘルパ(winvnc -servicehelper)のコンテキストで実行するようにしています。
  5. vncIconMgr?はWindowsのアイコン(HICON)からPNGイメージを生成します。

MS-Windows 2000/XP版クライアント

MS-Windows版ではローカルデスクトップのタスクスイッチとスタートメニューにリモートのタスクスイッチとスタートメニューを統合します。

タスクスイッチは以下のように実装しています。

  1. リモートのタスクスイッチのウィンドウに対応するウィンドウを作ります。(MetaTaskbar?::createTaskSw?)
  2. このウィンドウによりタスクスイッチに対する操作を処理します(MetaTaskbar?::WndProc?)
  3. ITaskbarList?を使ってタスクスイッチの追加/削除を行ないます。

タスクスイッチ関連の動きはまだちょっと変です。

スタートメニューは以下のように実装しています。

  1. リモートメニュー項目に対応して
    vncviewer -launch <vncviewerのHWND>:<メニュー項目ID>~
    というショートカットを作ります。
  2. vncviewerは引数-launchを解釈し、対応するvncviewerのHWNDに対しメッセージを投げます。このとき、念のためHWNDのウィンドウクラス名のチェックをします。(MetaLauncher?::launch)
  3. メッセージを投げられたvncviewerは引数で指定されたidに対応するリモートメニューを実行します。

また、リモートのメニューはローカルのメニューと同じディレクトリに置くこともできます。その場合、同じ名前のショートカットファイルが出来ることを防ぐため、ファイル名の最後に"@"+リモートコンピュータ名を付加しています。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-09-15 (土) 23:40:25 (3569d)