高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technote 1144

Writing Custom Hoses For LaserWriter 8.6


 

目次


DTP タイプの識別

ホースプラグインの追加

ホースタイプの登録

要約

関連ファイルのダウンロード
LaserWriter 8.6 では PAP、LPR、IrDA など、さまざまなデスクトッププリンタのタイプがサポートされています。それぞれのデスクトッププリンタは、対応する物理プリンタ、RIP、またはその他のポストプリンティングプロセッサとの間でデータ通信を行うための独自の方法を持ちます。カスタム「ホース」の導入により、LaserWriter 8.6 にはさまざまな通信方法をインプリメントするための共有ライブラリと、これらのライブラリを DTP タイプに基づいて動的にロードする機能が追加されました。このテクニカルノートではデベロッパ向けにカスタムホースの仕様の概要を示します。

DTP タイプの識別
それぞれの LaserWriter 8 デスクトッププリンタには、プリンタの名前やその他の関連する通信パラメータだけでなく、DTP のタイプを識別する 'PAPA' リソースが対応しています。DTP タイプは 4 バイト定数の形式をとります。'PAP ' タイプを除き、すべての DTP タイプは '=XXX' (たとえば、'=Hld' または '=Fil') という形式を持つ必要があります。これは、LaserWriter 8.5.1 ドライバのリリースとともに従来の 'PAPA' リソースが拡張されたためです。新しい DTP タイプのシグネチャは、従来の 103 バイトの 'PAPA' リソースに含まれるゾーン文字列を置き換え、'PAPA' リソースの適切な 'TYPE' タグにマップします。'PAPA' リソースの内容については、「Technote 1115: LaserWriter 8.5.1: 拡張 'PAPA' リソース」を参照してください。



LaserWriter 8.6 の DTP タイプ
LaserWriter 8.6 とともに出荷されている PrintingLib では、次の DTP タイプがサポートされています。

'PAP '
プリンタとのデータのやり取りは AppleTalk の PAP (Printer Access Protocol) を使って実行されます。プリンタの AppleTalk 名、タイプ、ゾーンは「Technote 1115: LaserWriter 8.5.1: 拡張 'PAPA' リソース」で説明されているように、従来の 'PAPA' リソースとの互換部分に格納されています。

'=Hld'
「保留」デスクトッププリンタは、それに対応する通信モジュールが存在しないという点で独自のデスクトッププリンタです。保留デスクトッププリンタがデスクトップスプールファイルを PostScript に変換することはなく、スプール ファイルを単純にキューに入れるだけです。保留デスクトッププリンタのキューに入っているスプールファイルを印刷するには、そのファイルを別のタイプのデスクトッププリンタのキューに移動する必要があります。

'=Fil'
「ファイルに保存」デスクトッププリンタは、PostScript、EPS、または PDF 出力をファイルに書き込みます。

注意:
PDF を出力するためには、あらかじめ Adobe の Acrobat Distiller をインストールしておく必要があります。

'=LPR'
LPR デスクトップ プリンタは Unix の LPD プロトコルを使用し、TCP/IP を介してプリントサーバとの間でデータをやり取りします。このプロトコルの詳細については、「RFC 1179(http://ds.internic.net/ds/dspg1intdoc.html) を参照してください。

'=Cst'
カスタムアプリケーションデスクトッププリンタは PostScript をディスクに書き込んだ後、PostScript ジョブを処理するアプリケーションを起動します。カスタム DTP の詳細については、「Technote 1113: デスクトッププリンタユーティリティのカスタマイズ」を参照してください。

'=Ird'
PostScript ジョブは赤外線リンクを使って IrDA 対応のプリンタに転送されます。LaserWriter 8 は http://www.irda.org/ で概説されている IrDA 仕様に準拠しています。

注意:
LaserWriter 8 ドライバの将来のリリースには USB および FireWire のサポートが組み込まれる予定です。

ホースプラグインの追加
ジョブをデスクトッププリンタに印刷するとき、LaserWriter 8.6 では 4 バイトの DTP タイプを取得し、さらに、それに対応したホースを含む共有ライブラリを検索します。LaserWriter 8.6 は次の順序でライブラリを検索します。

  1. システムの“プリントプラグイン”フォルダ (“機能拡張”フォルダ内)
  2. PrintingLib ファイル

デスクトッププリンタのタイプは、「Technote 1129: LaserWriter 8.5.1: プリンタ設定ライブラリ (SettingsLib)」で説明されているように、SettingsLibpsGetDTPType() 呼び出しを使って取得されます。この後、DTP タイプに対応するサブタイプを含んだ 'hose' タイプのプリンティングプラグインを検索するため、Printing Plug-in Manager が使用されます (詳細については、近刊予定のテクニカルノートを参照してください)。

カスタムホースをはじめ、Printing Plug-ins Managerによって管理されるプラグインファイルは、対象となるファイルに含まれるプラグインに関する情報を含んだ ID -8192 の 'PLGN' タイプのリソースを持っている必要があります。このリソースがないと、プラグインファイルは使用することができず、LaserWriter 8.6 ドライバによって無視されます。また、プラグインはファイルのデータフォークに格納されているコードフラグメントを記述する標準的な 'cfrg' リソースを持っている必要があります。

'PLGN' リソースには、このファイルに含まれる共有ライブラリの数に関する情報が含まれます。また、それぞれの共有ライブラリについて、対象となるプラグインのタイプ、ライブラリが処理するサブタイプ、およびライブラリ名が含まれます。

'PLGN' リソースは以下のとおりです。

 short num;                // 共有ライブラリの数
  PluginLibInfo libInfo[num];

PluginLibInfo 構造体は以下のとおりです。

  typedef struct PluginLibInfo{
   SettingsDataType type;
   SettingsDataSubType subtype;
   unsigned char libraryName[ ];  // Pascal 文字列
                                 // ワードアライン
  }PluginLibInfo;

type: PluginLibInfo によって記述されるプラグインのタイプ
subtype: PluginLibInfo によって記述されるプラグインで処理できるデータのサブタイプ
libraryName: この PluginLibInfo によって記述されるプラグインファイル内のコードフラグメントのライブラリ名

ResEdit で 'PLGN' リソースを編集できるように、PrintingLib 8.6 には 'TMPL' リソースが用意されています。タイプフィールドは 'hose' で、サブタイプは '=XXX' にしてください。ここで XXX はサポートされている DTP のカスタム登録タイプを表します。登録の詳細については、後述の「ホースタイプの登録」を参照してください。libraryName はホースをインプリメントするデータフォーク内のコードフラグメントの名前と一致するようにしてください。

ホースインタフェース

hoseOpen
ホースフラグメントは単一のエントリポイントをエクスポートする必要があります。このエントリポイントである hoseOpen() は次のシグネチャを持ちます。

OSStatus hoseOpen(HoseInfo *hoseInfo, const BufCallbacks *callbacks, Collection hints, Handle papaH);

hoseOpen ルーチンの主要なジョブは HoseInfo で指される構造体を設定することです。 /* HoseInfo 構造体は hoseOpen プロシージャによって設定されます。この構造体はホースのバッファ要件と、ホースの読み込み、書き込み、クローズに必要となる関数ポインタを記述します。

 */
 typedef struct{
  HoseOutProc out;        // バッファを書き込むために呼び出されます。
  HoseInProc in;          // バッファを読み込むために呼び出されます。
  HoseIdleProc idle;      // 周期的に呼び出されます。
  HoseCloseProc close;    // 接続を切断するために呼び出されます。
  HoseConnProc connState; // このプロシージャは現在の接続のステータスを返します。
  HoseStatusProc status;  // ホースの現在のステータス文字列を返します。
  HoseDisposeProc dispose;// ホースはすべてのメモリを解放する必要があります。
  Size bufSize;           // 割り当てられた各データバッファのサイズ。
  long minBufs;           // ホースはこの数のバッファを必要とします。
                          // バッファに割り当てるメモリが十分でないと、
                          // クライアントは memFullErr を返すことになります。
  long maxBufs;           // これを超えるバッファを割り当てることはありません。
  void *refcon;           // ホースルーチンに渡されるポインタ。
 }HoseInfo;

ホースはまず、その機能をインプリメントするホース内のルーチンへのネイティブ関数ポインタを使って、out、in、idle、close、connState、status、および dispose の各フィールドを設定する必要があります (たとえば、PPC コードは PPC 関数ポインタを提供し、68KCFM コードは 68KCFM 関数ポインタを提供します。なお、クラシック 68K 関数ポインタはサポートされていません)。ホースの関数ポインタの設定に加えて、さらに bufSize、minBufs、および maxBufs フィールドを設定して、ホースのバッファ要件を記述する必要があります。最後に、ホース独自のストレージへのポインタを使って refcon フィールドを設定します。

ホースを呼び出してデータを転送する前に、ホースクライアントはパフォーマンスを向上させるためにバッファリングを提供します。このようなバッファリングを行うため、ホースは 1 つの転送バッファと 1 つの受信バッファを同時に処理する必要があります。バッファリングに使用するバッファの割り当てはホースクライアントが行います。ホースは、hoseOpen の実行時に bufSize フィールドを設定することで、そのクライアントが割り当てるべきバッファのサイズを指定します。典型的なバッファサイズは、'PAP ' ホースの場合 4096 バイトで、'=Fil' の場合 16384 バイトです。ホースは、必要最小限のバッファ数を minBufs に指定します。minBufs フィールドには、双方向ホースでは少なくとも 4、単方向ホースでは少なくとも 2 を設定することをお勧めします。割り当てることのできるバッファの最大数は、ホースによって maxBufs フィールドに設定されます。このフィールドに適用されるサムの現在の規則は、256K 相当を超えるメモリを指定してはいけないということです。つまり、(262144 / bufSize) を超えてはいけないということです。これはサムの一般的な規則であり、ホースによっては、より大きな maxBufs の設定値を必要とするものもあれば、より小さな設定値を使用するものもあります。

hoseOpen へのコールバックパラメータは、ホースクライアントによって設定された BufCallbacks 構造体へのポインタです。

 typedef void (*FinishedWriteProc)(MemQElemPtr memElem, OSStatus err);
 typedef void (*FinishedReadProc)(MemQElemPtr memElem, OSStatus err);

 typedef struct{
  FinishedWriteProc finishedWrite;
  FinishedReadProc finishedRead;
 }BufCallbacks;

ホースのクライアントは、この構造体内にネイティブ関数への 2 つのポインタを置きます。これらの関数は、読み込みまたは書き込みが完了した時点でホースによって呼び出されることになります。これらの関数ポインタの詳細については、後述の「HoseOutProc」および「HoseInProc」の説明を参照してください。ホースではこの構造体のコピーをプライベートデータとして格納してください。

hoseOpen 呼び出しの一部として、ホースはホース経由で転送されるジョブを環境設定するためのヒントを含んだ Collection Manager コレクションに渡されます。このコレクションに含まれるヒントは、QuickDraw から PostScript へのコンバータとなるホースクライアントによって使用され、PostScript 言語の出力を生成するために使用可能なバイトコードを環境設定します。特に、LaserWriter 8.6 で定義されている kHintEighthBitTag および kHintTransparentChannelTag ヒントは、ホースクライアントが標準 PostScript 言語の印刷可能な ASCII 文字セットの範囲を超えるバイト値を使ってデータを生成できるかどうかを環境設定します。これらのヒントは次のように定義されています。

/* 出力ストリームとして PostScript を生成するとき、デフォルトの設定で PostScript コンバータは必要なときに 0x80-0xFF の範囲の文字を使用します。'kHintEighthBitTag' の値として 'false' を使用すると、コンバータは上位ビットセットを含むバイトを送信しなくなります。

 */
 #define kHintEighthBitTag   'bit8'
 #define kHintEighthBitId   1
 #define kHintEighthBitVariableType  Boolean
 #define kHintEighthBitDefault  true

/* 出力ストリームとして PostScript を生成するとき、デフォルトの設定で PostScript コンバータは必要なときに 0x00-0x1F の範囲の文字を使用します。'kHintTransparentChannelTag' の値として 'false' を使用すると、コンバータは 0x20 未満のバイトを送信しなくなります。

 */
 #define kHintTransparentChannelTag  'trns'
 #define kHintTransparentChannelId   1
 #define kHintTransparentChannelVariableType Boolean
 #define kHintTransparentChannelDefault  true

通常、hoseOpen に渡されるヒントコレクションには、これらのタグ/IDペアに対応するコレクション項目は含まれません。これは、kHintEighthBitTag および kHintTransparentChannelTag ヒントに true を設定していることに相当します。つまり、0x00-0xFF の範囲のバイトがすべて使用可能です。

このようなデフォルトの設定よりも制限のある属性を持ったチャネルを介してデータをやり取りするホースの場合は、ヒントコレクションに適切なコレクション項目を追加して、ホースクライアントがサポートされている範囲だけでバイトを書き込むようにする必要があります。なお、追加する必要があるのはデフォルトよりも制限されたヒントのみです。ホースがフル 8 ビットのデータ通信をサポートしている場合、渡されるヒントコレクションにこれらのヒントを追加する必要はありません。

場合によって、hoseOpen に渡されるヒントコレクションには kHintEighthBitTag および kHintTransparentChannelTag コレクション項目の一方または両方がすでに含まれていて、コレクション項目がロックされていることがあります。ホースクライアントが現在よりも制限のある設定を必要とする場合は、ヒントがすでにロックされているかどうかに関係なく、コレクションにヒントを追加する必要があります。

  OSErr err;

  // たとえば、このホースは上位 8 ビットを転送できません
  kHintEighthBitVariableType eightBit = false;

  // ヒントがすでに存在する場合はヒントのロックを解除します。
  // ヒントのロックがすでに解除されている場合はこれで OK です。
  err = SetCollectionItemInfo(hints, kHintEighthBitTag,
     kHintEighthBitId, collectionLockMask,
     0);
  // ヒントがすでに存在しない場合は問題ありません。
  if(err == collectionItemNotFoundErr)
    err = noErr;

  if(!err){
   err = AddCollectionItem(hints, kHintEighthBitTag,
      kHintEighthBitId, sizeof(eightBit),
     &eightBit;);
   if(!err)
    err = SetCollectionItemInfo(hints,
      kHintEighthBitTag, kHintEighthBitId,
     collectionLockMask, collectionLockMask);
  }

Collection Manager の詳細については、『Inside Macintosh: QuickDraw GX Environment and Utilities』を参照してください。

hoseOpen の最後のパラメータである papa は拡張 'PAPA' 構造体へのハンドルです。この構造体の詳細については、「Technote 1115: LaserWriter 8.5.1: 拡張 'PAPA' リソース」を、また 'PAPA' アクセッサルーチンの psPapaToCollectionpsCollectionToPapa については、「Technote 1129: LaserWriter 8.5.1: プリンタ設定ライブラリ (SettingsLib)」を参照してください。各タイプのホースは、ターゲットとなる出力デバイスと、通信チャネルを環境設定する方法を指定するそれぞれ異なった通信パラメータを持ちます。'PAPA' ハンドルはホースに対応するこれらの通信設定を提供し、デスクトッププリンタのクリエータによって設定されます。

hoseOpen ルーチンの中で、ホースは必要となる任意のメモリを割り当て、プリンタとの接続のオープンを開始しなければなりません。ホース(大部分の接続タイプの場合)は hoseOpen 呼び出しの中で接続を完了する必要はありません。大部分の通信技術では接続に長い時間を要するため、プリンタとの接続のオープンは非同期的に行ってください。ホースは接続プロセスを開始し、hoseOpen から noErr を受け取ります。クライアントでは hoseConnProc を周期的に呼び出して、接続に関する現在のステータスを要求します。hoseConnProc は以下のようになります。

 typedef enum{
  kConnClosed = 0,  // このステータスで開始します。
  kConnOpening,     // これは、プリンタが接続を受け付けるのを待っているステータスです。
  kConnOpen,        // これは、プリンタへの読み書きを行っているステータスです。
  kConnClosing      // これは、接続のクローズを待っているステータスです。
 }ConnState;

 typedef ConnState (*HoseConnProc)(void *refcon);

接続を確立している間、ホースの接続プロシージャは定数 kConnOpening を返します。オープンが正常に完了したら、ホースの接続プロシージャ呼び出しは kConnOpen を返します。ホースをオープンしていて何らかのエラーが発生した場合、ホースの接続プロシージャは kConnClosed を返します。この時点でホースクライアントはホースの HoseCloseProc を呼び出すことになり、HoseCloseProc ではホースをオープンできなかった理由を示す適切なエラーコードを返す必要があります。

HoseOutProc
ホースの主要な目的はデータの転送です。これは、HoseOutProc 呼び出しを介してホースのクライアントによって実現されます。HoseOutProc は以下のとおりであり、

 typedef OSStatus (*HoseOutProc)(void *refcon, MemQElem *memElem);

ホースの関数は以下のようになります。

 OSStatus hoseOut(void *refcon, MemQElem *memElem);

HoseOutProc に渡される refcon パラメータは、hoseOpen ルーチンによって設定された HoseInfo 構造体の refcon フィールドから取得されます。この値は、ホースのプライベートデータへのポインタまたはハンドルでなければなりません。

HoseOutProc の 2 番目のパラメータである memElem は、書き込まれるデータを記述する MemQElem 構造体へのポインタです。

 typedef struct MemQElem{
  QElemPtr qLink;      // Enqueue および Dequeue によって使用されます - プライベート。
  short qType;         // キューを識別する定数 (kMemQueueType) - プライベート。
  struct BufIO *bufIO; // こうしてバッファ情報を回復できます - プライベート。
  Byte *buf;           // 割り当てられたバッファへのポインタ。
  SInt32 maxBytes;     // 'buf' が指すブロックのサイズ。
  SInt32 nBytes;       // 'buf' に含まれる有効なバイトの数。
Boolean eoj;         // データの後に end of job が続く場合は true。
Boolean inQOnly;     // このバッファは入力ルーチンに対してのみ使用してください - プライベート。
 }MemQElem, *MemQElemPtr;

注意:
MemQElem 構造体の多くのフィールドはプライベートであり、ホースクライアントによって使用されます。これらのフィールドのコメントには「プライベート」と記載してあります。ホースがこれらのフィールドを使用してはいけません。

ホースクライアントは MemQElem 構造体の 'eoj' フィールドを使って、PostScript の end of job をプリンタに転送する必要があるときに、そのことをホースに通知します。MemQElem 構造体の 'eoj' フィールドが true の場合、PostScript の end of job の通知は、この MemQElem 構造体に含まれるデータのバッファの後またはデータのバッファとともに送信する必要があります。シリアル接続での control-D のように、通信チャネルによってはこの 'eoj' はデータの後に送信されるデータバイトになります。また、PAP などの他の通信チャネルでは、end of job インジケータはデータそのものを含むバンドの外部にあります。

繰り返しになりますが、ホースはその読み書きを非同期的な方法で実行することをお勧めします。この場合、HoseOutProc は buf が指す nBytes の書き込みを開始した後、呼び出し元に制御を戻します。書き込みが完了すると、ホースは BufCallbacks 構造体として hoseOpen に渡された finishedWrite 関数ポインタを呼び出して、呼び出し元に通知します。

 typedef void (*FinishedWriteProc)(MemQElem *memElem, OSStatus err);

FinishedWriteProc を呼び出すとき、ホースはエラーコードとともに MemQElem として hoseOut に渡されたポインタを渡します。書き込みが正常に終了した場合、エラーコードは noErr になります。書き込み中にエラーが発生した場合は、そのコードを FinishedWriteProc に渡します。

FinishedWriteProc の呼び出しは、ホースが MemQElem 構造体の処理を完了し、別の hoseOut 呼び出しを受け付ける準備が整ったことをホースからクライアントに通知します。実際、FinishedWriteProc を介して呼び出されるルーチンは、ホースに戻る前にすぐに別の hoseOut を呼び出すことがあります。このため、まだ非同期的な完了ルーチン内にあるときでも、ホースは次に呼び出される hoseOut ルーチンの準備を整えておく必要があります。さらに、MemQElem ポインタが FinishedWriteProc に渡された後は、ホースがそれを参照しないようにしてください。FinishedWriteProc を呼び出す前に構造体からコピーしたデータはもはや有効なものではなくなります (特に 'buf')。つまり、構造体そのものが有効でないだけでなく、それ以前に使用されていた構造体に含まれるデータも有効なものではありません。

HoseInProc
単方向通信チャネルを管理している場合、ホースはデータを読み込むルーチンを必要としません。この場合、hoseOpen ルーチンの実行時に HoseInfo 構造体の 'in' フィールドに NULL を設定してください。 プリンタからデータを読み込める場合、ホースは HoseInfo 構造体の in フィールドにデータを読み込むルーチンへのポインタを設定します。

 typedef OSStatus (*HoseInProc)(void *refcon, MemQElem memElem);

HoseOutProc と同様、HoseInProc も非同期的に実行してください。呼び出されたときに HoseInProc が読み込みを開始するようにします。データが使用可能で、ホースの非同期完了ルーチンが呼び出されるとき、ホースはクライアントの FinishedReadProc を呼び出し、HoseInProc に渡された MemQElem ポインタとエラーコードを渡します。ホースは memElem->maxBytes を超えるバイトを読み込むことはできません。また、ホースは memElem->buf に読み込まれたバイト数を memElem->nBytes に設定する必要があります。

 typedef void (*FinishedReadProc)(MemQElem memElem, OSStatus err);

データの書き込みと同様、FinishedReadProc が呼び出された後、ホースは FinishedReadProc が制御を戻す前に別の HoseInProc を呼び出す準備を整えておく必要があります。FinishedWriteProc の場合と同様、FinishedReadProc がホースによって呼び出された後、MemQElem のデータは無効であると見なしてください。

HoseIdleProc
すべてのホースが非同期完了ルーチンを使って読み込みまたは書き込みの終了を通知できるわけではありません。このようなホースを支援するため、hoseOpen から返された HoseInfo 構造体に HoseIdleProc を指定することができます。HoseInfo 構造体の idle フィールドが NULL でない場合、ホースのクライアントは周期的に HoseIdleProc を呼び出すことになります。このアイドルプロシージャは保留中の読み込みと書き込みのステータスをチェックし、必要に応じて、FinishedWriteProcFinishedReadProc を呼び出します。大部分のホースは HoseIdleProc を必要としませんが、必要な場合は、次のシグネチャを持ちます。

 typedef OSStatus (*HoseIdleProc)(void *refcon);

HoseStatusProc
ホースがオープンしている間、ホースのクライアントはホースがプリンタにステータスを問い合わせることを周期的に要求します。呼び出しが行われるとき、ホースはプリンタの最新のステータスを記述する Pascal 文字列を statusStr が指すバッファにコピーします。また、ホースはプリンタへの非同期ステータスリクエストを開始する必要があります。非同期ステータスリクエストが返されたとき、ホースは次のステータスプロシージャが呼び出されるまで、そのステータスを保持していなければなりません。

 typedef OSStatus (*HoseStatusProc)(void *refcon, StringPtr statusStr);

注意:
StringPtr がつねに有効な Pascal 文字列を指していることを確認してください (つまり、文字列全体が書き込まれるまで length バイトを 0 にしておきます。そうすれば、タイミングが悪い場合にもクライアントが意味不明の文字を表示することがなくなります)。

シリアルチャネルなどの一部の通信チャネルでは、プリンタのステータスが HoseInProc によって読み込まれたバックチャネルに返されます。このような場合は、ホースのクライアントがバックチャネルからステータスを取り出し、ホースは出力デバイスにステータスリクエストを転送すること以外に他の処理を行う必要はなくなります。

HoseCloseProc
ホースの処理を終了するとき、クライアントはホースの HoseCloseProc を呼び出して接続を切断します。このとき、ホースは保留中の読み込みと書き込みを中止して、接続の切断を開始しなければなりません。この切断プロシージャが即座に実行された場合は、このルーチンが制御を戻す前に切断を完了することができます。切断プロシージャの実行に時間を要する場合、このルーチンは処理を開始して制御を戻すことができます。

 typedef OSStatus (*HoseCloseProc)(void *refcon);

HoseDisposeProc
HoseCloseProc が呼び出された後、kConnClosed が返されるまで HoseConnProc が繰り返し呼び出されます。ホースが接続の切断を通知するとき、HoseDisposeProc が呼び出され、ホースがまだ保持しているメモリの解放が可能になります。

 typedef OSStatus (*HoseDisposeProc)(void *refcon);

非同期クローズを行っているときに何らかのエラーが発生した場合は、HoseDisposeProc がゼロでないエラー値を返すようにします。

ホースタイプの登録
ホースタイプの重複を避けるため、Apple では、devprograms@apple.com まで電子メールをお寄せいただき、4 バイトのカスタムホースタイプを登録していただくことをお願いしています。カスタムホースタイプを登録するには、次の情報をお知らせください。

  1. 担当者名
  2. 会社名
  3. 住所
  4. 電話番号
  5. 電子メールアドレス
  6. デバイスの型式
  7. 通信方法の説明
  8. 4 バイトのタイプ('=XXX' の形式)

要約
このテクニカルノートで概説したように、LaserWriter 8.6 に対応したカスタムホースの作成はかなり単純であり、わかりやすいものといえます。ただし、カスタムホースの作成を実際に始める前に、このテクニカルノートで言及されている参考文献を読んでみることをお勧めします。

参考文献
Technote 1113: デスクトッププリンタユーティリティのカスタマイズ
Technote 1115: LaserWriter 8.5.1: 拡張 'PAPA' リソース
Technote 1129: LaserWriter 8.5.1: プリンタ設定ライブラリ (SettingsLib)
Technote 11XX: Printing Plug-ins Manager Specification (近刊)
Inside Macintosh: QuickDraw GX Environment and Utilities

関連ファイルのダウンロード

Hose.h (9K) - binhex 形式 -英語版