sudo dpkg-reconfigure -plow console-setup
2016年7月13日水曜日
2016年4月29日金曜日
The Debian Alternatives System
Debian には同一あるいは類似の機能を持つプログラムをひとつのシステムに同時にインストールして、共存させる仕組みがある。それが Debian Alternatives system です。これらのプログラムを管理するコマンドが update-alternatives コマンド。
Debian のパッケージ管理コマンドについて
Debian 管理者ハンドブック 5.4 Note dpkg か? apt か?
dpkg はシステムツール (バックエンド)、apt はユーザに近いツールとみなすべきです。apt は dpkg の制限を克服しています。これらのツールは互いに協力して作業を行います。両者は互いに異なる得意分野を持っており、それぞれが特定の作業を担当しています。
APT は巨大なプロジェクトで、当初の予定ではグラフィカルインターフェースを含んでいました。APT はライブラリに基づいており、そのライブラリにはコアアプリケーションが含まれています。apt-get は最初のコマンドラインベースフロントエンドで、APT プロジェクト内で開発されました。apt は APT から提供されているもう一つのコマンドラインベースフロントエンドで、apt-get の持っていた設計上のミスを克服しています。
APT の数多くのグラフィカルインターフェースは外部プロジェクトとして生まれました。たとえば synaptic、aptitude (テキストとグラフィカルモードインターフェースの両方があり、グラフィカルモードインターフェースはまだ完成していません)、wajig などが生まれました。最も推奨されるインターフェースは apt で、この節では apt を例に使います。apt のコマンドライン構文と apt-get や aptitude のコマンドライン構文はよく似ていることに注意してください。apt、apt-get、aptitude の間に大きな違いがある場合は、その違いを詳しく述べます。
APT は C++ プログラムで、libapt-pkg 共有ライブラリがその機能の多くを担っています。共有ライブラリを使うとユーザインターフェース (フロントエンド) の作成が楽になります。なぜなら、ライブラリに含まれるコードは簡単に再利用できるからです。歴史的に言って、apt-get は libapt-pkg のテスト用フロントエンドとして設計されましたが、成功を収めたためにその事実は曖昧にされがちです。
なるほど。コマンドラインベースのフロントエンドとしては apt を推奨しているようです。その他、管理者のために設計された対話型の準グラフィカルモードを備えた aptitude を使用するのも apt-get よりかはずっと合理的(6.4.1)とあるので、apt もしくは aptitude がよいようです。
なるほど。コマンドラインベースのフロントエンドとしては apt を推奨しているようです。その他、管理者のために設計された対話型の準グラフィカルモードを備えた aptitude を使用するのも apt-get よりかはずっと合理的(6.4.1)とあるので、apt もしくは aptitude がよいようです。
Debian に Node.js
Debian(8.4.0)に Node.js をインストールする際の少しややっこしい話。apt コマンドを使ってインストールするとコマンド名が通常 node となるところnodejs になる。いろいろめんどうになるとののことなのでこれを変更する。
VirtualBox に Debian インストール後 sudo をインストールしてユーザを sudo グループに追加してあります。そして Node.js のインストール。
sudo apt update
sudo apt install Node.js
確認のため dpkg に L オプションをつけて表示してみる。
dpkg -L nodejs
インストール先一覧が出ると思います。バイナリは /usr/bin/nodejs であることがわかります。これを一般的な node コマンドとして使用するために update-alternatives を使用して設定してやります。
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
成功すればその旨のメッセージがでます。
VirtualBox に Debian インストール後 sudo をインストールしてユーザを sudo グループに追加してあります。そして Node.js のインストール。
sudo apt update
sudo apt install Node.js
確認のため dpkg に L オプションをつけて表示してみる。
dpkg -L nodejs
インストール先一覧が出ると思います。バイナリは /usr/bin/nodejs であることがわかります。これを一般的な node コマンドとして使用するために update-alternatives を使用して設定してやります。
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
成功すればその旨のメッセージがでます。
2015年2月7日土曜日
JavaScript for Automation Release Note
OSXで作業を自動化するために AppleScript を使いますが Yosemite からは JavaScript もサポートとされました。以下ドキュメントです。
<https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html>
<https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html>
2014年11月15日土曜日
Master for iTunes Droplet を Yosemite で使う
OS X 10.10 で Master for iTunes Droplet を使うときの注意。
https://discussions.apple.com/message/27014610#27014610
ドロップレットのスクリプト にバージョンのミスマッチがあるよ、との指摘です。ご指摘の通りに書き直す。適当にコピーを作ってとおっしゃっていますが、僕は直接書き換えました。
以上。
https://discussions.apple.com/message/27014610#27014610
ドロップレットのスクリプト にバージョンのミスマッチがあるよ、との指摘です。ご指摘の通りに書き直す。適当にコピーを作ってとおっしゃっていますが、僕は直接書き換えました。
- Master for iTunes Droplet -> パッケージの内容を表示
- Contents/Resources/Scripts/main.scpt をスクリプトエディタで開く
- 検索すると "10.6" が2箇所あるので両方 "10.10" に書き換えて保存する
以上。
2014年11月2日日曜日
起動可能な OS X インストーラを OS X Mavericks で作成する
Yosemite にアップデートする前にいろいろの準備をする。タイトルの通り。Apple の説明によると以下のよう。
sudo /Applications/Install\ OS\ X\
Mavericks.app/Contents/Resources/createinstallmedia --volume
/Volumes/MyVolume --applicationpath /Applications/Install\ OS\ X\
Mavericks.app
Apple のリンク
http://support.apple.com/kb/HT5856?viewlocale=ja_JP
2014年10月9日木曜日
2014年5月29日木曜日
NSTableView, NSCell-based or NSView-based
NSTableView がどんな場合に cell-based か view-based で作成されるべきかわからなかったのでメモ。
NSCell-Based Tables Are Still Supported
In OS X v10.6 and earlier, each table view cell was required to be a subclass of NSCell. This approach caused limitations when designing complex custom cells, often requiring you to write your own NSCell subclasses. Providing animation, such as progress views, was also extremely difficult. In this document these types of table views are referred to as NSCell-based table views. NSCell-based tables continue to be supported in OS X v10.7 and later, but they’re typically used only to support legacy code. In general, you should use NSView-based tables.
Although you use the same Interface Builder techniques to create both NSView-based and NSCell-based table views (and to add columns to a table), the code required to provide individual cells, populate the table view, and support programmatic editing differs depending on the table type. In addition, you use different Cocoa bindings techniques depending on whether you’re working with an NSView-based or NSCell-based table.
- Table View Programming Guide for Mac -
Mac OS X 10.6 とその以前のバージョンでは、各テーブルセルは NSCell のサブクラスである必要がありました。複雑なカスタムセルを設計する際に、独自の NSCell のサブクラスを記述しなければならないことがあり、このアプローチは限界をもたらしました。プログレスビュー(進捗状況を表示するビュー)のようなアニメーションを提供するときはまた、非常に困難でした。本ドキュメントではこのタイプのテーブルビューは セルベース(NSCell-based)のテーブルビューと呼びます。セルベースのテーブルは継続して、Mac OS X 10.7 とそれ以降でサポートされますが、典型的には従来のコードをサポートするためだけに使用われます。通常はビューベース(NSView-based)のテーブルを使用するべきです。
ビューベースとセルベースのテーブルビュー両方を作成(そしてテーブルにカラムを追加)するためにインターフェイスビルダーで同じ手法を用いますが、個々のセルを提供するために必要とされるコード、テーブルビューへのデータの格納、そしてプログラム的な編集のサポートは、テーブルのタイプに応じて異なります。加えて、ビューベースまたはセルベースのテーブルで作業しているかどうかに応じて、異った Cocoa バインディングの手法を用います。
Most Tables Are Based on NSView
Most tables are NSView based, which means that each cell is provided by an NSView subclass, often by NSTableCellView (or a subclass). Some tables are NSCell based, which means that each table cell is based on a subclass of NSCell. For the most part, NSCell-based tables are used to support legacy code; if you’re creating a new app, you want to use NSView-based tables. In this document, a table is assumed to be NSView based unless specified otherwise.
- Table View Programming Guide for Mac -
ほとんどのテーブルは NSView に基づいています。それは、それぞれのセルが NSView や、しばしば NSTableCellView(またはサブクラス)によって提供されることを意味します。いくつかのテーブルは NSCell に基づいていて、それぞれのテーブルセルが NSCell のサブクラスに基づいていることを意味します。ほとんどの場合、セルベースのテーブルは従来のコードをサポートするために使用されます。新たにアプリケーションを作成するならば、ビューベースのテーブルを使っていただきたい。本ドキュメントでは特に断りがない限り NSView に基づいたテーブルを仮定しています。
というわけで、レガシーコードをサポートするとき以外はビューベースで。
さらにテーブルのバインディングについてメモ。 同ドキュメントには "Populating a Table View Using Cocoa Bindings" でビューベースのテーブルのバインディングについての説明がある。以下まとめ。
以上。セルベースのテーブルはカラムにバインドするとかなんとか。詳しくは "Creating Bindings for an NSCell-Based Table View" で。関係ないけど "populate"という単語はプログラム関係の翻訳では、データベースにデータを入れるという意味で使用される。移入する、とか格納するとか、投入するとか。
NSCell-Based Tables Are Still Supported
In OS X v10.6 and earlier, each table view cell was required to be a subclass of NSCell. This approach caused limitations when designing complex custom cells, often requiring you to write your own NSCell subclasses. Providing animation, such as progress views, was also extremely difficult. In this document these types of table views are referred to as NSCell-based table views. NSCell-based tables continue to be supported in OS X v10.7 and later, but they’re typically used only to support legacy code. In general, you should use NSView-based tables.
Although you use the same Interface Builder techniques to create both NSView-based and NSCell-based table views (and to add columns to a table), the code required to provide individual cells, populate the table view, and support programmatic editing differs depending on the table type. In addition, you use different Cocoa bindings techniques depending on whether you’re working with an NSView-based or NSCell-based table.
- Table View Programming Guide for Mac -
Mac OS X 10.6 とその以前のバージョンでは、各テーブルセルは NSCell のサブクラスである必要がありました。複雑なカスタムセルを設計する際に、独自の NSCell のサブクラスを記述しなければならないことがあり、このアプローチは限界をもたらしました。プログレスビュー(進捗状況を表示するビュー)のようなアニメーションを提供するときはまた、非常に困難でした。本ドキュメントではこのタイプのテーブルビューは セルベース(NSCell-based)のテーブルビューと呼びます。セルベースのテーブルは継続して、Mac OS X 10.7 とそれ以降でサポートされますが、典型的には従来のコードをサポートするためだけに使用われます。通常はビューベース(NSView-based)のテーブルを使用するべきです。
ビューベースとセルベースのテーブルビュー両方を作成(そしてテーブルにカラムを追加)するためにインターフェイスビルダーで同じ手法を用いますが、個々のセルを提供するために必要とされるコード、テーブルビューへのデータの格納、そしてプログラム的な編集のサポートは、テーブルのタイプに応じて異なります。加えて、ビューベースまたはセルベースのテーブルで作業しているかどうかに応じて、異った Cocoa バインディングの手法を用います。
Most Tables Are Based on NSView
Most tables are NSView based, which means that each cell is provided by an NSView subclass, often by NSTableCellView (or a subclass). Some tables are NSCell based, which means that each table cell is based on a subclass of NSCell. For the most part, NSCell-based tables are used to support legacy code; if you’re creating a new app, you want to use NSView-based tables. In this document, a table is assumed to be NSView based unless specified otherwise.
- Table View Programming Guide for Mac -
ほとんどのテーブルは NSView に基づいています。それは、それぞれのセルが NSView や、しばしば NSTableCellView(またはサブクラス)によって提供されることを意味します。いくつかのテーブルは NSCell に基づいていて、それぞれのテーブルセルが NSCell のサブクラスに基づいていることを意味します。ほとんどの場合、セルベースのテーブルは従来のコードをサポートするために使用されます。新たにアプリケーションを作成するならば、ビューベースのテーブルを使っていただきたい。本ドキュメントでは特に断りがない限り NSView に基づいたテーブルを仮定しています。
というわけで、レガシーコードをサポートするとき以外はビューベースで。
さらにテーブルのバインディングについてメモ。 同ドキュメントには "Populating a Table View Using Cocoa Bindings" でビューベースのテーブルのバインディングについての説明がある。以下まとめ。
- ArrayController に Content Array を設定する。(モデルオブジェクトの入った Array)
- テーブルビューの Content に ArrayController, arrangedObjects でバインドする
- TableCellView のサブビューにそれぞれ Table Cell View, objectValue.{property} でバインドする。
以上。セルベースのテーブルはカラムにバインドするとかなんとか。詳しくは "Creating Bindings for an NSCell-Based Table View" で。関係ないけど "populate"という単語はプログラム関係の翻訳では、データベースにデータを入れるという意味で使用される。移入する、とか格納するとか、投入するとか。
2014年5月23日金曜日
ポップアップメニュー
ボタンを押したらポップアップメニューが出るようにしたい。どうするか。
NSButton のサブクラスを作成して、NSView の
+ (NSMenu *)defaultMenu
- (NSMenu *)menuForEvent:(NSEvent *)theEvent
をオーバーライドしてもいいけど、サブクラスを作らない方法。
-----------------------------------------------------------
- (IBAction)buttonAction:(id)sender {
NSMenu *menu = [[[NSMenu alloc] initWithTitle:@"MenueTitle"] autorelease];
[menu addItemWithTitle:@"Test"
action:@selector(selectedItem:)
keyEquivalent:@""];
[NSMenu popUpContextMenu:menu
withEvent:[NSApp currentEvent]
forView:[[sender cell] controlView]];
return;
}
- (void)selectedItem:(id)sender {
NSLog(@"Selected:%@",sender);
}
-----------------------------------------------------------
NSButton のサブクラスを作成して、NSView の
+ (NSMenu *)defaultMenu
- (NSMenu *)menuForEvent:(NSEvent *)theEvent
をオーバーライドしてもいいけど、サブクラスを作らない方法。
-----------------------------------------------------------
- (IBAction)buttonAction:(id)sender {
NSMenu *menu = [[[NSMenu alloc] initWithTitle:@"MenueTitle"] autorelease];
[menu addItemWithTitle:@"Test"
action:@selector(selectedItem:)
keyEquivalent:@""];
[NSMenu popUpContextMenu:menu
withEvent:[NSApp currentEvent]
forView:[[sender cell] controlView]];
return;
}
- (void)selectedItem:(id)sender {
NSLog(@"Selected:%@",sender);
}
-----------------------------------------------------------
2014年5月22日木曜日
self and super
super
実行するメソッドの検索をコンパイラに伝える単なるフラグ。レシーバとしてのみ使用する。
self
変数名。
以下 ”Objective-C プログラミング言語” によるサンプル。
-----------------------------------------------------
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
-----------------------------------------------------
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
-----------------------------------------------------
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
-----------------------------------------------------
悪い、良い、 最高の違いは、クラスメソッドがサブクラスからの呼び出しに対応しているかどうか。
実行するメソッドの検索をコンパイラに伝える単なるフラグ。レシーバとしてのみ使用する。
self
変数名。
以下 ”Objective-C プログラミング言語” によるサンプル。
-----------------------------------------------------
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
-----------------------------------------------------
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
-----------------------------------------------------
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
-----------------------------------------------------
悪い、良い、 最高の違いは、クラスメソッドがサブクラスからの呼び出しに対応しているかどうか。
2013年7月3日水曜日
To Implement 1D Cellular Automaton in Pure Data.
wikipedia の説明によりますと "最も単純だが自明ではないCAは、1次元で各セルは2つの状態をとることができ、近傍は両側に接している隣のセルという場合である。" そうです。 "自明ではない" としているところから、最も条件の少ない CA として証明はされていないのだろうと推測します。
さてさて、この場合、注目する中央1つのセルとその近傍の2つのセルのとれる状態は全部で 23= 8 通り。2つの状態をそれぞれ◆と◇で表現すると以下のよう。
◆◆◆ | ◆◆◇ | ◆◇◆ | ◆◇◇ | ◇◆◆ | ◇◆◇ | ◇◇◆ | ◇◇◇ |
そして注目する中央のセルが近傍のセルの状態でどのように次の状態に移行するか、という規則を定めます。
◆◆◆ | ◆◆◇ | ◆◇◆ | ◆◇◇ | ◇◆◆ | ◇◆◇ | ◇◇◆ | ◇◇◇ |
◇ | ◇ | ◇ | ◆ | ◆ | ◆ | ◆ | ◇ |
上の例では並びが◆◇◇, ◇◆◆, ◇◆◇, ◇◇◆のとき注目する中央のセルが◆にそれ以外は◇になります。とれる状態が2つであることから、これらを◆=1、◇=0 としてビットの並びに置き換えますと、
111 | 110 | 101 | 100 | 011 | 010 | 001 | 000 |
0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
となり、規則が8ビット(0 から 255)で参照できるようになります。この例では 00011110 なので、十進で 30 と表現できます。規則の総数は 28 = 256 通りになります。
Pure Data での実装
32 個のセルを用意し現在の状態(0 or 1)を Array に保存しています。セルの両端はつながっているもの(..., 31, 0, 1, 2, 3, ..., 29, 30, 31, 0, ...)としています。[for++] を使い、中央の注目するセルを Array から順番に呼び出しています。そして、まず注目する中央と近傍のセルの状態をビットの並びに変換するのに [expr] を使って計算します。
expr ($s2[($f1+31) % 32] << 2) + ($s2[$f1] << 1) + ($s2[$f1 + 1] % 32)
$s2は起動時に現在の状態を保存してある Array の名前がセットされます。そこから [for++] で 0 から 31 が順番に読み出されるのですが、近傍の表現に注意します。注目する中央のセルが 0 番目のとき 31 を返すように、余りを使っています。31 番目のときも同様です。読み出された値は並それぞれ、シフトします。これで 111 から 000(0 から 7)のどれかになります。そして、この数値をシフトしてやれば規則の想定するビットの並びのどれかになりますので、そのまま AND で演算してやると、合致しているならば 0 以上になります。これより下の処理の流れは [tabwrite] に書き込むための処理です。[expr] のみで書くなら、
expr if ((1 << ($s3[($f1+31) % 32] << 2) + ($s3[$f1] << 1) + ($s3[$f1 + 1] % 32) & $f2) > 0, 1, 0 );
$f1
として 2nd アウトレットをそのまま [tabwrite] の 2nd インレット、同様に 1st どうしをつなげてやります。
CA32.pd
2013年4月13日土曜日
Ethernet
ETHER TYPE IANA "IEEE 802 Numbers"
http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xml
IEEE 802.3 資料
http://standards.ieee.org/about/get/802/802.3.html
http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xml
IEEE 802.3 資料
http://standards.ieee.org/about/get/802/802.3.html
2013年3月31日日曜日
公開したくないインスタンス変数を持ちたいけれど、どうしたらよいか?
Objective-Cのはなし。
公開したくないインスタンス変数を持たせたいけれど、どうしたらよいか?
手元に実装コードがなくても既存のクラスにメソッドを追加できるのがカテゴリ。でもインスタンス変数は追加できない。では @property で追加したらどう?ってことで試したけれどだめです。
これにはクラス拡張(class extensions)で対応します。クラス拡張はカテゴリのカテゴリ名を無記名にするだけ。括弧内に名前を与えないので匿名カテゴリ(anonymous categories)と呼ぶこともあるそうです。
@interface ClassName () {
// インスタンス変数の追加も可能
id _obj;
}
// 宣言プロパティ
@property NSString *string;
// メソッド
- (void)method;
@end
また、クラス拡張でメソッドを追加した場合はクラス本体のソースコードにメソッドの実装をする必要があります。
公開したくないインスタンス変数を持たせたいけれど、どうしたらよいか?
手元に実装コードがなくても既存のクラスにメソッドを追加できるのがカテゴリ。でもインスタンス変数は追加できない。では @property で追加したらどう?ってことで試したけれどだめです。
これにはクラス拡張(class extensions)で対応します。クラス拡張はカテゴリのカテゴリ名を無記名にするだけ。括弧内に名前を与えないので匿名カテゴリ(anonymous categories)と呼ぶこともあるそうです。
@interface ClassName () {
// インスタンス変数の追加も可能
id _obj;
}
// 宣言プロパティ
@property NSString *string;
// メソッド
- (void)method;
@end
また、クラス拡張でメソッドを追加した場合はクラス本体のソースコードにメソッドの実装をする必要があります。
2013年1月23日水曜日
2013年1月9日水曜日
Does Time Waits for Someone?
時間に関するオブジェクトについて
Cocoa は日付と時間を NSDate オブジェクトで表しています。そして NSDate は日付を"点"で(具体的には yyy-mm-dd hh:mm:sss ±TimeZone のかたちで)表しています。そして日付についてあーだこーだするためには、この NSDate と生活時間を表している NSCalendar と構成要素の NSDateComponents を行ったり来たりしてあーだこーだします。詳しくは"Date and Time Programming Guide"を。
Cocoa は日付と時間を NSDate オブジェクトで表しています。そして NSDate は日付を"点"で(具体的には yyy-mm-dd hh:mm:sss ±TimeZone のかたちで)表しています。そして日付についてあーだこーだするためには、この NSDate と生活時間を表している NSCalendar と構成要素の NSDateComponents を行ったり来たりしてあーだこーだします。詳しくは"Date and Time Programming Guide"を。
2012年12月4日火曜日
How to install bash
bash のインストール
OpenBSD に bash をインストール。まず pkg_add でコンパイル済みのバイナリをインストールします。そのまえに環境変数 PKG_PATHの設定をします。詳しくは pkg_add(1) を。
# PKG_PATH=ftp://お近くの ftp サーバ/`uname -s`/`uname -r`/packages/`uname -p`/
# export PKG_PATH
# pkg_add -i -v bash
ログインシェルとして使用する場合は /etc/shells に書き込む必要がありまが、自動的に/usr/local/bin/bash が /etc/shells に追加されます。
ログインシェルの変更
~$ chsh -s /usr/local/bin/bash
bash のプロンプトを変更
ログインをし直してから
-bash-4.2# cat .profile > .bash_profile
以下追加
# Prompt
PS1="\h:\W \u\$ "
編集後に
source .bash_profile
でプロンプトが
ホスト名:dir ユーザ名#or$
になります。
OpenBSD に bash をインストール。まず pkg_add でコンパイル済みのバイナリをインストールします。そのまえに環境変数 PKG_PATHの設定をします。詳しくは pkg_add(1) を。
# PKG_PATH=ftp://お近くの ftp サーバ/`uname -s`/`uname -r`/packages/`uname -p`/
# export PKG_PATH
# pkg_add -i -v bash
ログインシェルとして使用する場合は /etc/shells に書き込む必要がありまが、自動的に/usr/local/bin/bash が /etc/shells に追加されます。
ログインシェルの変更
~$ chsh -s /usr/local/bin/bash
bash のプロンプトを変更
ログインをし直してから
-bash-4.2# cat .profile > .bash_profile
以下追加
# Prompt
PS1="\h:\W \u\$ "
編集後に
source .bash_profile
でプロンプトが
ホスト名:dir ユーザ名#or$
になります。
2012年11月26日月曜日
OpenBSD でしょ?
VirtualBox のゲストに OpenBSD をインストールします。
特に理由はありませんが紳士はやっぱり OpenBSD でしょ?ということです。
さて OpenBSD のサイトから"リリースを入手"で、OpenBSD を入手先を探します。 プロトコルは http/ftp のどちらでもよいですが、地域が近いミラーにします。日本ではそれぞれ、ふたつずつあります。
Japan (Ishikawa) http://ftp.jaist.ac.jp/pub/OpenBSD/
Japan (Saitama) http://www.ftp.ne.jp/OpenBSD/
Japan (Ishikawa) ftp://ftp.jaist.ac.jp/pub/OpenBSD/
Japan (Saitama) ftp://ftp.kddilabs.jp/OpenBSD/
現時点(2012年11月25日)の最新版(5.2)を使用することにします。いざ鎌倉というときでもインストールが可能なように OpenBSD 以下のディレクトリから install52.iso をダウンロード。CPUのアーキテクチャは x86_64 の場合 amd64 になります。
適当に設定した仮想マシンに iso イメージをマウントして起動します。インストール項目は基本的にデフォルトにしましたが、以下は変更しています。
キーボード
Choose your keyboard layout ('?' or 'L' for list) [default]
'L' でリストを表示。国名がたくさん出てきますので 'jp' を入力。
タイムサーバ
Start ntpd(8) by default? [no] y
NTP server? (hostname or 'default') [default] <ntpサーバ>
お近くの ntpサーバ をどうぞ。
パッケージの選択
Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-' to the set name, file name pattern or 'all'. Selected
sets are labelled '[X]'.
[X] bsd [X] etc52.tgz [X] xbase52.tgz [X] xserv52.tgz
[X] bsd.rd [X] comp52.tgz [X] xetc52.tgz
[X] bsd.mp [X] man52.tgz [X] xshare52.tgz
[X] base52.tgz [ ] game52.tgz [X] xfont52.tgz
Set name(s)? (or 'abort' or 'done') [done] -game52.tgz
ゲームは特にいらないかな?
インストールの終了後再起動します。これでインストールは完了です。
さて OpenBSD のサイトから"リリースを入手"で、OpenBSD を入手先を探します。 プロトコルは http/ftp のどちらでもよいですが、地域が近いミラーにします。日本ではそれぞれ、ふたつずつあります。
Japan (Ishikawa) http://ftp.jaist.ac.jp/pub/OpenBSD/
Japan (Saitama) http://www.ftp.ne.jp/OpenBSD/
Japan (Ishikawa) ftp://ftp.jaist.ac.jp/pub/OpenBSD/
Japan (Saitama) ftp://ftp.kddilabs.jp/OpenBSD/
現時点(2012年11月25日)の最新版(5.2)を使用することにします。いざ鎌倉というときでもインストールが可能なように OpenBSD 以下のディレクトリから install52.iso をダウンロード。CPUのアーキテクチャは x86_64 の場合 amd64 になります。
適当に設定した仮想マシンに iso イメージをマウントして起動します。インストール項目は基本的にデフォルトにしましたが、以下は変更しています。
キーボード
Choose your keyboard layout ('?' or 'L' for list) [default]
'L' でリストを表示。国名がたくさん出てきますので 'jp' を入力。
タイムサーバ
Start ntpd(8) by default? [no] y
NTP server? (hostname or 'default') [default] <ntpサーバ>
お近くの ntpサーバ をどうぞ。
パッケージの選択
Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-' to the set name, file name pattern or 'all'. Selected
sets are labelled '[X]'.
[X] bsd [X] etc52.tgz [X] xbase52.tgz [X] xserv52.tgz
[X] bsd.rd [X] comp52.tgz [X] xetc52.tgz
[X] bsd.mp [X] man52.tgz [X] xshare52.tgz
[X] base52.tgz [ ] game52.tgz [X] xfont52.tgz
Set name(s)? (or 'abort' or 'done') [done] -game52.tgz
ゲームは特にいらないかな?
インストールの終了後再起動します。これでインストールは完了です。
2012年5月4日金曜日
SoundCloud
SoundCloud に Pd-extended で生成したシグナルを上げました。
CC で配布していますので、自由にご利用くださいませ。
http://soundcloud.com/generalphotographics
CC で配布していますので、自由にご利用くださいませ。
http://soundcloud.com/generalphotographics
2012年4月17日火曜日
2012年2月19日日曜日
To increase output for a kitten.
I/O Kit とは?
以前ネットワークをキャプチャするコマンドラインツールを作成しましたが、ioctl を使ってネットワークインターフェイス名を取得していました。探索を I/O Kit の流儀でおこなえるようにします。その前にごくごく簡単に I/O Kit について。
I/O Kit は 以前の Mac OS 9 や流れをくむ FreeBSD のドライバモデルの機能が不十分なので、Mac OS X のために Apple が開発したものです。そして、
I/O Kit は Mac OS X でデバイスドライバを作成するためのシステムフレームワーク、ライブラリ、ツール、その他リソースの集まりです。マルチスレッドのカーネルでの使用に適さない機能を省略した、制限された形式の C++ で実装されているオブジェクト指向プログラミングモデルに基づいています。I/O Kit は Mac OS X システムに接続されているハードウェアをモデル化することによって、特定のカテゴリのなかでデバイスに共通の機能を抽象化し、デバイスドライバ開発過程を効率化します。
なるほど。さらに、
I/O Kit とは、カーネルに常駐していて、システムハードウェアのモデルを提供する Darwin 中にあるオブジェクト指向の環境です。サービスやデバイスの各タイプはファミリのひとつ以上の C++ のクラスで表現されています。それぞれ利用可能なサービスやデバイスはそのクラスのインスタンス(オブジェクト)によって表現されています。
つまり?
I/O Kit とは
ioctl を使ってネットワークインターフェイス名を取得する
I/O Kit を使ってネットワークインターフェイス名を取得する
ioctl のではバッファに収まったかどうかで取得できたと看做しているのが少し気持ち悪い感がありましたが、I/O Kit は的確に答えを出してくれています。BPF のフィルタマシンに渡すプログラムのコンパイルを libpcap に肩代わりさせていましたが、こうゆうことまで I/O Kit を通して出来るのでしょうか?
以前ネットワークをキャプチャするコマンドラインツールを作成しましたが、ioctl を使ってネットワークインターフェイス名を取得していました。探索を I/O Kit の流儀でおこなえるようにします。その前にごくごく簡単に I/O Kit について。
I/O Kit は 以前の Mac OS 9 や流れをくむ FreeBSD のドライバモデルの機能が不十分なので、Mac OS X のために Apple が開発したものです。そして、
I/O Kit は Mac OS X でデバイスドライバを作成するためのシステムフレームワーク、ライブラリ、ツール、その他リソースの集まりです。マルチスレッドのカーネルでの使用に適さない機能を省略した、制限された形式の C++ で実装されているオブジェクト指向プログラミングモデルに基づいています。I/O Kit は Mac OS X システムに接続されているハードウェアをモデル化することによって、特定のカテゴリのなかでデバイスに共通の機能を抽象化し、デバイスドライバ開発過程を効率化します。
なるほど。さらに、
I/O Kit とは、カーネルに常駐していて、システムハードウェアのモデルを提供する Darwin 中にあるオブジェクト指向の環境です。サービスやデバイスの各タイプはファミリのひとつ以上の C++ のクラスで表現されています。それぞれ利用可能なサービスやデバイスはそのクラスのインスタンス(オブジェクト)によって表現されています。
つまり?
I/O Kit とは
- I/O Kit とはデバイスドライバを開発するためのフレームワークのこと。目的の機能を持つデバイスドライバがない場合、デバイスドライバを開発することになります。限定された C++ を使って目的の機能を実現するデバイスドライバを作成します。
- I/O Kit とはカーネルに常駐するシステムハードウェアモデルを提供する、オブジェクトのこと。Mac OS X に接続されているハードウェアのデバイスやドライバの情報を管理しています。デバイスやドライバを利用する場合は I/O Kit から目的のデバイスやドライバを絞り込み、I/O Kit が提供する目的のインターフェイスを使用します。
ioctl を使ってネットワークインターフェイス名を取得する
+ (NSArray *)interfaces { int socketFD,length, lastLength; char *buffer; struct ifconf ifc; socketFD = socket(AF_INET, SOCK_DGRAM, 0); lastLength = 0; length = sizeof(struct ifreq) * 100; // 初期値 /*////////////////////////////////////////////////////////////////////////// ioctl を使って ネットワークインターフェイスの情報を問い合わせる。 この方法は SIOCGIFCONF が適切な情報を全て必ず返しているかは バッファに収まるかどうかによるので、 ifc構造体の長さが前回に取得した長さと一致した場合に 全ての情報を適切に取得できたと看做している。 /////////////////////////////////////////////////////////////////////////*/ for (; ;) { buffer = (char *)calloc(length, sizeof(char)); ifc.ifc_len = length; ifc.ifc_ifcu.ifcu_buf = buffer; if ( ioctl(socketFD, SIOCGIFCONF, &ifc) < 0) { free(buffer); return nil; } else { if (ifc.ifc_len == lastLength) { break; } lastLength = ifc.ifc_len; } length += sizeof(struct ifreq) * 10; free(buffer); } close(socketFD); struct ifreq *ifr = (struct ifreq *)buffer; int next = 0; NSMutableArray *interfaces = [NSMutableArray array]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; while (ifr < (struct ifreq *)(buffer + lastLength)) { ifr = (struct ifreq *)(buffer + next); NSString *name = [NSString stringWithCString:ifr->ifr_name encoding:NSUTF8StringEncoding]; if ([name isEqualToString:@""] == NO) { // 同じ名前のインターフェイスはいらない。 [interfaces removeObject:name]; [interfaces addObject:name]; } next += IFNAMSIZ + ifr->ifr_ifru.ifru_addr.sa_len; } free(buffer); [pool drain]; return (NSArray *)interfaces; }
I/O Kit を使ってネットワークインターフェイス名を取得する
+ (NSArray *)interfaces { IOReturn ioReturnCode; mach_port_t masterPort; CFMutableDictionaryRef matchingDictionary; io_iterator_t iterator; io_object_t object; NSMutableArray *interfaces = [NSMutableArray array]; // マスターポートの取得 ioReturnCode = IOMasterPort(MACH_PORT_NULL, &masterPort); if (ioReturnCode != KERN_SUCCESS) { NSLog(@"IOMasterPort did not return KERN_SUCCESS"); return nil; } // ディクショナリの作成 matchingDictionary = IOServiceMatching(kIOEthernetInterfaceClass); if (matchingDictionary == NULL) { NSLog(@"IOServiceMatching returned a NULL Dictionary."); return nil; } // I/O Registry の中から辞書に一致するものを検索する ioReturnCode = KERN_SUCCESS; ioReturnCode = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); if (ioReturnCode != KERN_SUCCESS) { NSLog(@"IOServiceGetMatchingServicesdid did not return KERN_SUCCESS."); return nil; } while (object = IOIteratorNext(iterator)) { CFStringRef deviceName = NULL; // 一致したオブジェクトから BSD 名を取得する。 deviceName = IORegistryEntryCreateCFProperty(object, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0); if (deviceName) [interfaces addObject:(NSString *)deviceName]; CFRelease(deviceName); } IOObjectRelease(object); } return (NSArray *)interfaces; }
ioctl のではバッファに収まったかどうかで取得できたと看做しているのが少し気持ち悪い感がありましたが、I/O Kit は的確に答えを出してくれています。BPF のフィルタマシンに渡すプログラムのコンパイルを libpcap に肩代わりさせていましたが、こうゆうことまで I/O Kit を通して出来るのでしょうか?
2012年1月31日火曜日
She said, It is nasty to wire!
MBP を通して iPhone をインターネットに接続する。
iPhone の Wi-Fi 設定が DHCP ではネットワークに接続できませんでした。
Mac のログを見てみると、
xx/xx/xx 1:24:44 Firewall[58] Deny InternetSharing data in from ...
インターネットの共有データが拒否されています。
OSX Server でないので DHCP サーバがないから?
仕方なく DHCP ではなく「静的」を選んで設定します。
IPアドレス iPhone に割当てるアドレス。AirMac インターフェイスと同じネットワークにする。
サブネットマスク AirMac のIPアドレスに応じて適当に。
ルータ AirMac インターフェイスのアドレス。
DNS Mac が使っている DNS のアドレス。nslookup を使って調べるのがよろし。
検索ドメイン あれば。空白のままでもよい。
無事接続されました。
iPhone の Wi-Fi 設定が DHCP ではネットワークに接続できませんでした。
Mac のログを見てみると、
xx/xx/xx 1:24:44 Firewall[58] Deny InternetSharing data in from ...
インターネットの共有データが拒否されています。
OSX Server でないので DHCP サーバがないから?
仕方なく DHCP ではなく「静的」を選んで設定します。
IPアドレス iPhone に割当てるアドレス。AirMac インターフェイスと同じネットワークにする。
サブネットマスク AirMac のIPアドレスに応じて適当に。
ルータ AirMac インターフェイスのアドレス。
DNS Mac が使っている DNS のアドレス。nslookup を使って調べるのがよろし。
検索ドメイン あれば。空白のままでもよい。
無事接続されました。
2011年12月5日月曜日
2011年12月4日日曜日
Purge it !
現在非使用中
Macを長時間あれこれ使っていますと、現在非使用中のメモリがどんどん溜まっていきます。この領域を解放するための方法を探していましたが、デベロッパツールをインストールすると入る /usr/bin/purge が強力です。
user# purge
とターミナルから引数なしで、待つこと数秒、奇麗に現在非使用中メモリを解放してくれます。
エージェント化
たいした手間ではありませんので、気づいたときにターミナルから実行してやればよいのでしょうが、定期的に実行するには launchd にエージェントとして登録してやります。
plist 形式のファイルで適当にキーを指定してやり、用途に応じた場所(今回は ~/Library/LaunchAgents )に保存してやれば、起動時にlaunchd にエージェントとして登録されます。詳しくは man launchd.plist(5) を。
Macを長時間あれこれ使っていますと、現在非使用中のメモリがどんどん溜まっていきます。この領域を解放するための方法を探していましたが、デベロッパツールをインストールすると入る /usr/bin/purge が強力です。
user# purge
とターミナルから引数なしで、待つこと数秒、奇麗に現在非使用中メモリを解放してくれます。
エージェント化
たいした手間ではありませんので、気づいたときにターミナルから実行してやればよいのでしょうが、定期的に実行するには launchd にエージェントとして登録してやります。
plist 形式のファイルで適当にキーを指定してやり、用途に応じた場所(今回は ~/Library/LaunchAgents )に保存してやれば、起動時にlaunchd にエージェントとして登録されます。詳しくは man launchd.plist(5) を。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.apple.purge</string> <key>ProgramArguments</key> <array> <string>/usr/bin/purge</string> </array> <key>StartInterval</key> <integer>10800</integer> </dict> </plist>
2011年11月27日日曜日
IMP, SEL, Method
IMP
まず IMP です。メソッド実装の先頭部分を指すポインタです。
IMP はメソッドを実装する関数の先頭部分を指すポインタです。この関数は現在の CPU アーキテクテャのために実装された標準 C の呼出規約(calling convention)を使います。最初の引数は self(クラスの特定の具体的なインスタンスのためのメモリ、クラスメソッドのためのメモリ、メタクラスを指すポインタのためのメモリ)へのポインタです。2番目の引数はメソッドセレクタです。メソッドの引数は以下の通り。
SEL
そして SEL です。セレクタを表現する構造体で Opaque Type です。
メソッドのセレクタはランタイムでメソッドの名前表現として使われます。メソッドのセレクタは Objective-C に登録(またはマッピング)されている C 文字列です。コンパイラによって生成されたセレクタは、クラスがロードされるとき、自動的にランタイムによってマッピングされます。
実行時に新しいセレクタを追加し、sel_registerName 関数を使って存在しているセレクタを取得できます。
セレクタを使うとき、sel_registerName が返す値か、Objective-C のコンパイラディレクティブ @selector() を使わなければなりません。単純に C 文字列を SEL にキャストすることはできません。
Method
Method はクラスで定義されているメソッドを表現する構造体で Opaque Type です。リファレンスには
としかありませんが runtime.h にはさらに
めも
http://opensource.apple.com/
まず IMP です。メソッド実装の先頭部分を指すポインタです。
IMP はメソッドを実装する関数の先頭部分を指すポインタです。この関数は現在の CPU アーキテクテャのために実装された標準 C の呼出規約(calling convention)を使います。最初の引数は self(クラスの特定の具体的なインスタンスのためのメモリ、クラスメソッドのためのメモリ、メタクラスを指すポインタのためのメモリ)へのポインタです。2番目の引数はメソッドセレクタです。メソッドの引数は以下の通り。
SEL
そして SEL です。セレクタを表現する構造体で Opaque Type です。
メソッドのセレクタはランタイムでメソッドの名前表現として使われます。メソッドのセレクタは Objective-C に登録(またはマッピング)されている C 文字列です。コンパイラによって生成されたセレクタは、クラスがロードされるとき、自動的にランタイムによってマッピングされます。
実行時に新しいセレクタを追加し、sel_registerName 関数を使って存在しているセレクタを取得できます。
セレクタを使うとき、sel_registerName が返す値か、Objective-C のコンパイラディレクティブ @selector() を使わなければなりません。単純に C 文字列を SEL にキャストすることはできません。
Method
Method はクラスで定義されているメソッドを表現する構造体で Opaque Type です。リファレンスには
としかありませんが runtime.h にはさらに
struct objc_method { SEL method_name OBJC2_UNAVAILABLE; char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; }とあります。OBJC2_UNAVAILABLE は Objective-C 2.0 では無効ということのようで、Objective-C 2.0 の環境ではこの構造体に直接アクセスはできません。Method 構造体にのデータにアクセスするには専用(method_*)のランタイム関数を使ってやればよしです。
めも
http://opensource.apple.com/
2011年11月22日火曜日
Method Swizzling
Mac OSX で NSColor -> CGColor の変換をよく使いますが NSColor は CGColor を返すメソッドがありません(*1)せめて NSColor のメソッドが CGColor を返してくれるようになったら嬉しい。そんなわけで NSColor が CGColor を返してくれるようにカテゴリで拡張します。まずはソースコードから。
*1 NSColor のメソッドに - (CGColorRef)CGColor が追加されました。10.8 以降 使用できます。
NSColor+CGColor.h
NSColor+CGColor.m
こう考えてみた
preDealloc で擬似的なクラス変数に見立てた CGColorCollection を管理してやります。CGColorCollection が CGColor を持たなければメソッドの実装を元に戻してやります。ランタイムは NSColor の dealloc だと思って preDealloc を呼出しているので、最終的に本来呼ばれるべき dealloc を実装から直接呼んでやります。
*1 NSColor のメソッドに - (CGColorRef)CGColor が追加されました。10.8 以降 使用できます。
NSColor+CGColor.h
#import <Foundation/Foundation.h> @interface NSColor (CGColor) - (CGColorRef)CGColor; @end
NSColor+CGColor.m
#import "NSColor+CGColor.h" #import <objc/runtime.h> @interface NSColor (Swizzling) - (void)methodToExchangeImplementation; - (void)preDealloc; @end @interface NSColor (Accessor) - (void)initializeCGColorCollection; - (void)releaseColorCollection; - (void)setCGColorRef:(CGColorRef)colorRef; @end @implementation NSColor (Swizzling) static IMP PRE_DEALLOC_IMPLEMENTATION = NULL; static IMP DEALLOC_IMPLEMENTATION = NULL; - (void)methodToGetImplementation { // メソッド構造体を取得する Method preDealloc = class_getInstanceMethod([self class], @selector(preDealloc)); Method dealloc = class_getInstanceMethod([self class], @selector(dealloc)); // メソッド構造体からメソッド実装を取得する PRE_DEALLOC_IMPLEMENTATION = method_getImplementation(preDealloc); DEALLOC_IMPLEMENTATION = method_getImplementation(dealloc); } - (void)methodToExchangeImplementation { if (PRE_DEALLOC_IMPLEMENTATION == NULL || DEALLOC_IMPLEMENTATION == NULL) { [self methodToGetImplementation]; } // メソッド構造体を取得する Method preDealloc = class_getInstanceMethod([self class], @selector(preDealloc)); Method dealloc = class_getInstanceMethod([self class], @selector(dealloc)); // メソッドの実装を互いに入れかえる method_exchangeImplementations(preDealloc, dealloc); } - (void)preDealloc { // 辞書に CGColorRef を加えたオブジェクトは dealloc の前に解放する。 [self setCGColorRef:NULL]; [self releaseColorCollection]; // dealloc を実装から呼ぶ。 DEALLOC_IMPLEMENTATION(self, _cmd); } @end @implementation NSColor (Accessor) static NSMutableDictionary *CGColorCollection = nil; - (void)initializeCGColorCollection { @synchronized (self) { if (!CGColorCollection) { CGColorCollection = [[NSMutableDictionary dictionary] retain]; [self methodToExchangeImplementation]; } } } - (void)releaseColorCollection { @synchronized (self) { if ([CGColorCollection count] == 0) { [CGColorCollection release]; CGColorCollection = nil; [self methodToExchangeImplementation]; } } } - (void)setCGColorRef:(CGColorRef)newColorRef { NSString *aKey = [NSString stringWithFormat:@"%p",self]; @synchronized (self) { NSValue *value = [CGColorCollection valueForKey:aKey]; if (value) { CGColorRef colorRef = (CGColorRef )[value pointerValue]; [CGColorCollection removeObjectForKey:aKey]; CGColorRelease(colorRef); } if (newColorRef != NULL) { [CGColorCollection setValue:[NSValue valueWithPointer:newColorRef] forKey:aKey]; } } } @end @implementation NSColor (CGColor) - (CGColorRef)CGColor { [self initializeCGColorCollection]; // 現在のカラーの情報を取得する。 NSColorSpace *colorSpace = [self colorSpace]; size_t numberOfComponents = (size_t)[self numberOfComponents]; CGFloat *components = (CGFloat *)calloc(numberOfComponents, sizeof(CGFloat)); [self getComponents:components]; // CGColorRef を生成する。 CGColorRef colorRef = CGColorCreate([colorSpace CGColorSpace], components); free(components); // 自身をキーに生成した CGColorRef を辞書に加える。 [self setCGColorRef:colorRef]; return colorRef; } @end
こう考えてみた
- 単に NSColor からCGColor オブジェクトのインスタンスを生成するのでなく、NSColor の寿命に応じて 生成した CGColor の寿命もシンクロさせる。
- カテゴリはインスタンス変数の追加が出来ないので CGColor オブジェクトを適当なスコープ内に定義したグローバル変数で管理する。
preDealloc で擬似的なクラス変数に見立てた CGColorCollection を管理してやります。CGColorCollection が CGColor を持たなければメソッドの実装を元に戻してやります。ランタイムは NSColor の dealloc だと思って preDealloc を呼出しているので、最終的に本来呼ばれるべき dealloc を実装から直接呼んでやります。
2011年11月21日月曜日
It Is Possible To Detach My Mind from Main Thread
NSThreadの
について。
ガベージコレクトされないアプリケーションでは、aSelector で与えるメソッドが新たに切り離されたスレッドのために、自動解放プールを設定して、セレクタの実行が終了する前にプールを解放する責任があります。ガベージコレクトされるアプリケーションは自動解放プールを作成する必要はありません。
切り離されたスレッドを実行している間 aTarget と anArgument が与えるオブジェクトは保持され、そのあと解放されます。切り離されたスレッドは aTarget オブジェクトの aSelector で与えるメソッドが完了するとすぐに(クラスメソッドの + (void)exit を使用して)終了します。
このスレッドがアプリケーションで最初に切り離されたスレッドの場合、このメソッドはデフォルトの通知センタに nil オブジェクトをともなって NSWillBecomeMultiThreadedNotification を投函します。
つまり
ガベージコレクションをしないアプリケーションでは、指定したセレクタ内で、自動解放プールの管理をしなさいねとのこと。例えば
について。
ガベージコレクトされないアプリケーションでは、aSelector で与えるメソッドが新たに切り離されたスレッドのために、自動解放プールを設定して、セレクタの実行が終了する前にプールを解放する責任があります。ガベージコレクトされるアプリケーションは自動解放プールを作成する必要はありません。
切り離されたスレッドを実行している間 aTarget と anArgument が与えるオブジェクトは保持され、そのあと解放されます。切り離されたスレッドは aTarget オブジェクトの aSelector で与えるメソッドが完了するとすぐに(クラスメソッドの + (void)exit を使用して)終了します。
このスレッドがアプリケーションで最初に切り離されたスレッドの場合、このメソッドはデフォルトの通知センタに nil オブジェクトをともなって NSWillBecomeMultiThreadedNotification を投函します。
つまり
ガベージコレクションをしないアプリケーションでは、指定したセレクタ内で、自動解放プールの管理をしなさいねとのこと。例えば
- (IBAction)saveData:(id)sender { [NSThread detachNewThreadSelector:@selector(saveBitmap) toTarget:bitmapController withObject:nil]; }みたいなのがあって、ターゲットのオブジェクトでは
- (void)saveBitmap { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; /* 処理 */ [pool drain]; }を実装します。 また、10.5 以降ではこのクラスメソッドだけでなく NSThread のインスタンスが生成できるようになりました。NSOperation と同様の制御が可能です。
2011年11月7日月曜日
NSProgressIndicator on Sheet
NSProgressIndicator をシート上で動かそうとしたときに動きませんでした。
このメソッドは指定されたシートのためのモーダル・イベント・ループを同期的に実行します。表示するシートをキーウィンドウにして、実行ループを開始します。そして、そのためのイベントを処理します。アプリケーションが実行ループ中のあいだ、シートに関連付けされてない限り、他のどんなイベント(マウス、キーボード、またはウィンドウ-クローズ・イベントを含む)にも応答しません。また、モーダル実行ループに関連付けられていないどんな(タイマー発動のような)タスクも実行しません。つまり、このメソッドはイベントを処理するために必要なCPU時間を費し、それらをモーダル・ウィンドウに関連付けられたアクション・メソッドへ送ります。
ということで、シート上のインジケータの更新を反映させるには、
このメソッドは指定されたシートのためのモーダル・イベント・ループを同期的に実行します。表示するシートをキーウィンドウにして、実行ループを開始します。そして、そのためのイベントを処理します。アプリケーションが実行ループ中のあいだ、シートに関連付けされてない限り、他のどんなイベント(マウス、キーボード、またはウィンドウ-クローズ・イベントを含む)にも応答しません。また、モーダル実行ループに関連付けられていないどんな(タイマー発動のような)タスクも実行しません。つまり、このメソッドはイベントを処理するために必要なCPU時間を費し、それらをモーダル・ウィンドウに関連付けられたアクション・メソッドへ送ります。
ということで、シート上のインジケータの更新を反映させるには、
for (NSInteger index = 0; index < 1000; index++) { [indicator incrementBy:1.0]; [indicator displayIfNeeded]; }ウィンドウとかビューとかに直接 display* を送信してやります。
2011年11月3日木曜日
Sometimes Talk About The Past...
♪ 時には昔の話をしようか ♪
そんな気分のときってあると思います。 クラスメソッドの initialize を実装してみましたが2回呼ばれているようです。10.6 Xcode 3.2.6 の話。
特定のクラスが initialize を実装していない場合、スーパークラスの initialize メソッドは2回呼出されます。スーパークラスが1回と initialize を実装していないサブクラスが1回です。クラスが一度だけのクラス固有の初期化を実行することを確実にするには、次の例のように初期化を実装します。
実際この例のように実装してみたら呼出しが1回になりました。2011-09-08 に改訂されている NSObject Class Reference での initialize ではこの記述がなかったので、10.7 Xcode 4 では変更されているのかも。
ところで
もともと NSUserDefaults を使って NSRegistrationDomein にアプリケーションの初期値を設定しようと思っていました。
アプリケーションのデフォルトの動作を登録するために、NSUserDefaults の共有インスタンスを取得し、デフォルト値を登録します。これを行うのに良い場所は、デフォルト値を使用するクラスの initialize メソッドです。次の例は DeleteBackup という名前で YES の値を登録します。
とありましたが、この Topics は 2011-10-12 で更新されて Preferences and Settings Programming Guide という名前になりました。そしてこの記述はなくなりました。
♪ 今でも 同じように 見果てぬ夢を描いて 走り続けているよね どこかで ♪
そんな気分のときってあると思います。 クラスメソッドの initialize を実装してみましたが2回呼ばれているようです。10.6 Xcode 3.2.6 の話。
特定のクラスが initialize を実装していない場合、スーパークラスの initialize メソッドは2回呼出されます。スーパークラスが1回と initialize を実装していないサブクラスが1回です。クラスが一度だけのクラス固有の初期化を実行することを確実にするには、次の例のように初期化を実装します。
@implementation MyClass + (void)initialize { if ( self == [MyClass class] ) { /* put initialization code here */ } }
実際この例のように実装してみたら呼出しが1回になりました。2011-09-08 に改訂されている NSObject Class Reference での initialize ではこの記述がなかったので、10.7 Xcode 4 では変更されているのかも。
ところで
もともと NSUserDefaults を使って NSRegistrationDomein にアプリケーションの初期値を設定しようと思っていました。
User Defaults Programming Topics "Setting a Default in the NSRegistrationDomain"
アプリケーションのデフォルトの動作を登録するために、NSUserDefaults の共有インスタンスを取得し、デフォルト値を登録します。これを行うのに良い場所は、デフォルト値を使用するクラスの initialize メソッドです。次の例は DeleteBackup という名前で YES の値を登録します。
+ (void)initialize { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"YES" forKey:@"DeleteBackup"]; [defaults registerDefaults:appDefaults]; }
とありましたが、この Topics は 2011-10-12 で更新されて Preferences and Settings Programming Guide という名前になりました。そしてこの記述はなくなりました。
♪ 今でも 同じように 見果てぬ夢を描いて 走り続けているよね どこかで ♪
2011年10月31日月曜日
Loading Objective-C Classes
NSBundle でアプリケーションバンドル内のクラスをロードします。NSBundle のロードのためのメソッドは Objective-C で書かれたのクラスのみで C++ その他の言語で書かれたものは使用できません。
- (void)loadClass { Class foo; id bar; NSBundle *bundle = [NSBundle mainBundle]; if ( foo = [bundle classNamed:@"Foo"] ) { bar = [[foo alloc] init]; } }
SyntaxHighlighter on Blogger
Blogger に SyntaxHighlighter をホスティングで導入しましたが、細かいスタイルの変更はどうしたらよいのでしょうか? 直接サーバにインストールして使用している場合は "shCoreDefault.css" を編集しているようです。しかしホスティングではそうはまいりません。Blogger ではどうするか?
テンプレート -> HTMLの編集
で解決しようと思いましたら、直接HTMLを編集するより、よかったらテンプレートデザイナーを使ってね、と出てきました。そこで
テンプレート -> カスタマイズ -> アドバンス -> CSSの追加
/* SyntaxHighlighter 行ごとの色の変更 */ .syntaxhighlighter .line.alt2 { background-color: #f7f7f7 !important; } /* SyntaxHighlighter 行番号とソースコードの間の線の幅と色*/ .syntaxhighlighter .gutter .line { border-right: 3px solid #ededed !important; }と記述しましたとさ。
2011年7月29日金曜日
イメージを描画する(11.3)
bpf のフィルタを設定したい。そこで bpf(4) を見ます。オペコード、アキュームレータ、インデックスレジスタ... アセンブリ言語?疑似マシンへの命令は僕には難しすぎます。そんな僕のために libpcap は疑似マシン命令を手軽にコンパイルしてくれるということなので頼ります。
/*事前に/dev/bpf* はオープンされていて、ネットワークインターフェイス(struct ifreq ifr)がアタッチされている。*/ char errorBuffer[PCAP_ERRBUF_SIZE]; bpf_u_int32 mask; bpf_u_int32 net; if ((pcap_lookupnet(ifr.ifr_name, &net, &mask, errorBuffer)) == -1 ) { fprintf(stderr,"pcap_lookupnet:%s",errorBuffer); net = 0; mask = 0; } u_int dataLinkType; u_int bufferLength; ioctl(bpf, BIOCGDLT, &dataLinkType); ioctl(bpf, BIOCGBLEN, &bufferLength); pcap_t *tmpHandle = pcap_open_dead(dataLinkType, bufferLength); if (!tmpHandle) { fprintf(stderr,"pcap_open_dead:NULL"); } struct bpf_program *bpfProgram = (struct bpf_program *)malloc(sizeof(struct bpf_program)); const char *filterExpression = "ether proto \\ip"; int optimize = 0; if (pcap_compile(tmpHandle, bpfProgram, filterExpression, optimize, mask) == -1 ) { fprintf(stderr,"pcap_compile:%s",pcap_geterr(tmpHandle)); } pcap_close(tmpHandle); ioctl(bpf, BIOCSETF, bpfProgram); pcap_freecode(bpfProgram);
2011年7月19日火曜日
SyntaxHighlighter on Blogger
ソースコードが見にくいので SyntaxHighlighter を Blogger で使えるようにします。
SyntaxHighlighter -> integration から ここのサイトを参考にして Objective-C を加えたのが以下。デザイン-> HTMLの編集で <HEAD> の前に挿入。
C
Objective-C
行ごとに色を変る方法は確認中。
SyntaxHighlighter -> integration から ここのサイトを参考にして Objective-C を加えたのが以下。デザイン-> HTMLの編集で <HEAD> の前に挿入。
<!--SYNTAX HIGHLIGHTER BEGINS--> <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/> <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'></script> <script src='http://www.undermyhat.org/blog/wp-content/uploads/2009/09/shBrushObjectiveC.js' type='text/javascript'></script> <script language='javascript'> SyntaxHighlighter.config.bloggerMode = true; SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf'; SyntaxHighlighter.all(); </script> <!--SYNTAX HIGHLIGHTER ENDS-->
C
int main (int argc, char const *argv[]) { printf("Hello world!"); return 0; }
Objective-C
#import <Cocoa/Cocoa.h> @interface TestObject : NSObject { NSMutableArray *testArray; } @property (readonly) NSMutableArray *testArray; - (void)setTestArray:(NSMutableArray *)array;
行ごとに色を変る方法は確認中。
2011年7月15日金曜日
イメージを描画する(11.2)
インターフェイスと bpf デバイスファイルのアタッチ
めも
また読込みは bpf(4) Mac OS X Man page より bpf_hdr について。
The following structure is prepended to each packet returned by read(2):
"以下の構造体(bpf_hdr)はread(2) によって戻される各パケットの先頭に追加されます。"
Additionally, individual packets are padded so that each starts on a word boundary. This requires that an application has some knowledge of how to get from packet to packet. The macro BPF_WORDALIGN is defined in to facilitate this process. It rounds up its argument to the nearest word aligned value (where a word is BPF_ALIGNMENT bytes wide).
p = (char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)
考え中。
// kernel -> bpf デバイスファイルへのデータコピーの状態
struct bpf_stat status;
ioctl(bpf, BIOCGSTATS,&status);
NSLog(@"receive:%d, drop:%d",status.bs_recv, status.bs_drop);
bs_drop: パケットトラフィックがついていっていないとカーネルがドロップする。その数。
めも
///// bpf デバイスファイルのオープン ///// NSArray *devices; NSString *deviceFile = @"/dev/bpf"; int bpf; [deviceFile completePathIntoString:nil caseSensitive:YES matchesIntoArray:&devices filterTypes:nil]; for (NSString *device in devices) { bpf = open([device UTF8String],O_RDONLY,0); if (bpf != -1 ) { break; } } // 使用するネットワークインターフェイスを用意する e.g "en0" struct ifreq ifr; bzero(ifr.ifr_name, sizeof(char) * IFNAMSIZ); strncpy(ifr.ifr_name, argv[1], IFNAMSIZ); // デバイスファイルとネットワークインターフェイスを接続、設定する u_int isImmediately = 1; u_int isIO = 0; // Input only; u_int bufferLength = (u_int)([[NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding] intValue] ioctl(bpf, BIOCSBLEN, &bufferLength); // 長さ ioctl(bpf, BIOCSETIF, &ifr); // 接続 ioctl(bpf, BIOCIMMEDIATE, &isImmediately); // すぐに書出す ioctl(bpf, BIOCSSEESENT, &isIO); // インプットのみあとは read(2) でデバイスファイルから読込む。
また読込みは bpf(4) Mac OS X Man page より bpf_hdr について。
The following structure is prepended to each packet returned by read(2):
"以下の構造体(bpf_hdr)はread(2) によって戻される各パケットの先頭に追加されます。"
Additionally, individual packets are padded so that each starts on a word boundary. This requires that an application has some knowledge of how to get from packet to packet. The macro BPF_WORDALIGN is defined in
p = (char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)
考え中。
// kernel -> bpf デバイスファイルへのデータコピーの状態
struct bpf_stat status;
ioctl(bpf, BIOCGSTATS,&status);
NSLog(@"receive:%d, drop:%d",status.bs_recv, status.bs_drop);
bs_drop: パケットトラフィックがついていっていないとカーネルがドロップする。その数。
2011年7月10日日曜日
イメージを描画する(11.1)
ネットワークインターフェイスの一覧を取得したい。
めも
めも
/////////////// ネットワークインターフェイスの取得 /////////////// int socketFD,length, lastLength; char *buffer; struct ifconf ifc; socketFD = socket(AF_INET, SOCK_DGRAM, 0); lastLength = 0; length = sizeof(struct ifreq) * 100; NSLog(@"length:%d",length); for (; ;) { buffer = (char *)calloc(length, sizeof(char)); ifc.ifc_len = length; ifc.ifc_ifcu.ifcu_buf = buffer; if ( ioctl(socketFD, SIOCGIFCONF, &ifc) < 0) { int erroNumber = errno; NSLog(@"%s",strerror(erroNumber)); } else { if (ifc.ifc_len == lastLength) { break; } lastLength = ifc.ifc_len; } length += sizeof(struct ifreq) * 10; free(buffer); } struct ifreq *ifr = (struct ifreq *)buffer; int next = 0; /////////////// 表示してみる /////////////// while (ifr < (struct ifreq *)(buffer + lastLength)) { ifr = (struct ifreq *)(buffer + next); NSLog(@"interface:%s",ifr->ifr_name); next += IFNAMSIZ + ifr->ifr_ifru.ifru_addr.sa_len; } free(buffer); close(socketFD);同じのがいっぱい出た。
2011年6月28日火曜日
イメージを描画する(10)
あなたの瞳の色が僕の中でどんな色で見えているのか伝えたい、写真家にもそんなときってあると思います。というわけでこんなものを作ります。
このイメージを
こう表示する。
-- 途中です。改訂します。 --
/* めも
RGB のカラー・ガモット(color gamut)の各頂点を情報(三刺激値?)を取得する。
プロファイルのデータから rXYZ, gXYZ, bXYZ を得る。
Specification ICC.1:2004-10-10 (Profile Version 4.2.0.0)
redMatrixColumnTag, greenMatrixColumnTag and blueMatrixColumnTag は XYZType.
-- XYZType Encoding --
0-3 4byte 'XYZ ' type sigunature.
4-7 4Byte reserved, must be set to 0.
8-end - an array of XYZ number. XYZNumber
-- XYZ Number --
0-3 4Byte CIE X s15Fixed16Number
4-7 4Byte CIE Y s15Fixed16Number
8-11 4Byte CIE Z s15Fixed16Number
-- s15Fixed16Number --
Number Encoding
-32768.0 80000000h
0 00000000h
1.0 00010000h
32767 + (65535/65536) 7FFFFFFFh
前半分が符号付き整数、後ろ半分が小数だけど、整数値を65536で割った値。つまり
iiiiiiiiiiiiiiii + ffffffffffffffff / 65536
7 Profile requirements
a) All profile data shall be encoded as big-endian,
ColorSync Manager API
CMGetPartialProfileElement //ColorSyncDeprecated.h 非推奨
elementData の値がリトルエンディアンで戻ったので EndianS32_BtoN にかけた。
*/
このイメージを
こう表示する。
-- 途中です。改訂します。 --
/* めも
RGB のカラー・ガモット(color gamut)の各頂点を情報(三刺激値?)を取得する。
プロファイルのデータから rXYZ, gXYZ, bXYZ を得る。
Specification ICC.1:2004-10-10 (Profile Version 4.2.0.0)
redMatrixColumnTag, greenMatrixColumnTag and blueMatrixColumnTag は XYZType.
-- XYZType Encoding --
0-3 4byte 'XYZ ' type sigunature.
4-7 4Byte reserved, must be set to 0.
8-end - an array of XYZ number. XYZNumber
-- XYZ Number --
0-3 4Byte CIE X s15Fixed16Number
4-7 4Byte CIE Y s15Fixed16Number
8-11 4Byte CIE Z s15Fixed16Number
-- s15Fixed16Number --
Number Encoding
-32768.0 80000000h
0 00000000h
1.0 00010000h
32767 + (65535/65536) 7FFFFFFFh
前半分が符号付き整数、後ろ半分が小数だけど、整数値を65536で割った値。つまり
iiiiiiiiiiiiiiii + ffffffffffffffff / 65536
7 Profile requirements
a) All profile data shall be encoded as big-endian,
ColorSync Manager API
CMGetPartialProfileElement //ColorSyncDeprecated.h 非推奨
elementData の値がリトルエンディアンで戻ったので EndianS32_BtoN にかけた。
*/
2011年6月20日月曜日
イメージを描画する(9)
あなたの瞳は世界をどんなふうに見るの?奇麗な瞳をみられたら写真家にもそんな気持ちになるときがあると思います。というわけで、こんなものをつくります。
Photoshop(CS3)では ”色の校正” プレビュー(5.0.3)では ”プロファイルを使ってソフトプルーフ” 、つまりソフトプルーフ機能を単独で実装します。
NSBitmapImageRep
表示だけのシステムなので、なにかないか探してみますとこんなものがありました。
すてき。長いです。画像を描画意図(rendering intent)で別の色空間に変換してくれます。ここに色校正に使うディスプレイ・プロファイルとアウトプット・プロファイルからカラースペースを作って渡してやればよさそうです。なお 10.6 以降です。
NSColorSpace
NSColorSpace にはプロファイルのクラスごとにカラースペースを生成してくれるメソッドがないので
を使ってColorSync プロファイルから作成してやれば良さそうです。引数が (void *)prof となっていますが、リファレンスは CMProfileRef わたすべしとなっています。なるほど。
ColorSync Manager API
目的は CMProfileRef を取得することです。
第1引数は戻ったときにプロファイルがはいります。なので第2引数の CMProfileLocation を取得して渡してやればよいですが、長旅になりそうな予感!
少し寄り道 CMIterateColorSyncFolder
インストースされているプロファイルの情報を提供してくれる API はないものでしょうか。そんな僕のために CMIterateColorSyncFolder 関数がありました。すべての利用可能なプロファイルからプロファイルごとの情報を確認できます。
第1引数は CMIterateColorSyncFolder ルーチンのなかで呼出されるコールバック関数のポインタになります。
第2引数はキャッシュの設定です。CMIterateColorSyncFolder 初めて呼出すときは0をセットしたポインタを渡せとあります。内部の seed と一致しなかったな場合はプロファイルごとに一度のコールバックを呼出すとあります。
第3引数は戻ってきたときに利用可能なプロファイルの数が入れられます。
第4引数は任意のデータへのポインタを指定します。この値は第1引数のコールバックが呼出されるたびに渡されます。なのでコールバック内で参照する必要のあるデータがある場合は設定します。
今度は CMProfileIterateUPP!
CMIterateColorSyncFolder の第1引数 CMProfileIterateUPP は
となっていて CMProfileIterateProcPtr は
です。第1引数にはプロファイルに関連するデータ構造体です。第2引数にはCMIterateColorSyncFolder の第4引数で設定したデータへのポインタがそのままやってきます。
CMProfileLocation を求めて
CMProfileIterateData はどうなっているのでしょうか。
CMProfileLocation ありました。これを CMOpenProfile に渡してやれば CMProfileRef が取得できます。さらに CM2Header 構造体の
OSType profileClass でプロファイルのクラスの情報があります。
cmDisplayClass と cmOutputClass を使ってプロファイルのクラスを選別できそうです。
それでは
戻り値のチェックをしていません。
Interface Builder での作業
その他
指定したカラースペースに変換したビットマップを生成するのに ColorSync Manager API だけでやろうとするとけっこうめんどうです。NCWConcatColorWorld か CWConcatColorWorld を使って CMWorldRef を作成してやります。それを CWMatchBitmap にかけてやってビットマップを作成すれば良いと思います。また、この間に使用するいくつかの構造体を定義してやらなければなりません。
Photoshop(CS3)では ”色の校正” プレビュー(5.0.3)では ”プロファイルを使ってソフトプルーフ” 、つまりソフトプルーフ機能を単独で実装します。
NSBitmapImageRep
表示だけのシステムなので、なにかないか探してみますとこんなものがありました。
すてき。長いです。画像を描画意図(rendering intent)で別の色空間に変換してくれます。ここに色校正に使うディスプレイ・プロファイルとアウトプット・プロファイルからカラースペースを作って渡してやればよさそうです。なお 10.6 以降です。
NSColorSpace
NSColorSpace にはプロファイルのクラスごとにカラースペースを生成してくれるメソッドがないので
を使ってColorSync プロファイルから作成してやれば良さそうです。引数が (void *)prof となっていますが、リファレンスは CMProfileRef わたすべしとなっています。なるほど。
ColorSync Manager API
目的は CMProfileRef を取得することです。
第1引数は戻ったときにプロファイルがはいります。なので第2引数の CMProfileLocation を取得して渡してやればよいですが、長旅になりそうな予感!
少し寄り道 CMIterateColorSyncFolder
インストースされているプロファイルの情報を提供してくれる API はないものでしょうか。そんな僕のために CMIterateColorSyncFolder 関数がありました。すべての利用可能なプロファイルからプロファイルごとの情報を確認できます。
第1引数は CMIterateColorSyncFolder ルーチンのなかで呼出されるコールバック関数のポインタになります。
第2引数はキャッシュの設定です。CMIterateColorSyncFolder 初めて呼出すときは0をセットしたポインタを渡せとあります。内部の seed と一致しなかったな場合はプロファイルごとに一度のコールバックを呼出すとあります。
第3引数は戻ってきたときに利用可能なプロファイルの数が入れられます。
第4引数は任意のデータへのポインタを指定します。この値は第1引数のコールバックが呼出されるたびに渡されます。なのでコールバック内で参照する必要のあるデータがある場合は設定します。
今度は CMProfileIterateUPP!
CMIterateColorSyncFolder の第1引数 CMProfileIterateUPP は
となっていて CMProfileIterateProcPtr は
です。第1引数にはプロファイルに関連するデータ構造体です。第2引数にはCMIterateColorSyncFolder の第4引数で設定したデータへのポインタがそのままやってきます。
CMProfileLocation を求めて
CMProfileIterateData はどうなっているのでしょうか。
CMProfileLocation ありました。これを CMOpenProfile に渡してやれば CMProfileRef が取得できます。さらに CM2Header 構造体の
OSType profileClass でプロファイルのクラスの情報があります。
cmDisplayClass と cmOutputClass を使ってプロファイルのクラスを選別できそうです。
それでは
戻り値のチェックをしていません。
DrawingImage_9_AppDelegate.h
DrawingImage_9_AppDelegate.m
DISourceImageView.h
DISourceImageView.m
DIProofImageView.h
DIProofImageView.m
Interface Builder での作業
その他
指定したカラースペースに変換したビットマップを生成するのに ColorSync Manager API だけでやろうとするとけっこうめんどうです。NCWConcatColorWorld か CWConcatColorWorld を使って CMWorldRef を作成してやります。それを CWMatchBitmap にかけてやってビットマップを作成すれば良いと思います。また、この間に使用するいくつかの構造体を定義してやらなければなりません。
登録:
投稿 (Atom)