Solaris 共通デスクトップ環境 プログラマーズ・ガイド

パート III オプションの統合方法

第 7 章「共通デスクトップ環境の Motif ウィジェット」から第 10 章「カレンダとの統合」では、次のオプションの統合方法の作業を実行する方法について説明します。

第 6 章 ワークスペース・マネージャとの統合

ワークスペース・マネージャは、デスクトップの複数のワークスペース環境の中でアプリケーションがウィンドウを管理するための手段を提供します。アプリケーションは、ワークスペース・マネージャと通信することによって、主に次の 4 つのタスクを実行できます。

通常、セッション・マネージャはプログラマに干渉されることなく、アプリケーションのメイン・ウィンドウを正しいワークスペースに取り出します。ただし、アプリケーションが複数のトップレベル・ウィンドウを持つ場合には、ワークスペース・マネージャの API を使用してウィンドウの位置を特定し、このデータをセッション状態の一部として保存しなければなりません。

セッション間のアプリケーション関連情報の保存の詳細は、第 4 章「セッション・マネージャとの統合」を参照してください。

ワークスペース・マネージャとの通信

アプリケーションは、デスクトップが提供する関数を使用して、ワークスペース・マネージャと通信します。これらの関数を使用すると、ワークスペースの管理に関連するさまざまなタスクをすばやく簡単に実行できます。次に、これらの関数のリストを示します。

2 つのデモ・プログラム (occupy.cwsinfo.c) の中に、これらの関数の使用方法を示すコードの一部分があります。occupy.cwsinfo.c、およびいくつかのブランドのワークステーションの makefile をリストしたものがディレクトリ /usr/dt/examples/dtwsm にあります。各関数の詳細は、該当するマニュアル・ページを参照してください。

アプリケーション・ウィンドウをワークスペースに置く

アプリケーションは、ウィンドウを任意のまたは全部の既存のワークスペースに置くことができます。DtWsmOccupyAllWorkspaces() は、現在定義されているすべてのワークスペースにウィンドウを置きます。一方、DtWsmSetWorkspacesOccupied() は、この関数に渡されたリストの中で指定されている、すべてのワークスペースにウィンドウを置きます。

アプリケーション・ウィンドウをすべてのワークスペースに置くには

    DtWsmOccupyAllWorkspaces() を使用します。

    occupy.c では、[すべてのワークスペースに配置] プッシュ・ボタンのコールバック allWsCB() がこの関数を呼び出します。

        DtWsmOccupyAllWorkspaces (XtDisplay(toplevel),
                               XtWindow(toplevel));
    • XtDisplay(toplevel) は、X ディスプレイです。

    • XtWindow(toplevel) は、すべてのワークスペースに置かれるウィンドウです。

この関数の詳細は、DtWsmOccupyAllWorkspaces() のマニュアル・ページを参照してください。

アプリケーション・ウィンドウを指定されたワークスペースに置くには

    DtWsmSetWorkspacesOccupied() を使用します。

    occupy.c では、[配置するワークスペース] プッシュ・ボタンのコールバック setCB() がこの関数を呼び出します。

        DtWsmSetWorkSpacesOccupied XtDisplay(toplevel),
                                  XtWindow(toplevel), paWsSet, numSet);
    • XtDisplay(toplevel) は、X ディスプレイです。

    • XtWindow(toplevel) は、ワークスペースに置かれるウィンドウです。

    • paWsSet は、X のアトムに変換されたワークスペース名のリストを指すポインタです。

    • numSet は、リスト内のワークスペースの番号です。

この関数の詳細は、DtWsmSetWorkspacesOccupied() のマニュアル・ページを参照してください。

アプリケーション・ウィンドウがあるワークスペースの識別

関数 DtWsmGetWorkspacesOccupied() は、指定されたアプリケーション・ウィンドウがあるワークスペースのリストを返します。occupy.c では、プロシージャ ShowWorkspaceOccupancy() がこの関数を呼び出します。この呼び出しの結果に基づいて、ShowWorkspaceOccupancy() はワークスペースを表すトグル・ボタンの外観を変更します。アプリケーション・ウィンドウがあるワークスペースの各トグル・ボタンには、チェック・マークが表示されます。

アプリケーション・ウィンドウがあるワークスペースを識別するには

    DtWsmGetWorkspacesOccupied() を使用します。

        rval = DtWsmGetWorkspacesOccupied(XtDisplay(toplevel)
                XtWindow(toplevel), &paWsIn, &numWsIn);
    • XtDisplay(toplevel) は、X ディスプレイです。

    • XtWindow(toplevel) は、ワークスペースで検索されるウィンドウです。

    • paWsIn は、X のアトムに変換されたワークスペース名のリストを指すポインタのアドレスです。

    • numWsIn は、リスト内のワークスペースの番号を表す整数のアドレスです。

この呼び出しの後、ループが設定され、ワークスペースのリスト (DtWsmGetWorkspaceList() によってプロシージャ SetUpWorkspaceButtons() で検索されます) と、アプリケーション・ウィンドウがあることがわかったワークスペースのリストとを比較します。各トグル・ボタンがアプリケーション・ウィンドウがあるワークスペースを表す場合は、トグル・ボタン・リソース XmNset に True が設定されます。

ワークスペース間のアプリケーションの移動防止

関数 DtWsmRemoveWorkspaceFunctions() は、アプリケーションが次の作業を実行しないようにします。

DtWsmRemoveWorkspaceFunctions() が上記の作業を実行する場合は、デスクトップ・ワークスペース・マネージャ (dtwm) のウィンドウ・メニューの一部分をアクティブにしないようにします。dtwm はアプリケーションのトップレベル・ウィンドウを管理するときにワークスペース情報をチェックするだけなので、アプリケーションはトップレベル・ウィンドウがマップされる前に DtWsmRemoveWorkspaceFunctions() を呼び出さなければなりません。アプリケーションのトップレベル・ウィンドウが管理された後で DtWsmRemoveWorkspaceFunctions() を呼び出す必要がある場合には、最初に Xlib 関数 XWithdrawWindow() を呼び出してから DtWsmRemoveWorkspaceFunctions() を呼び出し、次に XMapWindow() を呼び出して、トップレベル・ウィンドウを再マップしなければなりません。

別のワークスペースへの移動を防止するには

    DtWsmRemoveWorkspaceFunctions() を使用します。

        DtWsmRemoveWorkspaceFunctions(XtDisplay(toplevel),
                                   XtWindow(toplevel));
    • XtDisplay(toplevel) は、X ディスプレイです。

    • XtWindow(toplevel) は、ワークスペースの移動を防止するウィンドウです。

ワークスペースの変更の監視

次の関数の 1 つまたは両方を使用して、ワークスペースの変更を監視できます。

DtWsmAddCurrentWorkspaceCallback() は、ワークスペース・マネージャが新しいワークスペースに切り替えられるときに、必ず呼び出されるアプリケーション・コールバックを登録します。詳細は、DtWsmAddCurrentWorkspaceCallback(3) のマニュアル・ページを参照してください。

DtWsmWorkspaceModifiedCallback() は、ワークスペースが追加、削除、または変更されるときに必ず呼び出されるアプリケーション・コールバックを登録します。詳細は、DtWsmWorkspaceModifiedCallback(3) のマニュアル・ページを参照してください。

ワークスペースの切り替えを監視するには

    DtWsmAddCurrentWorkspaceCallback() を使用します。

    デモ・プログラム wsinfo.c では、この関数は、トップレベル・ウィジェットが実体化された後で呼び出されます。

        DtWsmAddCurrentWorkspaceCallback (toplevel, wschangecb, NULL);
    • toplevel は、アプリケーションのトップレベル・ウィジェットです。

    • wschangecb() は、呼び出される関数名です。

    • NULL は、コールバックに渡されるクライアント・データのパラメータです。この場合、データは渡されません。

他のワークスペースの変更を監視するには

    DtWsmWorkspaceModifiedCallback() を使用します。

        DtWsmWorkspaceModifiedCallback toplevel, wschangecb, NULL);
    • toplevel は、アプリケーションのトップレベル・ウィジェットです。

    • wschangecb() は、呼び出される関数名です。

    • NULL は、コールバックに渡されるクライアント・データのパラメータです。この場合、データは渡されません。

第 7 章 共通デスクトップ環境の Motif ウィジェット

共通デスクトップ環境 (CDE) は、Motif 2.1 ライブラリ (バグ修正付き) および拡張機能を提供します。さらに、CDE は、OPEN LOOK と Microsoft Windows の特定の機能を提供するために使用できる 4 つのカスタム・ウィジェットを提供します。この章では、これらの Motif カスタム・ウィジェットについて説明します。

ウィジェット・ライブラリ (libDtWidget) には、既存の Motif 2.1 ウィジェットの機能を組み合わせたり、拡張したりする 4 つのウィジェットがあります。

これらのウィジェットは、すべての CDE アプリケーションに共通の機能を提供します。これらのウィジェットは、サブクラス化はサポートしていません。

カスタム・ウィジェット・ライブラリは、次のライブラリに直接依存します。

メニュー・ボタン・ウィジェット (DtMenuButton)

DtMenuButton ウィジェットは、メニュー区画の外側にメニュー階層機能を提供するために使用します。

DtMenuButton ウィジェットは、XmCascadeButton ウィジェットのメニュー階層機能を補足するコマンド・ウィジェットです。XmCascadeButton ウィジェットを補うものとして、メニュー・バープルダウン、またはポップアップの外側で示すことができます (MenuPane の内部では XmCascadeButton ウィジェットを使用します)。図 7-1 に、DtMenuButton ウィジェットの使用例を示します。

図 7-1 メニュー・ボタン・ウィジェット (DtMenuButton) の例

Graphic

ライブラリとヘッダ・ファイル

DtMenuButton ウィジェットは、libDtWidget ライブラリにあります。ヘッダ・ファイルは、Dt/MenuButton.h です。

デモ・プログラム

DtMenuButton ウィジェットの使用例が入っているデモが、/usr/dt/examples/dtwidget/controls.c にあります。

簡易関数

DtCreateMenuButton() は、CDE ウィジェットを作成する簡易関数です。

DtMenuButton ウィジェットは、XmLabel クラスのサブクラスです。視覚的には、DtMenuButton ウィジェットは、ラベル文字列とメニュー・グリフ (絵文字) を持ちます。メニュー・グリフは、常にウィジェットの右端に表示され、デフォルトでは下向き矢印です。

DtMenuButton ウィジェットには、暗黙的に作成されたサブメニューが接続されています。サブメニューは、この DtMenuButton ウィジェットを親とするポップアップ・メニューです。暗黙的に作成されたサブメニュー名は、この DtMenuButton ウィジェットの名前の前に submenu_ を付けたものです。サブメニューのウィジェット ID は、この DtMenuButton ウィジェットの DtNsubMenuId リソースに XtGetValues を設定することにより取得できます。暗黙的に作成されたサブメニューは、このウィジェットの利用者によって破壊されることはありません。

サブメニューは、DtMenuButton ウィジェットのどこかで [メニュー・ポスト] ボタン(XmRowColumnXmNmenuPost リソースを参照) を押すことによって、または Motif の取り消しキー (通常は [Escape] キー) を押すことによってポップアップできます。

クラス

DtMenuButtonWidget は、CoreXmPrimitive、および XmLabel クラスから動作とリソースを継承します。

クラス・ポインタは、dtMenuButtonWidgetClass です。

クラス名は、DtMenuButtonWidget です。

DtMenuButtonWidget は、サブクラス化をサポートしません。

リソース

DtMenuButtonWidget は、次のリソースを提供します。これらのリソースのクラス、型、デフォルト、およびアクセスを表 7-1 に示します。

詳細は、DtMenuButtonwidget(3X) のマニュアル・ページを参照してください。

アクセス欄のコードは、次の作業が可能かどうかを示します。

表 7-1 DtMenuButtonWidget リソース

名前 

クラス 

型 

デフォルト 

アクセス 

DtNcascadingCallback

DtCCallback

XtCallbackList 

NULL 

DtNcascadePixmap

DtCPixmap

Pixmap 

XmUNSPECIFIED_PIXMAP 

CSG 

DtNsubMenuId

DtCMenuWidget

Widget 

NULL 

SG 

コールバックのための構造体

コールバックのための構造体を次に示し、表 7-2 で説明します。

typedef struct {
 	int 	reason;
 	XEvent	*event;
} XmAnyCallbackStruct;
表 7-2 DtMenuButtonWidget コールバックのための構造体

構造体 

説明 

reason

コールバックが呼び出された reason を返します。 

event

コールバックをトリガした XEvent へのポインタ。コールバックが XEvent によってトリガされなかった場合には NULL になります。

DtMenuButton ウィジェットの例

次の例は、DtMenuButton ウィジェットの作成方法と使用方法を示しています。このコードは、/usr/dt/examples/dtwidget ディレクトリの controls.c デモの一部です。

/*
  * Example code for DtMenuButton
  */  

#include Dt/DtMenuButton.h  

/* MenuButton custom glyph */  

#define menu_glyph_width 16 
#define menu_glyph_height 16 
static unsigned char menu_glyph_bits[] = {
 	0xe0, 0x03, 0x98, 0x0f, 0x84, 0x1f, 0x82, 0x3f, 0x82, 0x3f, 0x81,
 	0x7f, 0x81, 0x7f, 0xff, 0x7f, 0xff, 0x40, 0xff, 0x40, 0xfe, 0x20, 0xfe,
 	0x20, 0xfc, 0x10, 0xf8, 0x0c, 0xe0, 0x03, 0x00, 0x00};

static void CreateMenuButtons(Widget parent) {
     Widget menuButton, submenu, titleLabel, button;
     Pixmap cascadePixmap;
     Pixel fg, bg;
     Cardinal depth;
     XmString labelString;
     Arg args[20];
     int i, n;

      /* Create title label */

     labelString = XmStringCreateLocalized("MenuButton Widget");
     n = 0;
     XtSetArg(args[n], XmNlabelString, labelString); n++;
     titleLabel = XmCreateLabel(parent, "title", args, n);
     XtManageChild(titleLabel);
     XmStringFree(labelString);

     /*
      * Create a MenuButton.
      * Add push buttons to the built-in popup menu.
      */

     labelString = XmStringCreateLocalized("Action"); n = 0;
     XtSetArg(args[n], XmNlabelString, labelString); n++;
     menuButton = DtCreateMenuButton(parent, "menuButton1", args, n);
     XtManageChild(menuButton);
     XmStringFree(labelString);
     XtVaGetValues(menuButton, DtNsubMenuId, &submenu, NULL);
     button = XmCreatePushButton(submenu, "Push", NULL, 0);
     XtManageChild(button);
     button = XmCreatePushButton(submenu, "Pull", NULL, 0);
     XtManageChild(button);
     button = XmCreatePushButton(submenu, "Turn", NULL, 0);
     XtManageChild(button);

     /*
      * Create a MenuButton.
      * Replace the built-in popup menu with a tear-off menu.
      * Add a custom pixmap in the colors of the MenuButton.
      */

     labelString = XmStringCreateLocalized("Movement");
     n = 0;
     XtSetArg(args[n], XmNlabelString, labelString); n++;
  	  menuButton = DtCreateMenuButton(parent, "menuButton1", args, n);
     XtManageChild(menuButton);
     XmStringFree(labelString);

     /* Create a tear-off menu */

     n = 0;
     XtSetArg(args[0], XmNtearOffModel, XmTEAR_OFF_ENABLED); n++;
     submenu = XmCreatePopupMenu(menuButton, "submenu", args, n);
     button = XmCreatePushButton(submenu, "Run", NULL, 0);
     XtManageChild(button);
     button = XmCreatePushButton(submenu, "Jump", NULL, 0);
     XtManageChild(button);
     button = XmCreatePushButton(submenu, "Stop", NULL, 0);
     XtManageChild(button);

     XtVaSetValues(menuButton, DtNsubMenuId, submenu, NULL);

     /* Create a pixmap using the menu button's colors and depth */

     XtVaGetValues(menuButton,
 			XmNforeground, &fg,
 			XmNbackground, &bg,
 			XmNdepth, &depth,
 			NULL);

     cascadePixmap = XCreatePixmapFromBitmapData(XtDisplay
 	  (menuButton),DefaultRootWindow(XtDisplay
 	  (menuButton)),
 	  (char*)menu_glyph_bits,
 	  menu_glyph_width, menu_glyph_height,
     fg, bg, depth);
     XtVaSetValues(menuButton, DtNcascadePixmap, cascadePixmap,
 	  NULL); 
}

テキスト・エディタ・ウィジェット (DtEditor)

共通デスクトップ環境のテキスト編集システムは、次の 2 つのコンポーネントから成ります。

OSF/Motif テキスト・ウィジェットはプログラム・インタフェースも提供しますが、システム全体で一貫したエディタを使用するアプリケーションは、DtEditor(3) ウィジェットを使用しなければなりません。CDE のテキスト・エディタとメール・プログラムは、エディタ・ウィジェットを使用します。このウィジェットは、次のような状況のときに使用してください。

  1. [スペルチェック]、[元に戻す]、および [検索/変更] など、DtEditor(3) ウィジェットが提供する機能を使いたい場合

  2. ユーザがファイルからデータを読み込んだり、ファイルにデータを書き込んだりするコードを作成したくない場合

  3. ユーザが入力した文字またはユーザが行なったカーソル移動を調べる必要がないプログラムを作成する場合

この節では、テキスト・エディタ・ウィジェット DtEditor(3) について説明します。

エディタ・ウィジェット・ライブラリは、テキスト・ファイルの作成と編集のためのサポートを提供します。デスクトップ環境で実行するアプリケーションで、一貫した方法でテキスト・データを編集できるようにします。DtEditor(3) ウィジェットは、テキスト用のスクロールする編集ウィンドウ、オプションのステータス行と、テキストの検索と置換、スペルチェック、および書式オプションの指定を行うためのダイアログから成ります。テキスト・エディタ・ウィジェットには、ウィジェットをプログラム的に制御するための簡易関数のセットが含まれています。

ライブラリとヘッダ・ファイル

DtEditor ウィジェットは、libDtWidget ライブラリにあります。ヘッダ・ファイルは、Dt/Editor.h です。

デモ・プログラム

DtEditor ウィジェットの使用例が入っているデモが、/usr/dt/examples/dtwidget/editor.c にあります。

クラス

DtEditor ウィジェット・クラスについては、ウィジェットのサブクラス化はサポートされません。

DtEditor は、CoreCompositeConstraintsXmManager、および XmForm クラスから動作とリソースを継承します。

エディタ・ウィジェットのクラス名は、DtEditorWidget です。

クラス・ポインタは、dtEditorWidgetClass です。

簡易関数

DtEditor 簡易関数を、次の表に示します。

ライフ・サイクル関数

DtEditor ライフ・サイクル関数を表 7-3 に示します。

表 7-3 DtEditor ライフ・サイクル関数

関数 

説明 

DtCreateEditor

DtEditor ウィジェットの新規インスタンスとその子を作成します。

DtEditorReset

DtEditor ウィジェットを初期状態に復元します。

入出力関数

DtEditor 入出力関数を表 7-4 に示します。

表 7-4 DtEditor 入出力関数

関数 

説明 

DtEditorAppend

エディタ・ウィジェットの最後に内容データを追加します。 

DtEditorAppendFromFile

エディタ・ウィジェットの最後にファイルの内容を追加します。 

DtEditorGetContents

エディタ・ウィジェットの内容全体を検索します。 

DtEditorInsert

内容データを現在の挿入位置に挿入します。 

DtEditorInsertFromFile

ファイルの内容を現在の挿入位置に挿入します。 

DtEditorReplace

テキストの一部を与えられたデータと置き換えます。 

DtEditorReplaceFromFile

テキストの一部をファイルの内容と置き換えます。 

DtEditorSaveContentsToFile

現在選択されている内容を空白に置き換えます。 

DtEditorSetContents

内容データをエディタ・ウィジェットに読み込んで、ウィジェットの内容全体を置き換えます。 

DtEditorSetContentsFromFile

ファイルの内容をエディタ・ウィジェットに読み込んで、ウィジェットの内容全体を置き換えます。 

選択関数

DtEditor 選択関数を表 7-5 に示します。

表 7-5 DtEditor 選択関数

関数 

説明 

DtEditorClearSelection

現在選択されている内容を空白に置き換えます。 

DtEditorCopyToClipboard

現在選択されている内容をクリップボードにコピーします。 

DtEditorCutToClipboard

現在選択されている内容を削除して、クリップボードに入れます。 

DtEditorDeleteSelection

現在選択されている内容を削除します。 

DtEditorDeselect

選択されている内容を選択解除します。 

DtEditorPasteFromClipboard

クリップボードの内容をエディタ・ウィジェットにペーストして、現在選択されている内容を置き換えます。 

DtEditorSelectAll

エディタ・ウィジェットの内容全体を選択します。 

書式化関数

DtEditor 書式化関数を表 7-6 に示します。

表 7-6 DtEditor 書式化関数

関数 

説明 

DtEditorFormat

エディタ・ウィジェットの内容の全部または一部を書式化します。 

DtEditorInvokeFormatDialog

[書式] ダイアログ・ボックスを表示して、マージンと位置揃えのスタイルに関する書式設定を指定し、書式操作を実行できます。 

検索/変更関数

DtEditor検索/変更関数を表 7-7 に示します。

表 7-7 DtEditArea 検索/変更関数

関数 

説明 

DtEditorChange

文字列の 1 つまたはすべての存在箇所を置換します。 

DtEditorFind

文字列の次の出現箇所を検索します。 

DtEditorInvokeFindChangeDialog

文字列を検索 (オプションで置換も) するためのダイアログ・ボックスを表示します。 

DtEditorInvokeSpellDialog

現在の内容の中でスペルが間違っている単語のリストがあるダイアログ・ボックスを表示します。 

補助関数

DtEditor 補助関数を表 7-8 に示します。

表 7-8 DtEditor 補助関数

関数 

説明 

DtEditorCheckForUnsavedChanges

エディタ・ウィジェットの内容が前回の検索または保存以後に変更されているかどうかを報告します。 

DtEditorDisableRedisplay

ビジュアル属性が変更された場合でも、エディタ・ウィジェットの再表示をしません。 

DtEditorEnableRedisplay

エディタ・ウィジェットの表示の更新を強制します。 

DtEditorGetInsertPosition

エディタ・ウィジェットの挿入カーソル位置を返します。 

DtEditorGetLastPosition

編集ウィンドウの最後の文字の位置を返します。 

DtEditorGetMessageTextFieldID

アプリケーション・メッセージを表示するために使用されるテキスト・フィールド・ウィジェットのウィジェット ID を検索します。 

DtEditorGetSizeHints

エディタ・ウィジェットからサイズ情報を検索します。 

DtEditorGoToLine

挿入カーソルを指定された行へ移動します。 

DtEditorSetInsertionPosition

挿入カーソルの位置を設定します。 

DtEditorTraverseToEditor

エディタ・ウィジェットの編集ウィンドウへのキーボード移動を設定します。 

DtEditorUndoEdit

ユーザが行なった最後の編集を元に戻します。 

リソース

DtEditor ウィジェットは、次のリソースのセットを提供します。

ステータス行は、アプリケーションによって提供されるメッセージを表示するための Motif の XmTextField(3x) ウィジェットも含んでいます。このフィールドは、アプリケーションが編集中のドキュメントについてのステータスとフィードバックを表示するのに便利です。テキスト・フィールドの ID は、DtEditorGetMessageTextFieldID(3) を使用して検索されます。メッセージは、このウィジェットの XmNvalue または XmNvalueWcs リソースを設定することによって表示されます。テキスト・フィールドが必要ない場合には、その ID で XtUnmanageWidget(3X) を呼び出すことによって管理からはずことができます。

各リソースのクラス、型、デフォルト、およびアクセスを表 7-9 にリストします。継承クラスのリソース値を設定することによって、このウィジェットの属性を設定することもできます。.Xdefaults ファイルの中で名前またはクラスによってリソースを参照するには、DtN または DtC の接頭辞を除いて、残りの文字を使用します。.Xdefaults ファイルでリソースに対して定義済みの値の 1 つを指定するには、Dt 接頭辞を除いて、残りの文字を使用します (小文字または大文字で、単語の間に下線を入れます)。

アクセス欄のコードは、次の作業が可能かどうかを示します。

詳細は、DtEditor(3) のマニュアル・ページを参照してください。

表 7-9 DtEditor リソース

名前 

クラス 

型 

デフォルト 

アクセス 

DtNautoShowCursorPosition

DtCAutoShowCursorPosition

Boolean 

True 

CSG 

DtNblinkRate

DtCBlinkRate

int 

500 

CSG 

DtNbuttonFontList

DtCFontList

XmFontList 

Dynamic 

CSG  

DtNcolumns

DtCColumns

XmNcolumns 

Dynamic 

CSG 

DtNcursorPosition

DtCCursorPosition

XmTextPosition 

CSG 

DtNcursorPositionVisible

DtCCursorPositionVisible

Boolean 

True 

CSG 

DtNdialogTitle

DtCDialogTitle

XmString 

NULL 

CSG 

DtNeditable

DtCEditable

Boolean 

True  

CSG 

DtNlabelFontList

DtCFontList

XmFontList 

Dynamic 

CSG 

DtNmaxLength

DtCMaxLength

int 

Largest integer 

CSG 

DtNoverstrike

DtCOverstrike

Boolean 

False 

CSG 

DtNrows

DtCRows

XmNrows 

Dynamic 

CSG 

DtNscrollHorizontal

DtCScroll

Boolean 

True 

CG 

DtNscrollLeftSide

DtCScrollSide

Boolean 

Dynamic 

CG 

DtNscrollTopSide

DtCScrollSide

Boolean 

False 

CG 

DtNscrollVertical

DtCScroll

Boolean 

True 

CG 

DtNshowStatusLine

DtCShowStatusLine

Boolean 

False 

CSG 

DtNspellFilter

DtCspellFilter

char * 

Spell 

CSG 

DtNtextBackground

DtCBackground

Pixel 

Dynamic 

CSG 

DtNtextDeselectCallback

DtCCallback

XtCallbackList 

NULL 

DtNtextFontList

DtCFontList

XmFontList 

Dynamic 

CSG 

DtNtextForeground

DtCForeground

Pixel 

Dynamic 

CSG 

DtNtextTranslations

DtCTranslations

XtTranslations 

NULL 

CS 

DtNtextSelectCallback

DtCCallback

XtCallbackList 

NULL 

DtNtopCharacter

DtCTextPosition

XmTextPosition 

CSG 

DtNwordWrap

DtCWordWrap

Boolean 

True 

CSG 

継承されるリソース

DtEditor は、次のスーパークラスから動作とリソースを継承します。

詳細は、該当するマニュアル・ページを参照してください。

ローカライズ・リソース

次のリストは、DtEditor ウィジェットとそのダイアログ・ボックスのローカライズのために設計されるウィジェット・リソースのセットを示しています。これらのリソースのデフォルト値は、ロケールに依存します。

ローカライズ・リソースのそれぞれのクラス、型、デフォルト、およびアクセスを表 7-10 にリストします。アクセス欄のコードは、次の作業が可能かどうかを示します。

詳細は、DtEditor(3) のマニュアル・ページを参照してください。

表 7-10 DtEditor ローカライズ・リソース

名前 

クラス 

型 

デフォルト 

アクセス 

DtNcenterToggleLabel

DtCCenterToggleLabel

XmString 

Dynamic 

CSG 

DtNchangeAllButtonLabel

DtCChangeAllButtonLabel

XmString 

Dynamic 

CSG 

DtNchangeButtonLabel

DtCChangeButtonLabel

XmString 

Dynamic 

CSG 

DtNchangeFieldLabel

DtCChangeFieldLabel

XmString 

Dynamic 

CSG 

DtNcurrentLineLabel

DtCCurrentLineLabel

XmString 

Dynamic 

CSG 

DtNfindButtonLabel

DtCFindButtonLabel

XmString 

Dynamic 

CSG 

DtNfindChangeDialogTitle

DtCFindChangeDialogTitle

XmString 

Dynamic 

CSG 

DtNfindFieldLabel

DtCFindFieldLabel

XmString 

Dynamic 

CSG 

DtNformatAllButtonLabel

DtCFormatAllButtonLabel

XmString 

Dynamic 

CSG 

DtNformatParagraphButtonLabel

DtCFormatParagraphButtonLabel

XmString 

Dynamic 

CSG 

DtNformatSettingsDialogTitle

DtCFormatSettingsDialogTitle

XmString 

Dynamic 

CSG 

DtNinformationDialogTitle

DtCInformationDialogTitle

XmString 

Dynamic 

CSG 

DtNjustifyToggleLabel

DtCJustifyToggleLabel

XmString 

Dynamic 

CSG 

DtNleftAlignToggleLabel

DtCLeftAlignToggleLabel

XmString 

Dynamic 

CSG 

DtNleftMarginFieldLabel

DtCLeftMarginFieldLabel

XmString 

Dynamic 

CSG 

DtNmisspelledListLabel

DtCMisspelledListLabel

XmString 

Dynamic 

CSG 

DtNoverstrikeLabel

DtCOverstrikeLabel

XmString 

Dynamic 

CSG 

DtNrightAlignToggleLabel

DtCRightAlignToggleLabel

XmString 

Dynamic 

CSG 

DtNrightMarginFieldLabel

DtCRightMarginFieldLabel

XmString 

Dynamic 

CSG 

DtNspellDialogTitle

DtCSpellDialogTitle

XmString 

Dynamic 

CSG 

DtNtotalLineCountLabel

DtCTotalLineCountLabel

XmString 

Dynamic 

CSG 

コールバック関数

DtEditor ウィジェットは、次の 3 つのコールバック関数をサポートします。

エディタ・ウィジェットとそのダイアログ・ボックスについてのヘルプ情報を表示する場合は、XmNhelpCallback リソースを設定し、DtEditorHelpCallbackStruct の一部として渡される reason フィールドを使用して、[ヘルプ] ダイアログ・ボックスの内容を設定します。次の構造体へのポインタが XmNHelpCallback に渡されます。コールバックのための構造体を次に示し、表 7-11 で説明します。

typedef struct {
		int     reason;
 	XEvent   *event;
} DtEditorHelpCallbackStruct;
表 7-11 DtEditorHelp コールバックのための構造体

構造体 

説明 

reason

コールバックが呼び出された reason。reason のリストについては、DtEditor(3) のマニュアル・ページを参照してください。

event

このコールバックを呼び出したイベントへのポインタ。値は、NULL になることもあります。 

テキストが選択されているかどうかによって、メニュー項目とコマンドを有効か無効にする場合は、DtNtextSelectCallback リソースおよび DtNtextDeselectCallback リソースを使用します。DtNtextSelectCallback は、編集ウィンドウでテキストが選択されたときに呼び出される関数を指定します。DtNtextDeselectCallback は、編集ウィンドウでテキストが選択されていないときに呼び出される関数を指定します。コールバックによって送られる reason は、DtEDITOR_TEXT_SELECTDtEDITOR_TEXT_DESELECT です。

第 8 章 アプリケーションからのアクションの実行

アプリケーションが拡張性のある一連のデータ型を管理する場合には、アクションの実行によりデータ型を直接実行しなければなりません。この章では、アプリケーションからアクションを実行する方法について説明します。アクションの実行方法を示すサンプル・プログラムも示します。

アクションとアクションの作成の詳細は、第 9 章「データ型データベースのアクセス」「データ型データベースのアクセス」と、『Solaris 共通デスクトップ環境 上級ユーザ及びシステム管理者ガイド』の次の章を参照してください。

アプリケーションからアクションを実行する方法

デスクトップ・サービス・ライブラリによってエクスポートされたアクション実行 API は、アプリケーションから別のアプリケーションを実行したり、操作を実行したりするための方法の 1 つです。その他の方法として、次のものがあります。

これらの方法は、それぞれ利点と制約があるので、具体的な状況を評価して、どちらが適切かを判断しなければなりません。

アクション実行 API の利点は、次のとおりです。

アクションによりこれを実現するには、バッファまたはデータ・ファイルに対して [開く] アクションを実行するだけです。アクション実行 API はアクション・データベースに基づいて、送信する適切なメッセージまたは実行するコマンドを判断し、一時ファイルの作成や削除、必要なシグナルの取り込みなどのすべての詳細を処理します。

アクションの型

アクションのアプリケーション・プログラム・インタフェース (API) は、どの種類のアクションに対しても機能します。デスクトップでのアクションの種類は、次のとおりです。

コマンド・アクション 

実行するコマンド行を指定します。 

ToolTalk アクション 

送信する ToolTalk メッセージを指定します。メッセージは、適切なアプリケーションによって受信されます。 

マップ・アクション 

特定の動作を定義する代わりに、別のアクションを参照します。 

詳細は、『Solaris 共通デスクトップ環境 上級ユーザ及びシステム管理者ガイド』の第 10 章「アクションおよびデータ型の概要」を参照してください。

アクション実行 API

アクション実行 API は、デスクトップ・サービス・ライブラリからエクスポートされて、次のような多数のタスクを実行する関数を提供します。

関連情報

アクション・コマンド、関数、およびデータ形式の詳細は、次のマニュアル・ページを参照してください。

actions.c プログラム例

この節では、簡単なサンプル・プログラム actions.c について説明します。actions.c の完全なリストは、この章の終わりにあります。

アクションおよびデータ型データベースの読み込み

アプリケーションがアクションを実行するには、その前に、デスクトップ・サービス・ライブラリ (アクション実行 API を含む) を初期化して、アクションおよびデータ型定義のデータベースを読み込まなければなりません。

デスクトップ・サービス・ライブラリを初期化するには

    デスクトップ・サービス・ライブラリを初期化するには、DtInitialize() 関数を使用します。

       DtInitialize(*display,widget,*name,*tool_class)

    DtInitialize() は、デフォルトのイントリンシクス関数 XtAppContext を使用します。API は、アプリケーションが app_context を指定しなければならないときに使用する追加の関数 DtAppInitialize() を提供します。

       DtAppInitialize(app_context,*display,widget,*name, tool_class)

Dtinitialize() の例

次のコードの一部分は、サンプル・プログラム actions.c の中で DtInitialize() がどのように使用されているかを示しています。

    if (DtInitialize(XtDisplay(shell), shell,

argv[0],ApplicationClass)==False) {
 			/* DtInitialize() has already logged an appropriate error msg */
         			exit(-1);
    }

アクションおよびデータ型データベースを読み込むには

    アクションおよびデータ型データベースを読み込むには、DtDbLoad() 関数を使用します。

       DtDbLoad(void)

    DtDbLoad() は、アクションおよびデータ型データベースを読み込みます。この関数は、データベース・ファイルを検索するディレクトリのセット (データベース検索パス) を判断して、データベース内で見つかった *.dt ファイルを読み込みます。ディレクトリ検索パスは、DTDATABASESEARCHPATH 環境変数と内部のデフォルト値に基づきます。

DtDbLoad() の例

次のコードの一部分は、サンプル・プログラム actions.c の中で DtDbLoad() がどのように使用されているかを示しています。

/* Load the filetype/action databases */
    DtDbLoad();

再読み込みイベントの通知を要求するには

長時間実行中のアプリケーションの中で DtDbLoad() を使用する場合、データベースが変更されたときには、動的に再読み込みしなければなりません。

  1. DtDbReloadNotify() 関数を使用して、再読み込みイベントの通知を要求します。

    /* Notice changes to the database without needing to restart
    	 application */
    
      	DtDbReloadNotify(DbReloadCallbackProc, callback_proc,
    	 	XTPointer, client_data);
  2. 次の作業を実行するコールバックを指定します。

    • アプリケーションによって保持されている、キャッシュされたデータベース情報を破棄する。

    • DtDbLoad() 関数を再コールする。

callback_proc は、アプリケーションが保持している、キャッシュされたデータベース情報をクリーンアップしてから、DtDbLoad() を呼び出します。client_data を使用して、追加のクライアント情報をコールバック・ルーチンに渡すことができます。

アクション・データベースのチェック

アプリケーションは、アクションのアイコンまたはラベルを表示する必要がある場合には、データベースにアクセスします。また、アクションを実行することによって、アプリケーションはアクションの存在をチェックできます。データベース内のアクションは、アクション名によって識別されます。

ACTION action_name 
{
  ... 
}

たとえば、[電卓] アクションの定義は次のとおりです。

ACTION Dtcalc
{
      LABEL				電卓
      ICON						Dtcalc
      ARG_COUNT						0 
      TYPE            COMMAND
      WINDOW_TYPE						NO_STDIO
      EXEC_STRING						/usr/dt/bin/dtcalc
      DESCRIPTION						電卓 (Dtcalc) アクションは、デスクトップ電卓 ¥
                         アプリケーションを起動します 
}

[電卓] アクションのアクション名は Dtcalc です。

実行形式ファイルがデータベース内のアクション名と一致するファイル名を持つ場合には、そのファイルはアクション・ファイルです。すなわち、基本のアクションの表現です。そのファイルのアイコンとラベルに関する情報は、データベースに格納されます。

指定されたアクション定義が存在するかどうかを判断するには

    指定されたアクション定義が存在するかどうかを判断するには、DtActionExists() 関数を使用します。

       DtActionExists(*name)

    DtActionExists() は、指定された名前がデータベース内のアクションの名前に一致するかどうかをチェックします。この関数は、名前がアクション名に一致する場合には True を返し、その名前のアクションが見つからない場合には False を返します。

指定されたアクションのアイコン・イメージ情報を取り出すには

    アイコン・イメージ情報を取り出すには、DtActionIcon() 関数を使用します。

   DtActionIcon(char *action_name)

アクション定義は、アクションを表すために使われるアイコン・イメージを定義の ICON フィールドで指定します。

ACTION action_name
{
     ICON icon_image_base_name  
     ... 
}

DtActionIcon() は、アイコン・イメージ・フィールドの値にある文字列を返します。アクション定義にアイコン・フィールドがない場合には、この関数はデフォルトのアクション・アイコン・イメージの値 Dtactn を返します。

次に、使用したいアイコンとサイズの位置を決めます。アイコンには 4 つのサイズがあり、ビットマップまたはピックスマップ形式で使用できます。たとえば、[電卓] のアクション定義からアイコン・ファイルのベース名を見つけることができます。次に、そのベース名と表 8-1 の情報の組み合わせと、すべてのアイコンの格納情報から、目的のアイコン・ファイルを見つけ出せます。

[電卓] アクションのアイコン名は Dtcalc ですが、これはファイル名全体ではありません。アイコン・ファイル名はアイコンのサイズに基づき、4 つのサイズがあります。表 8-1 は、デスクトップ・アイコンのサイズとファイル名の命名規則を示します。

表 8-1 アイコンのサイズとファイル名

アイコンのサイズ 

ビットマップ名 

ピックスマップ名 

16 * 16 (極小) 

name.t.bm

name.t.pm

24 * 24 (小) 

name.s.bm

name.s.pm

32 * 32 (中) 

name.m.bm

name.m.pm

48 * 48 (大) 

name.l.bm

name.l.pm


注 -

デスクトップ・アイコン・ファイルの詳細は、『Solaris 共通デスクトップ環境 上級ユーザ及びシステム管理者ガイド』の第 14 章「デスクトップのアイコンの作成」を参照してください。


ビットマップの場合、マスクとして使われる追加のファイルがあり、そのファイルの拡張子 _m.bm で終わります。したがって、各サイズのアイコンに対して合計 3 個のファイルがあります。次に、電卓のアイコン・ファイルを示します。

Dtcalc.t.bm
Dtcalc.t.pm
Dtcalc.t_m.bm
Dtcalc.m.bm
Dtcalc.m.pm
Dtcalc.m_m.bm
Dtcalc.l.bm
Dtcalc.l.pm
Dtcalc.l_m.bm

注 -

電卓には小型アイコン (Dtcalc.s.bmDtcalc.s.pmDtcalc.s_m.bm) がない点に注意してください。


DtActionIcon() はベース名だけを返します。電卓の場合は Dtcalc です。種類 (ピックスマップまたはビットマップ) とサイズ (極小、小、中、大) を選択して、適用可能な拡張子をベース名に追加してください。また、ファイルがどこにあるかを知っておいてください。

アクションのローカライズ・ラベルを取り出すには

    アクションのローカライズ・ラベルを取り出すには、DtActionLabel() 関数を使用します。

   char *DtActionLabel(char *actionName)

アクション定義にはラベルを入れることができます。ラベルは、label_text フィールドを使用して定義されます。

ACTION action_name {

   LABEL label_text
   ...
}

このラベルは、グラフィック・コンポーネント (ファイル・マネージャやアプリケーション・マネージャなど) の中でアクションのアイコンにラベルを付けるために使用されます。アクション定義に label_text フィールドがない場合には、action_name が使用されます。

label_text 文字列の値は、エンドユーザがアクションを見分けられるように、すべてのインタフェース・コンポーネントによって使用されなければなりません。

DtActionLabel() 関数は、actionName という名前のアクションのアクション定義の中の label_text フィールドの値を返します。label_text フィールドがない場合には、この関数は actionName を返します。

アクションの実行

アプリケーションがデスクトップ・サービス・ライブラリを初期化した後は、アクションを実行できます。

アクションを実行するには

    アクションを実行するには、DtActionInvoke() 関数を使用します。

DtActionInvoke (widget, action, args, argCount, termOpts, execHost,, 
		contexDir, useIndicator,statusUpdateCb, client_data)

DtActionInvoke() は、アクション・データベースから、指定されたアクション名に一致するエントリを探して、指定されたクラス、型、およびカウントの引き数を受け入れます。アクションを実行する前に、アプリケーションはデータベースを初期化し、読み込まなければならないので注意してください。

DtActionInvoke() の例

次のコードは、actions.c の中の activateCB() (描画ボタンの起動コールバック) の一部です。

DtActionInvocationID actionId;
/* If a file was specified, build the file argument list */
printf("%s(%s)¥n",action,file);
if (file != NULL && strlen(file) != 0) {
  ap = (DtActionArg*) XtCalloc(1, sizeof(DtActionArg));
  ap[0].argClass = DtACTION_FILE;
  ap[0].u.file.name = file;
  nap = 1;
}
/* Invoke the specified action */
actionId = DtActionInvoke(shell,action,ap,nap,NULL,NULL,NULL,True,NULL,NULL);

actions.c のリスト

/*
  * (c) Copyright 1993, 1994 Hewlett-Packard Company
  * (c) Copyright 1993, 1994 International Business Machines Corp.
  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  * (c) Copyright 1993, 1994 Novell, Inc.
  */  

#include <Xm/XmAll.h> 
#include <Dt/Dt.h> 
#include <Dt/Action.h>  

#define ApplicationClass "Dtaction" 
 
static Widget shell; 
static XtAppContext appContext; 
static Widget actionText; 
static Widget fileText;  

static void CreateWidgets(Widget); 
static void InvokeActionCb(Widget, XtPointer, XtPointer); 
static void InvokeAction(char*, char*); 
static void DbReloadProc(XtPointer);  
void main(int argc, char **argv) 
{
     Arg args[20];
     int n=0;
     int numArgs = 0;

      shell = XtAppInitialize(&appContext , ApplicationClass, NULL, 0,
 								&argc, argv, NULL, args, n);

      CreateWidgets(shell);

   	if (DtInitialize(XtDisplay(shell), shell, argv[0],
 		ApplicationClass)==False) {
         /* DtInitialize() has already logged an appropriate error msg */
         exit(-1);
     }

     /* Load the filetype/action databases */
     DtDbLoad();
     /* Notice changes to the database without needing to restart application
 */
     DtDbReloadNotify(DbReloadProc, NULL);
     XtRealizeWidget(shell);
     XmProcessTraversal(actionText, XmTRAVERSE_CURRENT);

     XtAppMainLoop(appContext); 
}

static void CreateWidgets(Widget shell) 
{
     Widget messageBox, workArea, w;
     Arg args[20];
     int n;
     XmString labelString;
      labelString = XmStringCreateLocalized("Invoke");
      n = 0;
     XtSetArg(args[n], XmNdialogType, XmDIALOG_TEMPLATE); n++;
     XtSetArg(args[n], XmNokLabelString, labelString); n++;
     messageBox = XmCreateMessageBox(shell, "messageBox", args, n);
     XtManageChild(messageBox);
     XmStringFree(labelString);
     XtAddCallback(messageBox, XmNokCallback, InvokeActionCb, NULL);

     n = 0;
     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
     XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
     XtSetArg(args[n], XmNnumColumns, 2); n++;
     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_END); n++;
     workArea = XmCreateWorkArea(messageBox, "workArea", args, n);
     XtManageChild(workArea);

     labelString = XmStringCreateLocalized("Invoke Action:");
     n = 0;
     XtSetArg(args[n], XmNlabelString, labelString); n++;
     w = XmCreateLabel(workArea, "actionLabel", args, n);
     XtManageChild(w);
     XmStringFree(labelString);

     labelString = XmStringCreateLocalized("On File:");
     n = 0;     XtSetArg(args[n], XmNlabelString, labelString); n++;
     w = XmCreateLabel(workArea, "fileLabel", args, n);
     XtManageChild(w);
     XmStringFree(labelString);

     n = 0;
     XtSetArg(args[n], XmNcolumns, 12); n++;
     actionText = XmCreateTextField(workArea, "actionText", args, n);
     XtManageChild(actionText);

     n = 0;
     XtSetArg(args[n], XmNcolumns, 12); n++;
     fileText = XmCreateTextField(workArea, "fileText", args, n);
     XtManageChild(fileText); 
}

static void DbReloadProc(XtPointer cd) 
{
     /* Pick up any dynamic changes to the database files */
     DtDbLoad(); 
}  

static void InvokeActionCb(Widget w, XtPointer cd, XtPointer cb) 
{
     char *action;
     char *file;

     action = XmTextFieldGetString(actionText);
     if (action == NULL) return;
     if (strlen(action) == 0) {
         XtFree(action);
         return;
     }

     file = XmTextFieldGetString(fileText);

     InvokeAction(action, file);

     XtFree(action);
     XtFree(file); 

     XmTextFieldSetString(actionText, "");
     XmTextFieldSetString(fileText, "");
     XmProcessTraversal(actionText, XmTRAVERSE_CURRENT); 
}  

static void InvokeAction(char *action, char *file) 
{
     DtActionArg *ap = NULL;

int nap = 0;
     DtActionInvocationID actionId;

      /* If a file was specified, build the file argument list */  

printf("%s(%s)¥n",action,file);
     if (file != NULL && strlen(file) != 0) {
         ap = (DtActionArg*) XtCalloc(1, sizeof(DtActionArg));
         ap[0].argClass = DtACTION_FILE;
         ap[0].u.file.name = file;
         nap = 1;
     }

     /* Invoke the specified action */

  	actionId = DtActionInvoke(shell,action,ap,nap,NULL,NULL,NULL,True,NULL,NULL); 

}

第 9 章 データ型データベースのアクセス

この章では、データ型関数とデータ型データベースの使い方について説明します。

要約

データ型により、従来の UNIX ファイル・システムによって提供される機能を越えて、ファイルとデータの属性が拡張されます。これらの拡張は、アイコン名、記述、アクションなどの属性から成っており、ファイルがデータ上で実行できます。この情報は、DATA_ATTRIBUTES テーブル (またはデータベース) に名前と値の対として格納されます。デスクトップは、次のパラグラフで説明する特定の DATA_ATTRIBUTES のセットを使用します。DATA_ATTRIBUTES テーブルは、将来およびアプリケーション固有の成長のために拡張可能ですが、他のアプリケーションでは追加をチェックできないので、このテーブルを拡張することは推奨しません。

データを、特定のファイルまたは DATA_CRITERIA テーブルのデータ・エントリに一致させます。DATA_CRITERIA テーブルのエントリは、具体性が高いものから具体性が低いものへ降順で並べられます。たとえば、/usr/lib/lib*/usr/* よりも具体的なので、/usr/* より前に置かれます。ファイルまたはデータの型の検査が要求されると、このテーブルが始めから順にチェックされ、ファイルまたはデータから与えられた情報を使用して最も一致するものが検索されます。情報に一致するエントリが見つかると、DATA_ATTRIBUTES_NAME を使用して、正しい DATA_ATTRIBUTES エントリが検索されます。

アプリケーションがデスクトップと同じ方法でデータ・オブジェクト (ファイルまたはデータ・バッファ) をユーザに提示するようにする場合は、DtDts* API を使用して、データ・オブジェクトの表示方法とデータ・オブジェクトの操作方法を指定します。たとえば、アプリケーションは、ICON 属性に対して DtDtsDataTypeToAttributeValue() 関数を呼び出すことによって、データ・オブジェクトを表すアイコンを判断できます。

ライブラリとヘッダ・ファイル

データ型を使用するには、libDtSvc ライブラリをリンクしてください。アクションは、通常はデータ型情報と一緒に読み込まれます。アクションは、libXm ライブラリと libX11 ライブラリのリンクを必要とします。ヘッダ・ファイルは、Dt/Dts.hDt/Dt.h です。

デモ・プログラム

データ型データベースの使用例が入っているデモ・プログラムが、/usr/dt/examples/dtdts/datatypes/datatyping.c にあります。

データの基準とデータの属性

データ型検査は、次の 2 つの部分から成ります。

データ基準の属性は、次のとおりです (アルファベット順)。

データの基準を使用頻度が高いものから順に表 9-1 に示します。

表 9-1 データの基準 (使用頻度順)

基準 

説明 

使用例 

DATA_ATTRIBUTES_NAME

このデータ型の名前。この値は、データ属性テーブルの中の record_name です。

POSTSCRIPT 

NAME_PATTERN

このデータに一致するファイル名を記述するシェル・パターン照合表現。デフォルトは空の文字列で、照合の際にファイル名のパターンを無視することを意味します。 

*.ps

CONTENT

ファイル・ユーティリティが使用し、マジック・ファイルの開始、型、および値のフィールドとして解釈される 3 つの値。詳細は、file(1) のマニュアル・ページを参照してください。デフォルトは空のフィールドで、照合の際に内容を無視することを意味します。一致する型の例としては、文字列、バイト、ショート、ロング、およびファイル名があります。

0 string !%

MODE

stat 構造体のモード・フィールドに一致する 0 〜 4 文字の文字列。詳細は、stat(2) のマニュアル・ページを参照してください。最初の文字は、次のとおりです。

 

d は、ディレクトリに一致します。

s は、ソケットに一致します。

l は、シンボリック・リンクに一致します。

f は、通常ファイルに一致します。

b は、ブロック・ファイルに一致します。

c は、文字型特殊ファイルに一致します。

f&!x

 

 

 

次の文字は、最初または後続の文字にできます。 

 

r は、ユーザ、グループ、またはその他の読み取り権ビットが設定されたファイルに一致します。

w は、ユーザ、グループ、またはその他の書き込み権ビットが設定されたファイルに一致します。

x は、ユーザ、グループ、またはその他の実行あるいはディレクトリ検索のアクセス権ビットが設定されているファイルに一致します。

 

 

 

たとえば、frwMODE フィールドは、読み取り可能または書き込み可能な通常ファイルに一致します。x は、実行可能なビットまたは検索ビットが設定されたファイルに一致します。

デフォルトは空のフィールドで、照合の際にモードを無視することを意味します。 

 

PATH_PATTERN

このデータに一致する絶対パス名を記述するシェル・パターン照合式。デフォルトは空の文字列で、照合の際にパス・パターンを無視することを意味します。 

*/mysubdir /*

LINK_NAME

dtdtsfile(4) のマニュアル・ページを参照してください。

LINK_PATH

dtdtsfile(4) のマニュアル・ページを参照してください。

データ型の一般的な属性のいくつかをアルファベット順に示します。

これらのデータの属性を使用頻度が高い順に表 9-2 に示します。

表 9-2 データの属性 (使用頻度順)

基準 

説明 

使用例 

DESCRIPTION

人間が読める形式で書かれたデータの説明。このフィールドが NULL か、データ属性レコードに含まれていない場合は、データ属性名が使用されます。

This is a PostScript page description. 

ICON

このデータに対して使用されるアイコン名。このフィールドが NULL か、データ属性レコードに含まれていない場合は、標準のアイコンが使用されます。アイコンの命名の詳細は、dtdtsfile(4) のマニュアルページを参照してください。

Dtps

PROPERTIES

このデータの属性を示すキーワード。有効な値は、見える場合と見えない場合があります。このフィールドが NULL か、データ属性レコードに含まれていない場合は、可視属性とみなされます。これは、ファイルをユーザから完全に隠したい場合に使用します。

invisible

ACTIONS

このデータに対して実行できるアクションのリスト。このリストは、この型のオブジェクトに対してユーザに提示されるアクションのアクション・テーブル内の名前を参照します。このフィールドが NULL か、データ属性レコードに含まれていない場合は、どのアクションも使用できません。

Open,Print

NAME_TEMPLATE フィールド

 

この型のデータの新規ファイル作成に使用される文字列。文字列は、ファイル名と共に 1 つの引き数として sprintf(3) に渡されます。デフォルトは空です。このフィールドをデータ抽出条件テーブルの NAME_PATTERN フィールドと比較してみてください。テンプレートは %s.c など、特定のファイルを作成するために使用されますが、パターンは *.c などのファイルを検索するために使用されます。

%s.ps

IS_EXECUTABLE フィールド

このデータ型をアプリケーションとして実行できることをユーザに知らせる文字列論理値。IS_EXECUTABLE に true が設定されている場合 (DtDtsIsTrue() 参照)、データは実行可能です。このフィールドが NULL かデータ属性レコードに含まれていない、または true に設定されていない場合は、データは実行可能ではないとみなされます。

true 

MOVE_TO_ACTION

オブジェクトが現在のオブジェクトに移動されるときに実行されるアクション名 

FILESYSTEM_MOVE

COPY_TO_ACTION

オブジェクトが現在のオブジェクトにコピーされるときに実行されるアクション名 

FILESYSTEM_COPY

LINK_TO_ACTION

オブジェクトが現在のオブジェクトにリンクされるときに実行されるアクション名 

FILESYSTEM_LINK

IS_TEXT

このデータ型がテキスト・エディタまたはテキスト・ウィジェットでの操作 (表示または編集) に適していることをユーザに知らせる文字列論理値。データが本来はテキストである場合や、ユーザに対してテキスト形式で表示される場合、IS_TEXT フィールドには true が設定されます (DtDtsIsTrue() 参照)。その基準は、データが人間の言語から成るものか、手動で生成および管理されているか、テキスト・エディタでの表示と編集が可能か、構造体と書式の情報をまったく (あるいはごくわずかしか) ないかどうかという点から決定されます。

詳細な例については、表 9-3 を参照してください。

 

IS_TEXT フィールドが true の場合、データはアプリケーションから直接表示できます。すなわち、アプリケーションは XmText などのテキスト編集ウィジェットにデータを直接読み込むことができます。

 

MEDIA フィールド

MEDIA ネーム・スペース名は、データそのものの形式について記述します。MEDIA 名は、ICCCM 選択ターゲットとして使用され、データ型レコードの MEDIA フィールドで名前が付けられ、ToolTalk メディア交換メッセージの型パラメータの中で使用されます。

 

MEDIA ネーム・スペースは、ICCCM によって定義された選択ターゲット・アトムのネーム・スペースのサブセットです。データ書式を指定する選択ターゲットは、すべて有効な MEDIA 名です。有効な MEDIA 名は選択ターゲットとして直接使用できます。データ書式ではなく、選択の属性 (たとえば、LIST_LENGTH) や発生する副作用 (たとえば、DELETE) を指定する選択ターゲットもあります。これらの属性選択ターゲットは、MEDIA ネーム・スペースの一部ではありません。

POSTSCRIPT

MIME_TYPE

MEDIA は、デスクトップ内部にあり、データ型を表す一意の名前です。ただし、外部の他の命名組織もネーム・スペースを設定しています。MIME RFC で述べられている Multipurpose Internet Message Extensions (MIME)は、そのような外部登録の 1 つであり、デスクトップ・メール・プログラムのための標準的なネーム・スペースです。

application/postscript

X400_TYPE

X.400 型は、構造は MEDIA 型に似ていますが、異なる規則を使用して書式化され、異なる命名組織を持ちます。

1 2 840 113556 3 2 850

INSTANCE_ICON フィールド

データのインスタンスのために使用されるアイコン名で、通常は %name%.icon などの値 (dtdtsfile(4) のマニュアル・ページの「バグ」も参照)。INSTANCE_ICON が設定されている場合は、アプリケーションは ICON の代わりに使用しなければなりません。このフィールドが NULL か、データ属性レコードに含まれていない場合は、ICON フィールドが使用されます。

/myicondir/%name%.bm

DATA_HOST

DATA_HOST 属性は、*.dt ファイルのデータ属性テーブルに追加できるフィールドではありませんが、テーブルから属性を読み込むアプリケーションに返すことができます。データ型検査サービスはこの属性を自動的に追加して、データ型の読み込み元のホスト・システムを示します。このフィールドが NULL か、データ属性レコードに含まれていない場合、データ型はローカル・システムから読み込まれています。

 

IS_TEXT フィールドは、MIME_RFC で述べられている MIME コンテント・タイプである MIME_TYPE フィールドのテキスト属性とは異なります。MIME コンテント・タイプから、データがテキスト文字とバイト値のどちらで作成されているかがわかります。データがテキスト文字で作成され、データに text/* というラベルが付けられている場合、IS_TEXT フィールドはテキスト形式でユーザに表示するのに適したデータかどうかを判別します。

さまざまな MIME_TYPE属性での IS_TEXTの使用例を表 9-3 に示します。

表 9-3 IS_TEXT 属性の例

説明と MIME_TYPE 属性 

IS_TEXT 値 

ASCII でコード化された人間の言語 (MIME_TYPE text/plain)

IS_TEXT true

*EUC、JIS、Unicode、または ISO ラテン文字セットにコード化された人間の言語 (MIME-TYPE text/plain; charset=XXX)

IS_TEXT true

カレンダ・アポイント (MIME_TYPE text/plain)

IS_TEXT false

ハイパーテキスト・マークアップ言語 (HTML) (MIME_TYPE text/html)

IS_TEXT true

PostScript (MIME_TYPE application/postscript)

IS_TEXT false

C プログラム・ソース (C_SRC) (MIME_TYPE text/plain)

IS_TEXT true

ビットマップとピックスマップ (XBMXPM) (MIME_TYPE text/plain)

IS_TEXT false

デスクトップ・アプリケーション・ビルド・サービスのためのプロジェクトまたはモジュール・ファイル (MIME_TYPE text/plain)

IS_TEXT false

シェル・スクリプト (MIME_TYPE text/plain)

IS_TEXT false

uuencode(1) によって生成されたコード化テキスト (MIME_TYPE text/plain)

IS_TEXT false

*MIME_TYPE text/plain

IS_TEXT false

データ型属性の詳細は、dtdtsfile(4) のマニュアル・ページを参照してください。

データ型関数

データ・オブジェクトの属性を調べるには、まずオブジェクトの型を判断し、その型の適切な属性値を求めなければなりません。データベースにデータ情報を問い合わせるための関数を表 9-4 に示します。セクション 3 にこれらの関数のマニュアル・ページがあります。詳細は、該当するマニュアル・ページを参照してください。

表 9-4 データ型データベース問い合わせ関数

関数 

説明 

DtDtsBufferToAttributeList()

指定バッファのデータ属性のリストを検索します。 

DtDtsBufferToAttributeValue()

指定バッファのデータ属性を検索します。 

DtDtsBufferToDataType()

指定バッファのデータ型名を検索します。 

DtDtsDataToDataType()

指定データ・セットのデータ型を検索します。 

DtDtsDataTypeIsAction()

結果として保存されたディレクトリのデータ型を返します。 

DtDtsDataTypeNames()

使用可能なデータ型のリストを検索します。 

DtDtsDataTypeToAttributeList()

指定データ属性名の属性リストを検索します。 

DtDtsDataTypeToAttributeValue()

指定データ属性名の属性値を検索します。 

DtDtsFileToAttributeList()

指定ファイルのデータ属性のリストを検索します。 

DtDtsFileToAttributeValue()

指定ファイルのデータ属性値を検索します。 

DtDtsFileToDataType()

指定ファイルのデータ型を検索します。 

DtDtsFindAttribute()

属性 namevalue に一致するデータ型のリストを検索します。

DtDtsFreeAttributeList()

指定属性リストのメモリを解放します。 

DtDtsFreeAttributeValue()

指定属性値のメモリを解放します。 

DtDtsFreeDataType()

指定データ型名のアプリケーション・メモリを解放します。 

DtDtsFreeDataTypeNames()

DtDtsDataTypeNames() または DtDtsFindAttribute() を呼び出して作成されたメモリを解放します。

DtDtsIsTrue()

文字列を論理値に変換する簡易関数 

DtDtsRelease()

一般的には再読み込みの準備として、データ型データベース情報の読み込みを解除します。 

DtDtsSetDataType()

指定されたディレクトリのデータ型を設定します。 

DtsLoadDataTypes()

データ型関数のためにデータベース・フィールドを初期化し、読み込みます。アクションまたはアクション型を使用する必要がなく、パフォーマンスを向上させたい場合は、DtDbLoad() の代わりに使用します。アクションを使用する必要がある場合は DtDbLoad() を使用します。

データ型を検査して属性を検索するには、簡易、中間、拡張の 3 つの方法があります。

簡易データ型検査

データ型を検査するための最も簡単な方法は、次の関数を使用することです。

これらの関数を使用すると、ファイルの型が検査され、単一の属性またはリスト全体が検索されます。システム・コールが行われ、データ型の検査と属性の検索が行われます。次の関数は、中間データ型検査関数を呼び出します。

バッファは、読み取り権/書き込み権を持つ通常ファイルに一致するモードを持つと想定されます。読み専用バッファの型の検査については、「拡張データ型検査」を参照してください。

中間データ型検査

データの型を検査して属性を検索する場合、プロセスのデータ型検査部分は、パフォーマンスの点で最もコストがかかります。データ型の検査を 2 番目の方法で行うと、データ型検査のための関数と属性検索のための関数を切り離すことによって、パフォーマンスを改善できます。中間データ型検査には、次の関数を使用します。

アプリケーションが複数の属性値を問い合わせる場合には、これらの関数を使用します。これらの関数を使用すると、オブジェクトの型が検査され、その型を使用して属性リストから 1 つ以上の属性を検索します。

データ型検査と属性の検索を行うには、中間データ型関数を使用するようにしてください。これらの関数は、拡張データ型関数を呼び出し、バッファについて簡易データ型検査と同様に想定します。

拡張データ型検査

拡張データ型検査では、システム・コール、データ型、さらには属性検索も別々に行われます。拡張データ型検査では、あらかじめ初期化されてデータ型関数の一部としては含まれない既存のシステム・コールからのデータを使用するので、コード化が複雑になります。拡張データ型検査には、次の関数を使用してください。

DtDtsDataToDataType()

読み取り専用バッファの型を検査するには、st_mode フィールドが S_IFREG | S_IROTH |S_IRGRP | S_IRUSR に設定された stat 構造体が渡されなければなりません。

アクションであるデータ型 (DtDtsDataTypeIsAction)

データベースが読み込まれるとアクションの検査ができるようになるため、データベースの各アクションに対して合成データ型が生成されます。これらのデータ型は、次の 2 つの追加の属性を持つことができます。

ドロップ領域としてのオブジェクトの登録

アプリケーションがデータ型を定義する場合は、次の手順に従ってプログラマが意図したドラッグ & ドロップ動作のすべてが提供されているか確認してください。

  1. アプリケーションの中で、データ型を定義する必要があるかどうかを指定します。

  2. 定義する各データ型について、関連するオブジェクトをドロップ領域にするかどうかを指定します。

  3. ドロップ領域として登録する各オブジェクトについて、どの操作 (移動、コピー、またはリンク) を定義するかを指定します。

  4. 各オブジェクトに対して有効なドロップ操作について、適切なドロップ・アクションを定義します (MOVE_TO_ACTIONCOPY_TO_ACTION、および LINK_TO_ACTION 属性を設定してください)。

アプリケーションがデータ・オブジェクトのアイコンを表示する場合、それらのアイコンをドロップ領域としてサポートしなければならないこともあります。その場合、MOVE_TO_ACTIONCOPY_TO_ACTION、または LINK_TO_ACTION 属性を問い合わせて、それらのデータ・オブジェクトのドロップ動作を指定する必要があります。対応する属性値が NULL でない場合だけ、オブジェクトはドロップ操作をサポートしなければなりません。3 つの属性すべてが NULL の値を持つ場合、オブジェクトはドロップ領域として登録されません。データ型が定義されているオブジェクトの属性を最低 1 つでも設定すると、アプリケーションはそのオブジェクトをドロップ領域として登録できます。

ユーザがオブジェクトをドロップ領域にドラッグすると、アプリケーションはドロップを行うためにどのジェスチャ (すなわち、どのドラッグ操作) が使用されたかを判断します。ドラッグ操作とドロップ領域のデータ型に基づいて、アプリケーションはデータ型データベースからドロップ属性を検索します。次に、DtActionInvoke を呼び出して、次の 2 つの規則によってパラメータを判断します。

  1. ユーザがオブジェクト A と B をオブジェクト C 上にドロップした場合は、C、A、B を args として DtActionInvoke を呼び出します。action は、C の MOVE_TO_ACTIONCOPY_TO_ACTIONLINK_TO_ACTION のいずれかの値です。オブジェクト C がアクションの場合、args リストは C を含みません。また、action は C です。

ファイル・マネージャとそのディレクトリおよびフォルダ・オブジェクトは、デスクトップが移動、コピー、およびリンクされたドロップ属性を使用する方法を示す例となります。ユーザは、オブジェクト (ファイル) をディレクトリ・フォルダへドラッグ & ドロップできます。ファイル・マネージャは、フォルダ・オブジェクトに対して、MOVE_TO_ACTIONCOPY_TO_ACTION、および LINK_TO_ACTION アクションを定義します。これらのアクションは、適切なファイル・システムの移動、コピー、およびリンクのためのシステム関数を実行します。

MOVE_TO_ACTIONCOPY_TO_ACTION、および LINK_TO_ACTION 属性の定義の例については、/usr/dt/appconfig/types/C/dtfile.dt を参照してください。ドラッグ & ドロップの使用方法の詳細は、第 5 章「ドラッグ & ドロップとの統合」を参照してください。

データ型データベースの使用例

この節では、データ型検査のコード例を示します。このコード例は、/usr/dt/examples/dtdts/datatyping.c にあります。このサンプル・コードは、渡された各ファイルのデータ型、アイコン名、およびサポートされるアクションを示します。dtaction クライアントを使用して、サポートされているアクションをファイルで実行することもできます。datatyping の使い方は、次のとおりです。

datatyping file1 [file2 ...] 
#include <Xm/Form.h> 
#include <Xm/Text.h> 
#include <Dt/Dts.h> 

#define ApplicationClass "DtDatatyping"  

static Widget text;  

static void DisplayTypeInfo(int, char**);  

int main(int argc, char **argv) 
{
     XtAppContext appContext;
     Widget toplevel, form;
     Arg args[20];
     int n;

     toplevel = XtAppInitialize(&appContext, ApplicationClass,
 	  NULL, 0,
         argc, argv, NULL, NULL, 0);

     if (argc == 1) {
         printf("%s: No files specified.¥n", argv[0]);
         exit(1);
     }

     form = XmCreateForm(toplevel, "form", NULL, 0);
     XtManageChild(form);
     n = 0;
     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNeditable, False); n++;
     XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
     XtSetArg(args[n], XmNrows, 25); n++;
     XtSetArg(args[n], XmNcolumns, 90); n++;
     text = XmCreateScrolledText(form, "text", args, n);
     XtManageChild(text);

     XtRealizeWidget(toplevel);
 	  if (DtAppInitialize(appContext, XtDisplay(toplevel), toplevel, argv[0],
                                                 ApplicationClass) == False) {
         printf("%s: Couldn't initialize Dt¥n", argv[0]);
         exit(1);
     }

     DtDbLoad();

     DisplayTypeInfo(argc, argv); 

     XtAppMainLoop(appContext); 
}  

static void DisplayTypeInfo(int argc, char **argv) 
{
     char *file;
     char *datatype;
     char *icon;
     char *actions;
     char str[100];
     int i;

     sprintf(str, "%-30s¥t%-10s¥t%-8s¥t%-20s¥n",
                 "File",
                 "DataType",
                 "Icon",
                 "Actions");
     XmTextInsert(text, XmTextGetLastPosition(text), str);

     sprintf(str, "%-30s¥t%-10s¥t%-8s¥t%-20s¥n",
                 "-------------------",
                 "--------",
                 "----",
                 "-------");
     XmTextInsert(text, XmTextGetLastPosition(text), str);

      for(i=1; i < argc; i++) {
         char *file = argv[i];

         /* find out the Dts data type */
         datatype = DtDtsFileToDataType(file);

         if(datatype) {
             /* find the icon attribute for the data type */
             icon = DtDtsDataTypeToAttributeValue(datatype,
				 		 DtDTS_DA_ICON, file);
         }

  	 /*  Directly find the action attribute for a file */

          actions = DtDtsFileToAttributeValue(file,
 			 DtDTS_DA_ACTION_LIST);
          sprintf(str, "%-30s¥t%-10s¥t%-8s¥t%s¥n",
                         file,
                         datatype?datatype:"unknown",
                        icon?icon:"unknown",
                         actions?actions:"unknown");
         XmTextInsert(text, XmTextGetLastPosition(text), str);

         /* Free the space allocated by Dts */

         DtDtsFreeAttributeValue(icon);
         DtDtsFreeAttributeValue(actions);
         DtDtsFreeDataType(datatype);     
}

第 10 章 カレンダとの統合

カレンダのアプリケーション・プログラム・インタフェース (API) は、ネットワーク環境でカレンダ・データにアクセスし、管理するためのプログラム的な方法を提供します。API は、項目の挿入、削除、変更だけでなく、ブラウズおよび検索機能もサポートします。また、カレンダ管理関数をサポートします。

カレンダ API は、X.400 Application Programming Interface Association (XAPIA) の Calendaring and Scheduling API (CSA API) を実装しています。CSA API は、カレンダが有効なアプリケーションからカレンダおよびスケジュール・サービスのさまざまな機能へのアクセスを可能にする高水準の関数のセットを定義しています。最新の XAPIA 仕様の詳細は、X.400 API Association (800 El Camino Real, Mountain View, California 94043) に問い合わせてください。

この章では、次の節でカレンダ API を説明します。

ライブラリとヘッダ・ファイル

カレンダ API を使用するには、libcsa ライブラリをリンクする必要があります。ヘッダ・ファイルは、csa/csa.h です。

デモ・プログラム

カレンダ API の使用例を示すデモ・プログラムが、/usr/dt/examples/dtcalendar にあります。

カレンダ API の使い方

カレンダと統合するには

カレンダ API は、ネットワーク環境でカレンダ・データにアクセスし、管理する方法を提供します。

  1. アプリケーションに csa/csa.h を組み込みます。

  2. カレンダ API を使用して、アプリケーションの中で使用するカレンダ操作を組み込みます。

  3. libcsa とリンクします。

CSA API の概要

CSA インタフェースは、カレンダおよびスケジュール・サービスへの共通インタフェースを可能にします。CSA 実装のそれぞれについて、CSA によって与えられる表示と機能は、基本のカレンダ・サービスの表示と機能にマップされなければなりません。インタフェースは、実際のカレンダおよびスケジュールの実装に依存しないように設計されています。また、インタフェースは、カレンダ・サービスが使用するオペレーティング・システムと基本のハードウェアに依存しないように設計されています。

提供される関数呼び出しの数は、最小限のものです。一組の関数で複数の種類のカレンダ項目を管理します。

C の命名規則

表 10-1 に示すように、C インタフェースの要素の識別子は、要素の属性名とそれに関連するデータ型に由来します。属性名には、テーブルの 2 番目の欄の文字列が接頭辞として付けられます。英字は、3 番目の欄の大文字または小文字に変換されます。

表 10-1 C 命名規則の由来

要素の種類 

接頭辞 

大文字/小文字 

データ型 

CSA_

小文字 

データの値 

CSA_

大文字 

関数 

csa_

小文字 

関数の引き数 

なし

小文字 

関数の結果 

なし

小文字 

定数 

CSA_

大文字 

エラー 

CSA_E_

大文字 

マクロ 

CSA_

大文字 

拡張セットのために確保 

CSA_XS_

大文字/小文字 

拡張のために確保 

CSA_X_

大文字/小文字 

処理系作成者が使用するために確保 

CSAP

大文字/小文字 

ベンダ関数拡張のために確保 

csa_x

小文字 

構造体のタグ 

CSA_TAG_

大文字 

接頭辞 CSAP (大文字/小文字) が付いている要素は、CSA サービスの実装の作成者が内部専用として使用するために確保されています。CSA インタフェースによって書かれたプログラムが直接使用するためのものではありません。

接頭辞 CSA_XS_CSA_X_ (大文字/小文字)、および csa_x は、ベンダまたはグループによるインタフェースの拡張のために確保されています。仕様では、これらのインタフェース拡張は、基本関数セットの拡張として定義されています。

定数データ値の場合、定数データ値のデータ構造体または関数を示すために、通常、追加の文字列が CSA_ に追加されます。

機能のアーキテクチャ

本節では、CSA API をサポートしているサービスの機能のアーキテクチャを説明します。抽象実装モデル、抽象データ・モデル、および機能の概要を示します。

実装モデル

CSA API の適用範囲が理解できるように、抽象実装モデルが用意されています。

CSA インタフェースは、カレンダが使用可能なアプリケーションとカレンダ・サービスの間に定義されます。このインタフェースの機能はすべて、カレンダ・サービスに依存しないように設計されています。ただし、この API では、拡張の使用によって実行される共通関数のプロトコル固有の拡張は許されています。詳細は、「拡張」を参照してください。カレンダが使用可能なアプリケーションとカレンダ・サービスの CSA インタフェースの関係を図 10-1 に示します。

図 10-1 カレンダおよびスケジュール API の位置付け

Graphic

CSA インタフェースのモデルは、管理、カレンダ管理、および項目管理という 3 つのコンポーネントに分けることができます。これらのコンポーネントを図 10-2 に示します。

図 10-2 カレンダおよびスケジュール API のコンポーネント

Graphic

カレンダ・サービスへのアクセスは、カレンダ・セッションを通して確立されます。セッションは、カレンダ・サービスへの有効な接続のために用意され、サービスによって保持されるカレンダ情報の整合性の確保を支援します。カレンダが使用可能なアプリケーションは、カレンダ・サービス内の個々のカレンダにログインして、有効なセッションまたは接続を確立します。セッションは、カレンダが使用可能なアプリケーションがカレンダからログアウトすることによって終了します。

カレンダ・サービスは、1 つ以上のカレンダを保持します。カレンダ・サービスは、これらのカレンダに対して、いくつかのレベルの管理サポートを提供します。カレンダが使用可能なアプリケーションは、特定のカレンダ・サービスによって保持されるカレンダのリストにアクセスできます。さらに、カレンダ・サービスにより、実装固有の永続的形式にカレンダ情報を保管したり復元したりできます。カレンダ・サービスが複数のカレンダの保持をサポートする場合には、カレンダの作成と削除のためのサポート関数が定義されます。また、カレンダの特性を管理するための関数が定義されます。

CSA インタフェースのほとんどの関数は、個々のカレンダ項目を管理します。カレンダ項目は、イベント、予定、またはメモです。項目は、特定のカレンダへの追加、削除、更新、および読み取りができます。カレンダが使用可能なアプリケーションは、カレンダ項目に通知方法を追加できます。

データ・モデル

CSA インタフェースは、カレンダ・サービスによって保持されるカレンダ情報の概念上のバックエンドの記憶領域へのアクセス方法です。共通データ・モデルは、カレンダ・サービスによって保持されるカレンダ情報のコンポーネントを視覚化する際に役に立ちます。

カレンダ・エンティティ

データ・モデルは、カレンダ・エンティティの概念に基づきます。カレンダは、管理カレンダ属性とカレンダ項目の名前付きコレクションによって表されます。カレンダは、個々のユーザによって所有されます。ユーザは、個人、グループ、またはリソースを表します。

カレンダ属性は、カレンダに関する共通、実装固有、またはアプリケーション固有の管理特性を表す名前付きの値のセットです。たとえば、タイムゾーン、名前、所有者、およびカレンダへのアクセスの権利を、個々のカレンダ属性の中で指定できます。

カレンダ項目は、カレンダの主要なコンポーネントです。カレンダ項目の 3 つのクラスは、次のとおりです。

カレンダ項目は、固有な名前を付けられた項目属性のコレクションによって表されます。項目属性は、カレンダ項目の共通、実装固有、またはアプリケーション固有の特性を表す名前付きの値のセットです。たとえばイベントには、開始と終了の日付と時間、説明、およびサブタイプを指定できます。予定には、作成日、期限、優先順位、およびステータスを指定できます。メモには、作成日とテキスト内容または説明を入れることができます。

カレンダ属性と項目属性は、名前、型、値の 3 つの組から成ります。仕様によって定義されている共通属性を拡張できます。実装によって、固有の属性を定義できます。また、アプリケーションでアプリケーション固有の属性を定義するための機能を提供するものもあります。共通デスクトップ環境では、アプリケーション定義の属性をサポートします。

アクセス権

個々のユーザがカレンダにアクセスできるかどうかは、そのユーザに与えられるアクセス権によって制御されます。アクセス権は、カレンダのユーザと対になっています。CSA では、ユーザは、個人、グループ、またはリソースです。共通デスクトップ環境では、個々のユーザだけをサポートします。アクセス権は、アクセス・リストで保持されます。アクセス・リストは、特定のカレンダ属性です。アクセス権は、個別に制御され、それを累積することによって、カレンダとその項目に対するユーザのアクセスの範囲を定義できます。アクセス権は、次のアクセスの役割の観点から指定できます。

所有者の役割を与えられたユーザは、カレンダの所有者ができることであれば、カレンダまたはカレンダ項目に対して何でも実行できます。すなわち、カレンダの削除、カレンダ属性の表示、挿入、変更、カレンダ項目の追加と削除、項目属性の表示、挿入、および変更を実行できます。

主催者の役割を与えられたユーザは、そのユーザが主催者として指定されたカレンダ項目に対して、項目の削除、または項目属性の表示や変更を実行できます。デフォルトでは、項目を作成したカレンダ・ユーザが主催者です。

スポンサーの役割を与えられたユーザは、そのユーザがスポンサーとして指定されたカレンダ項目に対して、項目の削除、または項目属性の表示や変更を実行できます。スポンサーは、カレンダ項目を実質的に所有するカレンダ・ユーザです。

これらの役割に加えて、アクセス権の設定によって、公用、半私用、私用の分類に応じて、空き時間の検索へのアクセス、カレンダ属性の表示、挿入、変更、あるいは項目の表示、挿入、変更を制限できます。項目の分類は、アクセスできるかどうかの二次フィルタとして機能します。

機能の概要

CSA インタフェースは、主に 3 種類の作業をサポートします。

管理

CSA 関数呼び出しの大部分は、カレンダ・セッションの中で発生します。カレンダ・セッションは、カレンダが使用可能なアプリケーションとカレンダ・サービスによって保持された特定のカレンダとの間の論理的な接続です。セッションは、csa_logon() 関数の呼び出しで確立され、csa_logoff() 関数の呼び出しで終了します。セッションの状況は、セッション・ハンドルによって表されます。このハンドルは、1 つのカレンダ・セッションを他のセッションと見分けるためのトークンを各 CSA 関数の中で提供します。csa_logon() 関数は、また、カレンダ・サービスに対してユーザを認証し、セッション属性を設定します。現時点では、アプリケーション間でのカレンダ・セッションの共有はサポートされていません。

csa_list_calendars() 関数は、特定のカレンダ・サービスによって管理されるカレンダ名をリストするために使用されます。

csa_query_configuration()関数は、現在のカレンダ・サービスの構成に関する情報をリストするために使用されます。この情報は、文字セット、テキスト文字列の行終了文字、デフォルトのサービス名、指定されたカレンダ・サービスのデフォルトの認証ユーザ識別子、ユーザ識別子を認証するためにパスワードが必要かどうかを示すインジケータ、ユーザ・インタフェース・ダイアログの共通拡張がサポートされるかどうかを示すインジケータ、および実装によってサポートされる CSA 仕様などです。

CSA の実装は、サービスによって返されるカレンダ・オブジェクトおよび属性のためのメモリの管理をサポートします。csa_free() 関数は、このメモリが不要になったときに、解放するために使用されます。カレンダ・サービスによって割り当てられ、管理されるメモリを解放するのは、アプリケーションの責任です。

カレンダ管理

CSA インタフェースは、いくつかのカレンダ管理関数を提供します。共通デスクトップ環境では、1 つのカレンダ・サービスにつき複数のカレンダをサポートします。カレンダが使用可能なアプリケーションは、カレンダを追加したり削除したりできます。csa_delete_calendar() 関数は、カレンダを削除するために使用されます。csa_add_calendar() 関数は、サービスに新しいカレンダを追加するために使用されます。

アプリケーションは、また、csa_list_calendar_attributes()csa_read_calendar_attributes()、および csa_update_calendar_attributes() 関数を使用して、カレンダ属性のリスト、読み取り、および更新を実行できます。アプリケーションは、カレンダ・ログイン、カレンダの削除、カレンダ属性の更新、新しいカレンダ項目の追加、カレンダ項目の削除、およびカレンダ項目の更新について通知を受けるためのコールバック関数を登録できます。コールバック関数は、カレンダ・セッションの継続中だけ登録されます。この情報は、一部のカレンダ管理アプリケーションにとっては貴重なものです。

エントリ管理

CSA インタフェースは、カレンダ項目を管理するための強力な関数のセットを備えています。カレンダ・セッション中のカレンダ項目の状況は、項目ハンドルによって保持されます。このハンドルは、1 つのカレンダ項目を他の項目と見分けるためのトークンを CSA 関数の中で提供します。項目ハンドルは、csa_add_entry()csa_list_entries() 関数によって返されます。項目ハンドルは、カレンダ・セッションの継続期間、あるいは項目が削除または更新されるまで有効です。csa_free() の呼び出しによって解放されると、項目ハンドルは無効になります。

csa_add_entry() 関数は、カレンダに新しい項目を追加するために使用されます。csa_delete_entry() 関数は、カレンダの中の項目を削除するために使用されます。csa_list_entries() 関数は、項目属性基準の特定のセットと一致するカレンダ項目を列挙するために使用されます。csa_read_entry_attributes() 関数は、特定のカレンダ項目に関連するすべてまたは一組の項目属性値を取り出すために使用されます。

カレンダに項目を追加するには、カレンダが使用可能なアプリケーションは、まず csa_logon() 関数を使用して、カレンダ・サービスとのセッションを確立しなければなりません。次に、アプリケーションは、csa_add_entry() 関数を新しい項目を指定するために実行します。カレンダが使用可能なアプリケーションは、csa_add_entry() 関数の中で使われる属性を組み立てる責任があります。セッションの終了には、csa_logoff() 関数が使用されます。

個々のカレンダ項目の中の項目属性は、csa_list_entry_attributes() 関数で列挙できます。csa_read_entry_attributes() 関数を使用すると、1 つ以上の属性の値を読み取ることができます。個々の項目属性は、csa_update_entry_attributes() 関数で変更できます。

カレンダ情報を検索するために CSA の実装によって割り当てられたメモリは、関連するメモリ・ポインタを csa_free() 関数に渡すことによって解放されます。

再帰的活動に関連するカレンダ項目もあります。csa_list_entry_sequence() 関数を使用すると、他の再帰的カレンダ項目を列挙できます。この関数は、再帰的項目の項目ハンドルのリストを返します。

CDE カレンダ・サーバは、カレンダ項目に関連付けられるアラームまたは通知方法のサポートを提供します。通知方法は、端末のスピーカからの音声による通知、端末画面の点滅による通知、カレンダ・ユーザへのメール送信による通知、端末画面にポップアップを表示することによる通知などの形を取ることができます。カレンダ・サービスは通知方法を管理しますが、通知情報を検索し、情報に対処するのはカレンダ・アプリケーションの責任です。csa_read_next_reminder() 関数は、次のスケジュール済みの通知に関する情報を読み込むために使用されます。

拡張

CSA 仕様で定義されている大半のデータ構造と関数は拡張できます。拡張は、データ構造にフィールドを追加したり、関数呼び出しにパラメータを追加したりするために行われます。これらの拡張のための標準的な汎用データ構造が定義されています。それは、拡張を識別する項目コード、拡張データまたはデータ自体の長さを保持する項目データ、拡張値が格納されている場所を示す項目参照と、関連する項目の格納領域がない場合には NULL、および拡張のフラグから成ります。

関数呼び出しにパラメータを追加するような拡張を、入力または出力時に実行できます。すなわち、拡張は、アプリケーションから CSA サービスへの入力パラメータとして渡すことができ、または、CSA サービスからアプリケーションへの出力パラメータとして渡すこともできます。拡張が入力パラメータの場合には、アプリケーションは、拡張構造体と、その拡張に関連するその他の構造体のためのメモリを割り当てます。拡張が出力パラメータの場合には、CSA サービスは必要に応じて、拡張の結果のための記憶領域を割り当てます。この場合、アプリケーションは、割り当てられた記憶領域を csa_free() 呼び出しによって解放しなければなりません。

サポートされていない拡張が要求された場合には、CSA_E_UNSUPPORTED_FUNCTION_EXT が返されます。

共通デスクトップ環境 (CDE) の実装

CSA API の CDE 実装は、CDE カレンダ・サーバへのアクセスを可能にするライブラリです。ライブラリとサーバとの通信には、ONC の RPC が使用されます。CDE 実装におけるカレンダ・サーバは、カレンダ・プロトコル・バージョン 2 から 5、およびデータ・バージョン 3 と 4 をサポートするバージョン 5 です。カレンダ・プロトコルのバージョン 2 から 4 とデータ・バージョン 3 は、OpenWindows カレンダ・マネージャへの下位互換を確保するためのものです。カレンダ・プロトコル・バージョン 5 とデータ・バージョン 4 は CSA インタフェースとデータの拡張性をサポートします。

表 10-2 サポートされるサーバのバージョンとデータのバージョン

サーバのバージョン 

データのバージョン 

3、4 

サポートされるアクセス・モデル

2 つのアクセス・モデルがカレンダ API によってサポートされています。XAPIA CSA 仕様において指定されているアクセス・モデルは、データ・バージョン 4 のためだけにサポートされています。OpenWindows カレンダ・マネージャのアクセス・モデルは、データ・バージョン 1 から 3 までのためにサポートされています。OpenWindows のカレンダ・マネージャ・アクセス・モデルでは、カレンダのアクセス許可は、アクセス権を指定するアクセス・リストにより制御されます。次の 3 種類のアクセス権が定義されています。

CSA_X_DT_BROWSE_ACCESS (ユーザはカレンダのエントリをリストして、読み取ることができる)

CSA_X_DT_INSERT_ACCESS (ユーザはカレンダのエントリを挿入できる)

CSA_X_DT_DELETE_ACCESS (ユーザはカレンダのエントリを削除できる)

カレンダ API はすべてのバージョンのカレンダへのアクセスを可能にするので、プログラマは、データ・バージョンに対応する正しいアクセス・モデルを使用して、アクセス・リストに含まれるアクセス権を解釈しなければなりません。

カレンダが作成されるとき、アクセス・リストを指定しないかぎり、デフォルトのアクセス・リストにユーザ名として world という 1 つのエントリが含まれます。world のアクセス権では、公開エントリをブラウズできます。world というユーザ名は、すべてのユーザを意味する特別の名前です。

デフォルトでは、カレンダの所有者と同じユーザ名を持つユーザは、任意のマシンから、所有者のアクセス権でカレンダにアクセスできます。さらに厳しいアクセス制御をするには、owner-user-name@host という書式の名前をカレンダのアクセス・リストに追加できます。このようなエントリをアクセス・リストに追加するときは、対応するアクセス権は、データ・バージョン 4 では CSA_OWNER_RIGHTS、データ・バージョン 3 では (CSA_X_DT_BROWSE_ACCESS|CSA_X_DT_INSERT_ACCESS|CSA_X_DT_DELETE_ACCESS ) です。このようなエントリをアクセス・リストに追加した後は、指定されたホストからのユーザだけが所有者のすべての権利でカレンダにアクセスできます。

データ構造

表 10-3 に、CSA データ構造をリストします。詳細は、関連するマニュアル・ページを参照してください。

表 10-3 CSA データ構造

データ型の名前 

説明 

Access List 

カレンダ・ユーザのアクセスの権利構造体のリスト 

Attendee List 

出席者構造体のリスト 

Attribute 

属性構造体 

Attribute Reference 

属性参照構造体 

Boolean 

論理的な True または False を示す値 

Buffer 

データ項目のポインタ 

Calendar User 

カレンダ・ユーザ構造体 

Callback Data Structures 

コールバック・データ構造体 

Date and Time 

日付と時間の指定 

Date and Time List 

日付と時間の値のリスト 

Date and Time Range 

日付と時間の範囲 

Entry Handle 

カレンダ項目のハンドル 

Enumerated 

計算の値を含むデータ型 

Extension 

拡張構造体 

Flags 

ビート・マスクのコンテナ 

Free Time 

空き時間構造体 

Opaque Data 

不透明データ構造体 

Reminder 

通知方法構造体 

Reminder Reference 

通知方法参照構造体 

Return Code 

関数が成功したこと、または失敗した理由を示す戻り値 

Service Reference 

サービス参照構造体 

Session Handle 

カレンダ・セッションのハンドル 

String 

文字列ポインタ 

Time Duration 

継続時間 

カレンダ属性

表 10-4 に、共通デスクトップ環境でサポートされるカレンダ属性をリストします。詳細は、関連するマニュアル・ページを参照してください。カレンダ属性のリストは、拡張命名規則による拡張が可能です。

表 10-4 CSA カレンダ属性

属性名 

記号名 

サーバのバージョン 

データのバージョン 

読み取り専用 

Access List 

CSA_CAL_ATTR_ACCESS_LIST_ 

2-5 

1-4 

Calendar Name 

CSA_CAL_ATTR_CALENDAR_NAME 

2-5 

1-4 

○ * 

Calendar Owner 

CSA_CAL_ATTR_CALENDAR_OWNER 

2-5 

1-4 

○ * 

Calendar Size 

CSA_CAL_ATTR_CALENDAR_SIZE 

3,4 

○ 

Character Set 

CSA_CAL_ATTR_CHARACTER_SET 

○ 

Data Version** 

CSA_X_DT_CAL_ATTR_DATA_VERSION 

2-5 

1-4 

○ 

Date Created 

CSA_CAL_ATTR_DATE_CREATED 

○ 

Number Entries 

CSA_CAL_ATTR_NUMBER_ENTRIES 

2-5 

1-4 

○ 

Product Identifier 

CSA_CAL_ATTR_PRODUCT_IDENTIFIER 

2-5 

1-4 

○ 

Server Version** 

CSA_X_DT_CAL_ATTR_SERVER_VERSION 

2-5 

1-4 

○ 

Time Zone 

CSA_CAL_ATTR_TIME_ZONE 

○ 

Version 

CSA_CAL_ATTR_VERSION 

2-5 

1-4 

○ 

* カレンダ作成時に指定し、その後は読み取り専用になります。

** CDE のみ

次のカレンダ属性はサポートされません。

      
CSA_CAL_ATTR_COUNTRY
      CSA_CAL_ATTR_LANGUAGE
      CSA_CAL_ATTR_WORK_SCHEDULE

次の節では、表 10-4 にリストしたカレンダ属性について、追加の情報を提供します。

CDE 定義済みカレンダ属性は、次のとおりです。

項目属性

表 10-5 に、共通デスクトップ環境でサポートされる項目属性をリストします。詳細は、関連するマニュアル・ページを参照してください。項目属性のリストは、拡張命名規則による拡張が可能です。

表 10-5 CSA 項目属性

属性名 

記号名 

サーバのバージョン 

データのバージョン 

読み取り専用 

Audio Reminder 

CSA_ENTRY_ATTR_AUDIO_REMINDER 

2-5 

1-4 

Character Set* 

CSA_X_DT_ENTRY_ATTR_CHARACTER _SET 

Classification 

CSA_ENTRY_ATTR_CLASSIFICATION 

2-4 

Date Completed 

CSA_ENTRY_ATTR_DATE_COMPLETED 

Date Created 

CSA_ENTRY_ATTR_DATE_CREATED 

○ 

Description 

CSA_ENTRY_ATTR_DESCRIPTION 

Due Date 

CSA_ENTRY_ATTR_DUE_DATE 

End Date 

CSA_ENTRY_ATTR_END_DATE 

2-5 

1-4 

Exception Dates 

CSA_ENTRY_ATTR_EXCEPTION_DATES 

Flashing Reminder 

CSA_ENTRY_ATTR_FLASHING_ REMINDER 

2-5 

1-4 

Last Update 

CSA_ENTRY_ATTR_LAST_UPDATE 

○ 

Mail Reminder 

CSA_ENTRY_ATTR_MAIL_REMINDER 

2-5 

1-4 

Number Recurrences 

CSA_ENTRY_ATTR_NUMBER_ RECURRENCES 

○ 

Organizer 

CSA_ENTRY_ATTR_ORGANIZER 

2-5 

1-4 

○ 

Popup Reminder 

CSA_ENTRY_ATTR_POPUP_REMINDER 

2-5 

1-4 

Priority 

CSA_ENTRY_ATTR_PRIORITY 

Recurrence Rule 

CSA_ENTRY_ATTR_RECURRENCE_RULE 

Reference Identifier 

CSA_ENTRY_ATTR_REFERENCE_ IDENTIFIER 

2-5 

1-4 

○ 

Repeat Interval*  

CSA_X_ENTRY_ATTR_REPEAT_INTERVAL 

2-5 

1-4 

** 

Repeat Occurrence*  

CSA_X_ENTRY_ATTR_REPEAT_ OCCURRENCE_NUM 

2-5 

1-4 

** 

Repeat Times* 

CSA_X_ENTRY_ATTR_REPEAT_TIMES 

2-5 

1-4 

** 

Repeat Type* 

CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE 

2-5 

1-4 

** 

Sequence End Date* 

CSA_X_ENTRY_ATTR_SEQUENCE_END_ DATE 

2-5 

1-4 

** 

Showtimes* 

CSA_X_ENTRY_ATTR_SHOWTIME 

2-5 

1-4 

Sponsor 

CSA_ENTRY_ATTR_SPONSOR 

Start Date 

CSA_ENTRY_ATTR_START_DATE 

2-5 

1-4 

Status 

CSA_ENTRY_ATTR_STATUS  

2-5 

1-4 

Subtype 

CSA_ENTRY_ATTR_SUBTYPE 

2-5 

1-4 

Summary 

CSA_ENTRY_ATTR_SUMMARY 

2-5 

1-4 

Transparency 

CSA_ENTRY_ATTR_TIME_ TRANSPARENCY 

Type 

CSA_ENTRY_ATTR_TYPE 

2-5 

1-4 

○*** 

* CDE のみ

** データ・バージョン 1 から 3 については、この属性は指定または変更できます。ただし、データ・バージョン 4 については読み取り専用です。データ・バージョン 4 では、エントリ属性 CSA_ENTRY_ATTR_RECURRENCE_RULE から値が取られます。

***カレンダ作成時に指定し、その後は読み取り専用になります。

次のカレンダ属性はサポートされません。

      CSA_ENTRY_ATTR_ATTENDEE_LIST
      CSA_ENTRY_ATTR_EXCEPTION_RULE
      CSA_ENTRY_ATTR_RECURRING_DATES
      CSA_ENTRY_ATTR_SEQUENCE_NUMBER

次の節では、表 10-5 にリストした項目属性について、追加の情報を提供します。

      
CSA_X_DT_STATUS_ACTIVE
      CSA_X_DT_STATUS_DELETE_PENDING
      CSA_X_DT_STATUS_ADD_PENDING
      CSA_X_DT_STATUS_COMMITTED
      CSA_X_DT_STATUS_CANCELLED
      
CSA_X_DT_TYPE_OTHER

CDE エントリ属性

CDE 定義済み項目属性は、次のとおりです。

      
CSA_X_DT_REPEAT_ONETIME
      CSA_X_DT_REPEAT_DAILY
      CSA_X_DT_REPEAT_WEEKLY
      CSA_X_DT_REPEAT_BIWEEKLY
      CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY
      CSA_X_DT_REPEAT_MONTHLY_BY_DATE
      CSA_X_DT_REPEAT_YEARLY
      CSA_X_DT_REPEAT_EVERY_NDAY
      CSA_X_DT_REPEAT_EVERY_NWEEK
      CSA_X_DT_REPEAT_EVERY_NMONTH
      CSA_X_DT_REPEAT_MON_TO_FRI
      CSA_X_DT_REPEAT_MONWEDFRI
      CSA_X_DT_REPEAT_TUETHUR
      CSA_X_DT_REPEAT_WEEKDAYCOMBO
      CSA_X_DT_REPEAT_OTHER
      CSA_X_DT_REPEAT_OTHER_WEEKLY
      CSA_X_DT_REPEAT_OTHER_MONTHLY
      CSA_X_DT_REPEAT_OTHER_YEARLY

反復情報のエントリ属性

データ・バージョン 1 から 3 については、次の属性を使用してエントリの反復情報を指定します。すべて読み取りおよび書き込み属性です。

      CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE
      CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES
      CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL
      CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM
      CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE

データ・バージョン 4 については、エントリ属性 CSA_ENTRY_ATTR_RECURRENCE_RULECSA_ENTRY_ATTR_EXCEPTION_DATES を使用してカレンダ・エントリの反復情報を指定します。CSA_ENTRY_ATTR_RECURRENCE_RULE 属性の情報は、次の属性を使用して問い合わせることができます。

      CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE
      CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES
      CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL
      CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM
      CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE 

これらの計算された属性は、データ・バージョン 4 に対して読み取り専用です。

データ・バージョンによりサポートされる値

関数についての一般的な情報

次の一般的な情報は、すべての関数に適用されます。


注 -

ライブラリの中で渡されるテキストでの説明以外のデータは、すべて ASCII 形式でなければなりませんが、ライブラリはシングルバイトだけでなくマルチバイト文字列もサポートします。


サポートされる関数の拡張

管理関数

この節では、CDE でサポートされる管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

カレンダ管理関数

この節では、CDE でサポートされるカレンダ管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

項目管理関数

この節では、CDE でサポートされる項目管理関数について説明します。関数のプロトタイプと戻りコードのリストは、各関数に含まれています。詳細は、関連するマニュアル・ページを参照してください。

コーディング例

カレンダをリストして出力するには


例 10-1 サーバがサポートするカレンダをリストし出力する

Example:
List and print out the calendars supported by a server.
 	   Free memory returned by a CSA function. 
list_calendar() 
{
 	CSA_return_code		stat;
	CSA_uint32		i, number;
 	CSA_calendar_user	*calendars;
 	char			*host;

  	/* ネットワーク上のいくつかのマシンを指定します */
 	host = "somehost";

  	stat= csa_list_calendars(host, &number, &calendars, NULL);
  	for (i = 0; i< number; i++) {
 		/* calendar_address フィールドには、カレンダのアドレスが
 		 * user@host の書式で入っています		 */
 	printf("%d: %s¥n", i, calendars[i].calendar_address); 	
   }

  	/* 例: CSA 関数により返されるメモリを解放する
 	 * csa_list_calendars により返されるメモリを解放します
 	 */
 	stat = csa_free(calendars); 
}


カレンダを追加するには


例 10-2 activity という名前のカレンダをホスト host1 に追加する

#include <csa/csa.h>  

CSA_access_rights *setup_access_list() {
 	CSA_access_rights	*ptr1, *ptr2;
  	/* 任意のユーザに、公開および非公開エントリを表示する許可を与え、
 	 * ユーザ user1 に、公開エントリを表示し、挿入する許可を与えます。
 	 * 特別なユーザ名 world は任意のユーザを意味します。
   */

ptr2 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr2->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr2->user->user_name = strdup("world");
ptr2->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr2->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_VIEW_CONFIDENTIAL_ENTRIES;
ptr1 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr1->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr1->user->user_name = strdup("user1");
ptr1->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr1->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_INSERT_PUBLIC_ENTRIES;
ptr1->next = ptr2; 
} 

void destroy_access_list(CSA_access_rights *list) 
{
 	CSA_access_rights	*ptr;

  	while (list != NULL) {
 		ptr = list->next;

  		if (list->user) {
 			if (list->user->user_name)
 			free(list->user->user_name);
 			free(list->user);
 		} 		free(list);
  		list = ptr;
 	}
} 
add_calendar() 
{
 	CSA_return_code		stat;
 	CSA_calendar_user	caddr;
 	CSA_attribute		attr;
 	CSA_attribute_value	attr_val;

  	/* 追加するカレンダを指定します。 */

 	caddr.user_name = NULL;
 	caddr.user_type = NULL;
 	caddr.calendar_address = "activity@host1";
 	caddr.calendar_user_extensions = NULL;

  	/* アクセス・リストを設定します */
 	attr_val.type			= CSA_VALUE_ACCESS_LIST;
 	attr_val.item.access_list_value	= setup_access_list();
 	attr.name			= CSA_CAL_ATTR_ACCESS_LIST;
 	attr.value			= &attr_val;
 	attr.attribute_extensions	= NULL;
  	stat = csa_add_calendar(NULL, &caddr, 1, &attr, NULL);
  	destroy_access_list(attr_val.item.access_list_value);
}


カレンダにログインするには


例 10-3 カレンダにログインする

CSA_session_handle	cal;

logon() 
{
 	CSA_return_code		stat;
 	CSA_calendar_user	caddr;
 	CSA_flags		access;
 	CSA_extension		logon_exts[2];
 	CSA_X_COM_support	check_support[2];

  	/* ログインするカレンダを指定します */
caddr.user_name = NULL;
caddr.user_type = CSA_USER_TYPE_INDIVIDUAL;
caddr.calendar_address = "user@host";
caddr.calendar_user_extensions = NULL;

  	/* (CSA_X_DT_GET_USER_ACCESS_EXT) を指定して、
 	 * カレンダに関するユーザのアクセス権を取得します。
 	 */
logon_exts[0].item_code		= CSA_X_DT_GET_USER_ACCESS_EXT;
logon_exts[0].item_data		= 0;
logon_exts[0].item_reference	= NULL;
logon_exts[0].extension_flags	= NULL;

	/* CSA_X_COM_SUPPORT_EXT 拡張を指定して、
 	 * CSA_X_XT_APP_CONTEXT_EXT 拡張と、CSA_X_UI_ID_EXT 拡張が
 	 * サポートされているかどうかをチェックします。
 	 */
check_support[0].item_code	= CSA_X_XT_APP_CONTEXT_EXT;
check_support[0].flags		= NULL;
check_support[1].item_code	= CSA_X_UI_ID_EXT;
check_support[1].flags		= NULL;
logon_exts[1].item_code		= CSA_X_COM_SUPPORT_EXT;
logon_exts[1].item_data		= 2;
logon_exts[1].item_reference	= (CSA_buffer)check_support;
logon_exts[0].extension_flags	= CSA_EXT_LAST_ELEMENT;

  	stat = csa_logon(NULL, &caddr, NULL, NULL, NULL, &cal, logon_exts);

  	if (stat == CSA_SUCCESS) {
 		access = (CSA_flags)get_access_ext.item_data;
  		if (check_support[0].flag & CSA_X_COM_SUPPORTED)
 			printf("The CSA_X_XT_APP_CONTEXT_EXT extension is supported¥n");
  		if (check_support[1].flag & CSA_X_COM_SUPPORTED)
 			printf("The CSA_X_UI_ID_EXT extension is supported¥n");
 	}
 }


カレンダ・セッションを終了するには


例 10-4 カレンダ・セッションを終了する

logoff() 
{
 	CSA_return_code		stat;

  	/* セッションが必要ない場合は、csa_logoff を呼び出すことにより終了できます。
 	 * 前の例で csa_logon により返されたセッションを終了します。
 	 */
 	stat = csa_logoff(cal, NULL); 
}


カレンダを削除するには


例 10-5 カレンダを削除する

delete_calendar() 
{
 	/* csa_logon() を呼び出すことによりカレンダ・セッションを確立後、
 	 * csa_delete_calender() を使用してカレンダを削除できます。
 	 */
 	CSA_return_code		stat;
  	stat = csa_delete_calendar(cal, NULL);
}


カレンダ・エントリを追加するには


例 10-6 カレンダ・エントリを追加する

#include <csa/csa.h>  

CSA_return_code		stat;
CSA_session_handle	cal;
CSA_attribute		attrs[9];
CSA_attribute_value	attr_val[9];
CSA_reminder		audio;
CSA_reminder		mail;
CSA_entry_handle	new_entry;
int			i;

i = 0;

/* 開始日の属性。この属性にはデフォルトがないため、必ず指定してください。
 * CSA_date_time 値は、ISO 8601 規格にある UTC ベースの日付と時間を指定します。
 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE;
 attrs[i].value = &attr_val[i];
 attrs[i].attribute_extensions = NULL;
 attr_val[i].type = CSA_VALUE_DATE_TIME;
 attr_val[i].item.date_time_value = iso8601time(time(NULL));
 i++;

/* 終了日の属性。
 * 指定しないと、エントリは終了日の属性を持ちません。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_END_DATE;
 attrs[i].value = &attr_val[i];
 attrs[i].attribute_extensions = NULL;
 attr_val[i].type = CSA_VALUE_DATE_TIME;
 attr_val[i].item.date_time_value = iso8601time(time(NULL) + 3600);
 i++;

/* 分類属性。
 * 指定しないと、デフォルト値は CSA_CLASS_PUBLIC になります。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_CLASSIFICATION;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_CLASS_CONFIDENTIAL;
i++;  

/* タイプ属性。
 * この属性にはデフォルトがないため、必ず指定してください。
 */
attrs[i].name = CSA_ENTRY_ATTR_TYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_TYPE_EVENT;
i++;

/* サブタイプ属性。
 * 指定しないと、デフォルト値は CSA_SUBTYPE_APPOINTMENT になります。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT; 
i++;  

/* サマリ属性 */
attrs[i].name = CSA_ENTRY_ATTR_SUMMARY; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = argv6; 
attrs[i].attribute_extensions = NULL; 
i++;

/* 反復規則属性。
 * 指定しないと、エントリは 1 回だけのエントリになります。反復規則 D1 #3 は、
 * エントリが毎日 3 日間繰り返されるよう指定します。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_RECURRENCE_RULE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = argv7; 
i++;

/* オーディオ通知属性。
 * 通知プログラムのリード・タイムは、ISO 8601 規格にある CSA_time_duration の値で
 * 指定します。
 * たとえば、5 分間のリード・タイムは、文字列 +PT300S と表します。
 * マイナス 5 分間のリード・タイムは、-PT300S と表します。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_AUDIO_REMINDER; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_REMINDER; 
attr_val[i].item.reminder_value = &audio; 
memset((void *)&audio, NULL, sizeof(audio)); 
audio.lead_time = "+PT300S"; i++;

/* メール通知属性。
 * 電子メール・アドレスは、reminder_data フィールドに指定します。
 * この通知プログラムのリード・タイムは 1 日。
 */ 
attrs[i].name = CSA_ENTRY_ATTR_MAIL_REMINDER; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_REMINDER; 
attr_val[i].item.reminder_value = &mail; 
memset((void *)&mail, NULL, sizeof(mail)); 
mail.lead_time = "+PT86400S"; 
mail.reminder_data.data = "someuser@somehost"; 
mail.reminder_data.size = strlen(mail.reminder_data.data); 
i++;

/* 指定した属性値でエントリを追加します */
stat = csa_add_entry(cal, i, attrs, &newentry, NULL);  
if (stat == CSA_SUCCESS)
 	csa_free((CSA_buffer)newentry);


カレンダのエントリを検索するには


例 10-7 カレンダのエントリを検索する/属性値を読み取る

#include <csa/csa.h>  

CSA_return_code		stat; 
CSA_session_handle	cal;
CSA_attribute		attrs[4]; 
CSA_attribute_value	attr_val[4]; 
CSA_enum		ops[4];
CSA_uint32		i; 
CSA_uint32		num_entries;
CSA_entry_handle	*entries;
CSA_uint32		num_attributes; 
CSA_attribute		*entry_attrs;  

/* 次の判断基準ですべてのエントリを検索します。
 * UTC 時間 1996 年 8 月のすべてのアポイント
 * 開始日は、UTC 時間 1996 年 8 月 1 日 00:00:00 以降
 * 開始日は、UTC 時間 1996 年 9 月 1 日 00:00:00 より前
 * タイプは CSA_TYPE_EVENT 
 * サブタイプは CSA_SUBTYPE_APPOINTMENT
 */  

i = 0;  

/* 開始日は、UTC 時間 1996 年 8 月 1 日 00:00:00 以降 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = "19960801T000000Z"; 
ops[i] = CSA_MATCH_GREATER_THAN_OR_EQUAL_TO; 
i++;

/* 開始日は、UTC 時間 1996 年 9 月 1 日 00:00:00 より前 */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_DATE_TIME; 
attr_val[i].item.date_time_value = "19960901T000000Z" 
ops[i] = CSA_MATCH_LESS_THAN; 
i++;  

/* タイプは CSA_TYPE_EVENT */ 
attrs[i].name = CSA_ENTRY_ATTR_TYPE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_UINT32; 
attr_val[i].item.sint32_value = CSA_TYPE_EVENT; 
ops[i] = CSA_MATCH_EQUAL_TO; 
i++;

/* サブタイプは CSA_SUBTYPE_APPOINTMENT */
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE; 
attrs[i].value = &attr_val[i]; 
attrs[i].attribute_extensions = NULL; 
attr_val[i].type = CSA_VALUE_STRING; 
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT; 
ops[i] = CSA_MATCH_EQUAL_TO; 
i++;

/* 検索の実行 */
stat = csa_list_entries(csa, i, attrs, ops, &num_entries, &entries, NULL);

  if (stat == CSA_SUCCESS) {
     for (i = 0; i < num_entries; i++) {
	/* エントリのすべての属性値を取得します。
	 * number_names に 0 を指定し、attribute_names に NULL を指定すると、
	 * すべての属性値が返されます。
 	 */ 	
   stat = csa_read_entry_attributes(cal, entries[i], 0, NULL,
 					 &num_attributes, &entry_attrs,
 					 NULL); 	if (stat == CSA_SUCCESS) {
	    /* 返された属性値を使用し、終了時にメモリを解放します
 	     */
 	    csa_free(entry_attrs);
 	} else {
	    /* ハンドル・エラー */
 	}
     }
 } else {
     /* ハンドル・エラー */
}   

Example: Change the end time of the returned appointments to be
 	 one hour later.

CSA_attribute_reference	name = CSA_ENTRY_ATTR_END_DATE; 
char			buffer[80]; 
time_t			endtime; 
CSA_entry_handle	new_entry;

for (i = 0; i < num_entries; i++) {
     /* アポイントの終了時間を取得します */
     stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
 				    &num_attributes, &entry_attrs, NULL);
     if (stat == CSA_SUCCESS) {
	/* 終了時間を 1 時間後に変更します */
 	from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
 	endtime += 60*60 /* 1 時間の秒数 */
 	to_iso8601_time(endtime, buffer);
    attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
    attrs[0].value = &attr_val[i];
    attrs[0].attribute_extensions = NULL;	
    attr_val[0].type = CSA_VALUE_DATE_TIME;
 	attr_val[0].item.date_time_value = buffer;
  	stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
 			      	CSA_FALSE, 1, attrs, &new_entry,
 					   NULL);
 	if (stat == CSA_SUCCESS) {
 	    csa_free(new_entry);
 	} else {
 	    /* ハンドル・エラー */
 	}
  	csa_free(entry_attrs);
      } else {
 	    /* ハンドル・エラー */
     } 
}


カレンダのエントリを更新するには


例 10-8 返されたアポイントの終了時間を 1 時間後に変更する

CSA_attribute_reference	name = CSA_ENTRY_ATTR_END_DATE; 
char			buffer[80]; 
time_t			endtime; 
CSA_entry_handle	new_entry;  

for (i = 0; i < num_entries; i++) {
     /* アポイントの終了時間を取得します */
     stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
 				     &num_attributes, &entry_attrs, NULL);
     if (stat == CSA_SUCCESS) {
	/* 終了時間を 1 時間後に変更します */
 	from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
 	endtime += 60*60 /* 1 時間の秒数 */
 	to_iso8601_time(endtime, buffer);

  	attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
 	attrs[0].value = &attr_val[i];
 	attrs[0].attribute_extensions = NULL;
 	attr_val[0].type = CSA_VALUE_DATE_TIME;
 	attr_val[0].item.date_time_value = buffer;
  	stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
 					   CSA_FALSE, 1, attrs, &new_entry,
 					   NULL); 	if (stat == CSA_SUCCESS) {
 	    csa_free(new_entry);
 	} else {
 	    /* ハンドル・エラー */
 	}
  	csa_free(entry_attrs);
      } else {
 	    /* ハンドル・エラー */
    }
}


コールバックを登録し、通知プログラムを保持するには


例 10-9 コールバックを登録し、通知プログラムを保持する

/* このコーディング例では、csa_register_callback、csa_read_next_reminder、
  * および csa_call_callbacks の使用方法について示します。
  * 基本となるコードでは、イベント CSA_CB_ENTRY_ADDED、CSA_CB_ENTRY_DELETED、
  * および CSA_CB_ENTRY_UPDATED 用のコールバック・ルーチンを登録します。
  * また、別のコールバック・ルーチンを、CSA_CB_CALENDAR_ATTRIBUTE_UPDATE 
  * イベント用に登録します。
  * 通知デリバリ用のタイマを設定する方法も示します。
  * ISO 8601 書式の時間表記を UTC 1970 年 1 月 1 日 00:00:00 からの経過秒数を示す
  * ティック数への変換用の 2 つのユーティリティ・ルーチンも含みます。
  */ 

#include <csa/csa.h> 
#include <time.h> 
#include <unistd.h>  

CSA_session_handle	cal;	 /* カレンダ・セッション */
time_t			run_time; /* 通知プログラムを実行する時間 */ 
CSA_uint32		num_rems; /* 返される通知数 */
CSA_reminder_reference	*rems;	  /* 通知情報の配列 */

void 
set_up_callback_handler() 
{
 	CSA_return_code		stat;
 	CSA_flags		flags;

	/* Xt ベースのアプリケーションは、コールバック・ルーチンが非同期に呼び出せるように
	 * するため、CSA_X_XT_APP_CONTEXT_EXT 拡張を使用して、
	 * Xt アプリケーションのコンテキストを指定できます。
  *
  *	CSA_extension callback_ext;
  *	callback_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
  * 	callback_ext.item_data = (CSA_uint32)application_context;
  *	callback_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
  *
  * callback_ext を最後のパラメータとして、csa_register_callback に渡す。
  */

  	flags = CSA_CB_ENTRY_ADDED|CSA_CB_ENTRY_DELETED|CSA_CB_ENTRY_UPDATED;
 	stat = csa_register_callback(cal, flags, entry_update_callback,
 		NULL, NULL);

  	if (stat != CSA_SUCCESS) {
		/* エラー処理コード */
 	}

  	stat = csa_register_callback(cal, CSA_CB_CALENDAR_ATTRIBUTE_UPDATED,
 		calendar_update_callback, NULL, NULL);
  	if (stat != CSA_SUCCESS) {
		/* エラー処理コード */
 	} 
}  

/*  * このルーチンはライブラリをポーリングし、特定のイベントが発生していた場合に、
 * 登録されているコールバックを呼び出します。
 * アプリケーションが CSA_X_XT_APP_CONTEXT_EXT 拡張を使用してコールバックの
 * 呼び出しを非同期に設定していない場合、csa_call_callbacks を呼び出して、
 * コールバックの呼び出しを強制する必要があります。
 */ 

check_events(CSA_flags event)
{
 	csa_call_callbacks(cal, event, NULL); 
}

  /*
  * これは、イベント CSA_CB_ENTRY_ADDED、CSA_CB_ENTRY_ADDED、および 
  * CSA_CB_ENTRY_UPDATED のためのコールバック・ルーチンです。
  */ 
void 
entry_update_callback(
 	CSA_session_handle	cal,
 	CSA_flags		flags,
 	CSA_buffer		call_data,
 	CSA_buffer		client_data,
 	CSA_extension		*ext) 
{
	/* エントリが追加、削除、または更新されます。
	 * このコールバック・ルーチンで行う可能性があるのは次のとおりです。
	 *
	 * 1. カレンダ表示の更新
	 * 2. ユーザ自身のカレンダの場合は、通知情報の更新
	 *
	 * このルーチンのコーディング例は通知情報を更新します。
 	 */ 	reset_reminder();
}
 /*
 * これは CSA_CB_CALENDAR_ATTRIBUTE_UPDATED イベントのための
 * コールバック・ルーチンです。
 */ 
void 
calendar_update_callback(
 	CSA_session_handle	cal,
 	CSA_flags		flags,
 	CSA_buffer		call_data,
 	CSA_buffer		client_data,
 	CSA_extension		*ext) 
{
 	/* カレンダ属性を更新する */
}

   /*
  * このルーチンは通知情報を更新します。
  *	 - 既存の情報がある場合は削除する
  *	 - csa_read_next_reminder() を呼び出して、次に転送する通知を取得する
  *	 - 実行時間をチェックし、タイマーを設定する
  */ 
void 
reset_reminder() {
 	CSA_return_code		stat;
 	time_t			current_time;
 	char			isotime[BUFSIZ];
 	CSA_uint32		number_reminders;
 	CSA_reminder_reference	*reminders;

  	current_time = time(NULL);

	/* 既存の情報を削除する */
 	if (rems) {
		/* この比較の目的は、最後に実行された時刻から、現在の時刻までの間に実行された
		 * 通知が失われていないかを確認することです。
 		 */
 		if (current_time > run_time)
 			current_time = run_time;

  		csa_free((CSA_buffer)rems);
 	}

  	to_iso8601_time(current_time, isotime);
 	stat = csa_read_next_reminder(cal, 0, NULL, isotime,
 		&number_reminders, &reminders, NULL);

  	if (stat == CSA_SUCCESS && num_rems > 0) {
 		num_rems = number_reminders;
 		rems = reminders;

		/* タイマーを設定し、通知を転送する。
		 * sigset() を使用して、SIGALRM シグナルのためのシグナル処理を設定します。
 		 */
 		from_iso8601_time(reminders[0].run_time, &run_time);
 		remain = run_time - time(NULL);
 		alarm((remain > 0) ? remain : 1);

		/* Xt ベースのアプリケーションは、XtAppAddTimeOut を使用して
		 * タイマーを設定できます。
 		 */
 	}
}

/*
  * このルーチンは、ISO 8601 書式の時間表記を、UTC 1970 年 1 月 1 日 00:00:00 
  * からの経過秒数を示すティック数へ変換します。
  * このティックはローカル時間に調整されます。
  */ int from_iso8601_time(char *buf, time_t *tick_out) 
{
 	int		year, month, day, hour, min, sec;
 	struct tm	time_str;

  	sscanf(buf, "%4d%2d%2dT%2d%2d%2dZ",
 	    &year, &month, &day, &hour, &min, &sec);

  	time_str.tm_year	= year - 1900;
 	time_str.tm_mon		= month - 1;
 	time_str.tm_mday	= day;
 	time_str.tm_hour	= hour;
 	time_str.tm_min		= min;
 	time_str.tm_sec		= sec;
 	time_str.tm_isdst	= -1;
  	*tick_out = mktime(&time_str);

  	if (*tick_out != (long)-1) {

		/* ローカル・タイムゾーンに調整 */
 		if (time_str.tm_isdst == 0)
 			*tick_out -= timezone;
 		else
 			*tick_out -= altzone;
  		return(0);
 	} else
 		return(-1); 
}  

/*
  * このルーチンは、UTC 1970 年 1 月 1 日 00:00:00 からの経過秒数を示すティック数を、
  * ISO 8601 書式の時間表記へ変換します。
  */ 
int 
to_iso8601_time(time_t tick, char *buf_out) 
{
 	struct tm	time_str;
  	if (gmtime_r(&tick, &time_str)) {

		/* 書式文字列が固定幅 (ゼロで埋め込み) フィールドを強制する。 */
 		sprintf(buf_out, "%04d%02d%02dT%02d%02d%02dZ",
 			time_str.tm_year + 1900,
 			time_str.tm_mon + 1,
 			time_str.tm_mday,
 			time_str.tm_hour,
 			time_str.tm_min,
 			time_str.tm_sec);
  		return (0);
 	} else {
 		return (-1);
 	} 
}