|
Carbonの森に迷う FOO: few01@mac.com 目次: 1. はじめに 2. イベントハンドリング 3. QuickDrawとQuartz 4. QuickTimeの位置付け(未完) 5. Sound Manager, Sound Input Manager, Core Audio(未完) 1. はじめに 御存じのとおりCarbonとは、Mac OS 9以前の環境からOS Xへの移行を容易にすることを大きな目的として開発された環境である。そのため、古いOS 9以前の機能(API, 関数)の多くが使えるようになっている。また新しいOS Xの機能(API, 関数)も使えるようになっている。そのため、ADCのCarbon関連ドキュメントには膨大な数の関連資料が並んでいる。そのような背景からCarbonの見通しは相当に悪い。Cocoa環境が基本的にNextStep系のすっきりした見通しをほぼそのまま継承しているのに対して、相当に複雑である。ここでは、私が分かる範囲で、そのCarbonの森の見取り図を描いてみたい。 参考: Carbon Developer Documentation: 2. イベントハンドリング Mac OS 9以前のイベントの扱いは、WaitNextEvent型であった。これは開発者がプログラムの中で明示的にWaitNextEventという関数を呼ぶ方式である。WaitNextEventを呼ぶことで、次のイベントが訪れるまでOSに休ませてもらう。この方式は他のOSのGUI処理でも使われる汎用的な方法である。 またOS 9以前のイベント処理では、メニューや、標準的なコマンド(Quitなど)についてもプログラム中で記述するのが一般的だった。そのため、プログラムはイベント処理のプログラムにかなりの部分を割いていた。 これに対して、CarbonではCarbon Event Managerという新しい仕組みが導入された。このCarbon Event Managerでは、自作プログラムで処理を付け加えたいイベントに関してのみ、InstallEventHandlerという関数で、イベントを追加する。その後RunApplicationEventLoopという関数を呼ぶ。このRunApplicationEventLoopが、WaitNextEventのループに相当する。違いは、イベント処理の多くがCarbon Event ManagerひいてはOSにまかされているという点である。 従来のWaitNextEventループでは、基本的にどんなイベントが発生しても一度は自作プログラムのイベント処理ループに処理が渡される。そしてその多くは、標準的な処理を要求するイベントであったり、無関係なイベントであったりするので、処理をせずに、次のイベント待ちプログラム(WaitNextEventを動かしているプログラム)にイベントをバトンタッチすることになる。(ちょっと誇張である。実際はイベントマスクをかけるので、何でもかんでもやってくることはない) Carbon Event Handlerでは、Installしたイベントのみが引っ掛かってくる。より多くの部分をOSまかせにするスタイルといって良い。 例えばProject Builderで、NibベースのCarbonの新規プロジェクトを作ってみると良い。main.cの小ささに驚くだろう。これだけでちゃんとウィンドウやメニューがあり、それらがちゃんと動作するアプリケーションが作れるのだから。 さて、ここからがCarbonの混乱である。 実はCarbonでは、WaitNextEvent型でのプログラミングも許されている。また、任意のイベントを受けつけるようなイベントハンドラーをCarbon Event ManagerでInstallすることもできる。イベントを片端から受け付けて、「不適切な」処理をするプログラムが簡単に書けてしまうのだ。ユーザにとって迷惑この上ない。 したがって、なるべくCarbon Event Managerを使うのが良い。それも広くイベントを受けつけるように使うのではなく、自作アプリケーションが必要とする最小限のイベントを受けつけるように作るべきである。 しかし、ここでいくつかの障害がある。一つは逃げようがないものでCarbon Event Managerの実装がまだ十分でないために、従来のMac OS 9以前で可能だった処理が実現できない場合だ。(私の理解が及んでいないからかもしれないが、細かくバッファをコントロールするようなイベント処理を作るのが難しい) もう一つの障害は、現在用意されているたくさんのサンプルプログラムの多く(ほとんどと言って良い)が、WaitNextEvent型の処理をしているという点である。そういうサンプルプログラムは、いちいちCarbon Eventだとどうなるか、翻訳しながら読みすすめなればならない。面倒になって、そのまま従来型のイベント処理に戻りたくなることも多い。 このサイトで紹介するプログラムは、そこで可能な限りCarbon Event Managerベースでのサンプルプログラムを提供したいと思う。(余裕ができたら、ADCのサンプルプログラムのCarbon Event Handler化でもしてみようか) 3. QuickDrawとQuartz 御存じの通り、Mac OS XではQuartzと呼ばれる描画方式が導入された。Quartzの美しいアンチエイリアス処理が、OS Xの見た目の美しさの多くを担っているのは間違いない。ところでQuickDrawという描画方式もある。QuickDrawはOS 9以前に使われていた描画方式である。 Mac OS XのCarbonでは、このQuartzとQuickDrawの両方が使える。ではCarbonでの基本の描画方式はどちらだろうか? OS XなんだからQuartz? いや現QuickDrawだと言って良いと思う。なぜか。 どちらにしろ、まず描画をするには描画先を選ばなければならない。最初に与えられるのはWindowRef windowである。Nibベースのプロジェクトならば、次のような関数でwindowを最初に取得する。 CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window); さて、このWindowRefというのは、CGraphPtrであり、そのままQuickDrawの描画ルーチンの描画先として使える。この意味でOS 9以前のQuickDrawで描画していたプログラムはほぼそのまま移植できることになる。 それに対してQuartzで描画するには、WindowRefをもとにCreateCGContextForPortでグラフィックスコンテキストを取得する必要がある。Quartzでの描画では、このコンテキストに対して行う。しかし単にCreateするだけでは駄目で、エリアを指定したり、座標系を変更したりといった手続きをへて初めて描画できるようになる。詳しくは別項で紹介したいと思う。 なぜQuickDrawではそのまま描画できるのに、Quartzだといくぶん面倒な手続きをへなければならないのか?それは最初に与えられるのがWindowRefというQuickDraw用の参照子だからだ。 さて、では最初からQuickDrawではなくて、Quartzを標準にすれば良いのか、というとそうではない。Carbonの役割からして、第一の目的はMac OS 9以前のプログラムをなるべく変更なく移植できなければならないからだ。また我々が利用できるサンプルプログラムの多くも、QuickDrawを使っている。それらをそのまま使いたければQuickDrawが使える環境というのは非常に便利だ。 後から分かってくるのだが、Carbonの森の深さは、実はこのQuickDrawとQuartzの関係ほどシンプルではないのだった。 4. QuickTimeの位置付け5. Sound ManagerとCore Audio
---(未完)--- (c) few01@mac.com --[2002/2/13]-- |
|||