<!-- $XConsortium: ch08.sgm /main/9 1996/10/30 15:30:28 rws $ -->
<!-- (c) Copyright 1995 Digital Equipment Corporation. -->
<!-- (c) Copyright 1995 Hewlett-Packard Company. -->
<!-- (c) Copyright 1995 International Business Machines Corp. -->
<!-- (c) Copyright 1995 Sun Microsystems, Inc. -->
<!-- (c) Copyright 1995 Novell, Inc. -->
<!-- (c) Copyright 1995 FUJITSU LIMITED. -->
<!-- (c) Copyright 1995 Hitachi. -->
<Chapter Id="PG.aIII.div.1">
<Title Id="PG.aIII.mkr.1">Invoking Actions from Applications</Title>
<Para Id="PG.aIII.mkr.2">If your application manages an extensible collection of data types, there is a
strong likelihood that it should be directly involved with action invocation.
This chapter explains how you can invoke an action from an application.
Included is an example program that shows you how to invoke an action.</Para>
<Para>For more information on<IndexTerm>
<Primary>actions</Primary>
</IndexTerm><IndexTerm>
<Primary>actions</Primary>
<Secondary>invoking from an application</Secondary>
</IndexTerm>
actions and how you create them, see
<!--Original XRef content: 'Chapter&numsp;9,
&xd2;Accessing the Data-Typing Database'--><XRef Role="ChapNumAndTitle" Linkend="PG.datat.mkr.1">, in this manual, and the following
chapters in the <Emphasis>Advanced User's and System Administrator's Guide</Emphasis>:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para>&ldquo;Introduction to Actions and Data Types&rdquo;</Para>
</ListItem>
<ListItem>
<Para>&ldquo;Creating Actions and Data Types Using Create Action&rdquo;</Para>
</ListItem>
<ListItem>
<Para>&ldquo;Creating Actions Manually&rdquo;</Para>
</ListItem>
<ListItem>
<Para>&ldquo;Creating Data Types Manually&rdquo;</Para>
<InformalTable Id="PG.aIII.itbl.1" Frame="All">
<TGroup Cols="1">
<ColSpec Colname="1" Colwidth="4.0 in">
<TBody>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'Mechanisms for Invoking Actions from an Application110'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.3"></Para></Entry>
</Row>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'Types of Actions111'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.4"></Para></Entry>
</Row>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'Action Invocation API112'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.5"></Para></Entry>
</Row>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'Related Information112'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.6"></Para></Entry>
</Row>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'actions.c Example Program113'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.7"></Para></Entry>
</Row>
<Row Rowsep="1">
<Entry><Para><!--Original XRef content: 'Listing for actions.c118'--><XRef Role="JumpText" Linkend="PG.aIII.mkr.18"></Para></Entry>
</Row>
</TBody>
</TGroup>
</InformalTable>
</ListItem>
</ItemizedList>
<Sect1 Id="PG.aIII.div.2">
<Title Id="PG.aIII.mkr.3">Mechanisms for Invoking Actions from an Application</Title>
<Para>The action invocation API exported by the Desktop Services library is one
mechanism available to your application to cause another application to be
invoked or to perform an operation. Other mechanisms include:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para>The <Filename>fork/exec</Filename> system calls</Para>
</ListItem>
<ListItem>
<Para>ToolTalk messages</Para>
</ListItem>
</ItemizedList>
<Para>Each of these mechanisms has benefits and limitations, so you must evaluate
your specific situation to determine which is most appropriate.</Para>
<Para><IndexTerm>
<Primary>actions</Primary>
<Secondary>advantages of</Secondary>
</IndexTerm>The advantages of using the action invocation API include:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para>Actions can encapsulate both traditional command-line applications (that is,
<Command>COMMAND</Command> actions) and ToolTalk applications (that is, <Filename>TT_MSG</Filename> actions). The
application that invokes the action does not need to know whether a
command is forked or a message is sent.</Para>
</ListItem>
<ListItem>
<Para>Actions are polymorphic and are integrated with the desktop's data-typing
mechanisms. This means that an action, such as Open or Print, may have
different behavior depending on the type of argument that is supplied, but
the behavior differences are transparent to the application that invokes the
action.</Para>
</ListItem>
<ListItem>
<Para>Actions provide a great deal of configurability for the application developer,
system integrator, system administrator, and end user. Any one of these
people can edit the action database to modify the definition of how an
action is to be performed.</Para>
</ListItem>
<ListItem>
<Para>Actions work well in distributed environments. If an application uses
<Filename>fork/exec</Filename> to directly invoke another application, then both applications
must be available and able to run on the same system. By contrast, the
action invocation API uses information in the action database to determine
on which system a <Command>COMMAND</Command> action should be invoked.</Para>
</ListItem>
<ListItem>
<Para>Actions enable your application to behave consistently with the behavior of
the desktop. This is because the desktop's components interact by using
actions when manipulating the user's data files.</Para>
</ListItem>
</ItemizedList>
<Para>The disadvantage of using the action invocation API is that it is only an
invocation mechanism that has limited return value capabilities and has no
capabilities for a dialog with the invoked action handler. If these features are
required, <Command>fork/exec/pipes</Command> can be used. However, within CDE, ToolTalk is
the preferred cross process communications mechanism due to its generalized
client/server paradigm.</Para>
<Para>Returning to invocation, suppose your application manages data files in
several different formats (text and graphics) and needs to provide a way for
the user to edit and display these files. To implement this feature without using
actions, you would probably use one of the following mechanisms:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para>Use <Filename><IndexTerm>
<Primary>fork/exec</Primary>
</IndexTerm>fork/exec</Filename> to start the appropriate editor and invent some mechanism
(for example, environment variables) for the user to specify the names of the
editors. The limitations of this approach include the following:</Para>
<ItemizedList Remap="Bullet2">
<ListItem>
<Para>You must write complex code that uses system calls to invoke
subprocesses and monitors the resulting signals.</Para>
</ListItem>
<ListItem>
<Para>The editors must either be available on the same system as your
application or the system administrator must provide a complex
configuration using facilities such as <Command>rsh</Command>.</Para>
</ListItem>
<ListItem>
<Para>System administrators and users must learn and manage your
application's unique configuration model.</Para>
</ListItem>
</ItemizedList>
</ListItem>
<ListItem>
<Para>Use<IndexTerm>
<Primary>ToolTalk</Primary>
</IndexTerm>
ToolTalk messages to request that operations, such as Edit and Display,
be performed on the data. The limitation of this approach is that ToolTalk-
based editors must be available for all of your types of data.</Para>
</ListItem>
</ItemizedList>
<Para>To implement this feature using actions, you only have to invoke the Open
action on the buffer or on the data file. The action invocation API will use the
action database to determine the appropriate message to send or command to
invoke as well as handle all details, such as creating and cleaning up
temporary files and catching necessary signals.</Para>
</Sect1>
<Sect1 Id="PG.aIII.div.3">
<Title Id="PG.aIII.mkr.4"><IndexTerm>
<Primary>actions</Primary>
<Secondary>types</Secondary>
</IndexTerm><IndexTerm>
<Primary>2</Primary>
</IndexTerm><IndexTerm>
<Primary>2</Primary>
</IndexTerm><IndexTerm>
<Primary>actions</Primary>
<Secondary>types</Secondary>
</IndexTerm>Types of Actions</Title>
<Para>The action application program interface (API) works with any type of action.
Types of actions in the desktop include:</Para>
<InformalTable>
<TGroup Cols="2">
<TBody>
<Row>
<Entry><Para>Command actions</Para></Entry>
</Row>
<Row>
<Entry><Para>Specifies a command line to execute.</Para></Entry>
</Row>
<Row>
<Entry><Para>ToolTalk actions</Para></Entry>
</Row>
<Row>
<Entry><Para>Specifies a ToolTalk message to send, which is then
received by the appropriate application.</Para></Entry>
</Row>
<Row>
<Entry><Para>Map actions</Para></Entry>
</Row>
<Row>
<Entry><Para>Refers to another action instead of defining any specific
behavior.</Para></Entry>
</Row>
</TBody>
</TGroup>
</InformalTable>
<Para>See &ldquo;Introduction to Actions and Data Types&rdquo; in the <Emphasis>Common Desktop
Environment: Advanced Users' and System Administrator's Guide</Emphasis> for more
information.</Para>
</Sect1>
<Sect1 Id="PG.aIII.div.4">
<Title Id="PG.aIII.mkr.5"><IndexTerm>
<Primary>action invocation library</Primary>
</IndexTerm>Action Invocation API</Title>
<Para>The action invocation API is exported from the Desktop Services library and
provides functions to accomplish a number of tasks, such as:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para>Initializing and loading the database of action and data-type definitions.
The database <Emphasis>must</Emphasis> be loaded before an action can be run.</Para>
</ListItem>
<ListItem>
<Para>Querying the database. There are functions to determine whether a specified
action or its associated icon image, label, or description exists.</Para>
</ListItem>
<ListItem>
<Para>Invoking an action. The application can pass file or buffer arguments to the
action.</Para>
</ListItem>
<ListItem>
<Para>Registering a callback to receive action status and return arguments.</Para>
</ListItem>
</ItemizedList>
</Sect1>
<Sect1 Id="PG.aIII.div.5">
<Title Id="PG.aIII.mkr.6">Related Information</Title>
<Para>For detailed information about action commands, functions, and data formats,
see the following man pages:</Para>
<ItemizedList Remap="Bullet1">
<ListItem>
<Para><Filename>dtaction</Filename>(1)</Para>
</ListItem>
<ListItem>
<Para><Filename>dtactionfile(4)</Filename></Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionCallbackProc</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionDescription</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionExists</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionIcon</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionInvoke</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionLabel</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionQuit</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionQuitType</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>DtActionStUpCb</Filename>(3)</Para>
</ListItem>
<ListItem>
<Para><Filename>dtexec</Filename>(1)</Para>
</ListItem>
</ItemizedList>
</Sect1>
<Sect1 Id="PG.aIII.div.6">
<Title Id="PG.aIII.mkr.7"><IndexTerm>
<Primary>actions</Primary>
<Secondary>example program</Secondary>
</IndexTerm><IndexTerm>
<Primary>actions</Primary>
<Secondary>example program</Secondary>
</IndexTerm>actions.c Example Program</Title>
<Para>This section describes a simple example program, <Filename>actions.c</Filename>. A complete
listing of <Filename>actions.c</Filename> is at the end of this chapter.</Para>
<Sect2 Id="PG.aIII.div.7">
<Title>Loading the Database of Actions and Data Types</Title>
<Para>Before your application can invoke an action, it <Emphasis>must</Emphasis> initialize the Desktop
Services library (which contains the action invocation API) and load the
database of action and data-type definitions.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.8" Role="Procedure">
<Title>To Initialize the Desktop Services Library</Title>
<OrderedList>
<ListItem>
<Para>Use the <Filename><IndexTerm>
<Primary>DtInitialize</Primary>
</IndexTerm>DtInitialize()</Filename> function to initialize the Desktop Services
Library.</Para>
<programlisting>DtInitialize(*<Symbol Role="Variable">display</Symbol>,<Symbol Role="Variable">widget</Symbol>,*<Symbol Role="Variable">name</Symbol>,*<Symbol Role="Variable">tool_class</Symbol>)</programlisting>
<Para><Filename>DtInitialize()</Filename> uses the default Intrinsic <Command>XtAppContext</Command>. The API
provides an additional function, <Filename><IndexTerm>
<Primary>DtAppInitialize</Primary>
</IndexTerm>DtAppInitialize()</Filename> to use when your
application must specify an <Symbol Role="Variable">app_context</Symbol>:</Para>
<programlisting>DtAppInitialize(<Symbol Role="Variable">app_context</Symbol>,*<Symbol Role="Variable">display</Symbol>,<Symbol Role="Variable">widget</Symbol>,*<Symbol Role="Variable">name</Symbol>, <Symbol Role="Variable">tool_class</Symbol>)</programlisting>
</ListItem>
</OrderedList>
<Sect3 Id="PG.aIII.div.9">
<Title>DtInitialize() Example</Title>
<Para>The following code segment shows how the example program <Filename>actions.c</Filename>
uses <Filename>DtInitialize()</Filename>.</Para>
<ProgramListing>if (DtInitialize(XtDisplay(shell), shell, argv[0],ApplicationClass)==False) {
    /* DtInitialize() has already logged an appropriate error msg */
    exit(1);
}</ProgramListing>
</Sect3>
</Sect2>
<Sect2 Id="PG.aIII.div.10" Role="Procedure">
<Title>To Load the Actions and Data-Typing Database</Title>
<OrderedList>
<ListItem>
<Para>Use the <Filename><IndexTerm>
<Primary>DtDbLoad</Primary>
</IndexTerm>DtDbLoad()</Filename> function to load the actions and data-typing database.</Para>
<programlisting>DtDbLoad(void)</programlisting>
<Para><Filename>DtDbLoad()</Filename> reads in the action and data-typing database. This function
determines the set of directories that are to be searched for database files (the
database search path) and loads the <Filename>*.dt</Filename> files found into the database. The
directory search path is based on the value of the <Command>DTDATABASESEARCHPATH</Command>
environment variable and internal defaults.</Para>
</ListItem>
</OrderedList>
</Sect2>
<Sect2 Id="PG.aIII.div.11" Role="Procedure">
<Title Id="PG.aIII.mkr.8">To Request Notification of Reload Events</Title>
<Para>If you use DtDbLoad() in a long-lived application, it must dynamically reload
the database whenever it is modified.</Para>
<OrderedList>
<ListItem>
<Para>Use the <Command><IndexTerm>
<Primary>DtDbReloadNotify</Primary>
</IndexTerm>DtDbReloadNotify()</Command>function to request notification of reload
events.</Para>
</ListItem>
</OrderedList>
<ProgramListing>/* Notice changes to the database without needing to restart

  application */

 DtDbReloadNotify(DbReloadCallbackProc, callback_proc,

  XTPointer, client_data);
</ProgramListing>
<OrderedList>
<ListItem>
<Para>Supply a callback that:</Para>
<ItemizedList Remap="Bullet2">
<ListItem>
<Para>Destroys cached database information held by the application</Para>
</ListItem>
<ListItem>
<Para>Calls the <Filename>DtDbLoad()</Filename> function again</Para>
</ListItem>
</ItemizedList>
</ListItem>
</OrderedList>
<Para><Emphasis>C</Emphasis><Symbol Role="Variable">allback_proc</Symbol> cleans up any cached database information your application is
holding and then invokes <Filename>DtDbLoad()</Filename>. <Emphasis>Client_data</Emphasis> may be used to pass
additional client information to the callback routine.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.12">
<Title Id="PG.aIII.mkr.9">Checking the Actions Database</Title>
<ProgramListing>Your application accesses the database if it needs to display the icon or label for
an action. Also before invoking an action, your application can check that it
exists. An action is identified in the database by the action name:
ACTION <Symbol Role="Variable">action_name</symbol>
{

  &hellip;

}</ProgramListing>
<Para>For example, the action definition for the Calculator looks like this:</Para>
<ProgramListing>ACTION Dtcalc

{

        LABEL    Calculator

        ICON      Dtcalc

        ARG_COUNT      0

        TYPE            COMMAND

        WINDOW_TYPE      NO_STDIO

        EXEC_STRING      /usr/dt/bin/dtcalc

        DESCRIPTION      The Calculator (Dtcalc) action runs the \

                        desktop Calculator application.

}</ProgramListing>
<Para>The action name for the Calculator action is Dtcalc.</Para>
<Para>When an executable file has a file name that matches an action name in the
existing database, that file is an action file&mdash;a representation for the underlying
action. The information about the icon and label for that file are stored in the
database.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.13" Role="Procedure">
<Title>To Determine Whether a Specified Action Definition Exists</Title>
<OrderedList>
<ListItem>
<Para>Use the <Filename><IndexTerm>
<Primary>DtActionExists</Primary>
</IndexTerm><IndexTerm>
<Primary>actions</Primary>
<Secondary>icon image for</Secondary>
</IndexTerm>DtActionExists()</Filename> function to determine whether a specified
action definition exists.</Para>
<programlisting>DtActionExists(*<Symbol Role="Variable">name</Symbol>)</programlisting>
<Para><Filename>DtActionExists()</Filename> checks whether the specified <Symbol Role="Variable">name</Symbol> corresponds to the
name of an action in the database. The function returns True if <Symbol Role="Variable">name</Symbol>
corresponds to an action name, or False if no action with that name is found.</Para>
</ListItem>
</OrderedList>
</Sect2>
<Sect2 Id="PG.aIII.div.14" Role="Procedure">
<Title Id="PG.aIII.mkr.10">To Obtain the Icon Image Information for a Specified Action</Title>
<OrderedList>
<ListItem>
<Para>Use the <Filename Id="PG.aIII.mkr.11">DtActionIcon()</Filename> function to obtain the icon image information.</Para>
<programlisting>DtActionIcon(char *<Symbol Role="Variable">action_name</Symbol>)</programlisting>
</ListItem>
</OrderedList>
<Para>An action definition specifies the icon image used to represent the action in the
definition's ICON field:</Para>
<ProgramListing>ACTION <Symbol Role="Variable">action_name</Symbol>
{

   ICON  <Symbol Role="Variable">icon_image_base_name</symbol>
   &hellip;

}</ProgramListing>
<Para><Filename>DtActionIcon()</Filename> returns a character string containing the value of the icon
image field. If the action definition does not contain an icon field, the function
returns the value of the default action icon image, <Command>Dtactn</Command>.</Para>
<Para>You then need to determine the location of the icon, and the size you want to
use. Icons can exist in four sizes and are available in bitmap or pixmap form.
For example, you can find the base name of the icon file from the action
definition for the Calculator. You then use the base name coupled with the
information given in
<!--Original XRef content: 'Table&numsp;8&hyphen;1'--><XRef Role="CodeOrFigureOrTable" Linkend="PG.aIII.mkr.13"> and knowledge of the location of all the icons to
find the specific icon file you want.</Para>
<Para Id="PG.aIII.mkr.12">The icon name for the calculator action is <Command>Dtcalc</Command>, but that is not the entire file
name. Icon file names are based on the size of the icon.
<!--Original XRef content: 'Table&numsp;8&hyphen;1'--><XRef Role="CodeOrFigureOrTable" Linkend="PG.aIII.mkr.13"> shows the
sizes and file-naming conventions for the desktop icons.</Para>
<Table Id="PG.aIII.tbl.1" Frame="Topbot">
<Title Id="PG.aIII.mkr.13">Icon Sizes and File Names</Title>
<TGroup Cols="3">
<ColSpec Colname="1" Colwidth="1.25 in">
<ColSpec Colname="2" Colwidth="1.25 in">
<ColSpec Colname="3" Colwidth="1.375 in">
<THead>
<Row>
<Entry><Para><Literal>Icon Size</Literal></Para></Entry>
<Entry><Para><Literal>Bitmap Name</Literal></Para></Entry>
<Entry><Para><Literal>Pixmap Name</Literal></Para></Entry>
</Row>
</THead>
<TBody>
<Row>
<Entry><Para>16 by 16 (tiny)</Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.t.bm</Filename></Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.t.pm</Filename></Para></Entry>
</Row>
<Row>
<Entry><Para>24 by 24 (small)</Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.s.bm</Filename></Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.s.pm</Filename></Para></Entry>
</Row>
<Row>
<Entry><Para>32 by 32 (medium)</Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.m.bm</Filename></Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.m.pm</Filename></Para></Entry>
</Row>
<Row>
<Entry><Para>48 by 48 (large)</Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.l.bm</Filename></Para></Entry>
<Entry><Para><Symbol Role="Variable">name</Symbol><Filename>.l.pm</Filename></Para></Entry>
</Row>
</TBody>
</TGroup>
</Table>
<Note>
<Para>See &ldquo;Creating Icons for the Desktop&rdquo; in the <Emphasis>Advanced User's &amp; System
Administrator's Guide</Emphasis> for more information about the desktop icon files.</Para>
</Note>
<Para>For bitmaps, there is an additional file that is used as a mask, and its extension
ends with <Filename>_m.bm</Filename>. Thus, there can be a total of three files for each size icon.
Here are the icon files for the calculator:</Para>
<ProgramListing>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</ProgramListing>
<Note>
<Para>There are no small icons (<Filename>Dtcalc.s.bm</Filename>, <Filename>Dtcalc.s.pm</Filename>,
<Filename>Dtcalc.s_m.bm</Filename>) for the Calculator.</Para>
</Note>
<Para><Filename Id="PG.aIII.mkr.14">DtActionIcon()</Filename> returns only a base name; for the Calculator it is <Command>Dtcalc</Command>.
You must choose the type (pixmap or bitmap) and size (tiny, small, medium, or
large) and append the applicable extension to the base name. In addition, you
must know where the file resides.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.15" Role="Procedure">
<Title>To Get the Localized Label for an Action</Title>
<OrderedList>
<ListItem>
<Para>Use the<Command Id="PG.aIII.mkr.15"> DtActionLabel()</Command> function to get the localized label for an action.</Para>
<programlisting>char *DtActionLabel(char *<Symbol Role="Variable">actionName</Symbol>)</programlisting>
</ListItem>
</OrderedList>
<Para>An action definition may include a label. The label is defined using the
<Emphasis>label_text</Emphasis> field:</Para>
<ProgramListing>ACTION <Symbol Role="Variable">action_name</symbol>
{

   LABEL <Symbol Role="Variable">label_text</symbol>
   &hellip;

}</ProgramListing>
<Para>This label is used in graphical components (such as File Manager and the
Application Manager) to label the action's icon. If an action definition does not
include a <Emphasis>label_text</Emphasis> field, the <Symbol Role="Variable">action_name</Symbol> is used.</Para>
<Para>The value of <Emphasis>label_text</Emphasis> string should be used by all interface components to
identify the action to the end user.</Para>
<Para>The <Filename>DtActionLabel()</Filename> function returns the value of the <Emphasis>label_text</Emphasis> field in the
action definition of the action named <Symbol Role="Variable">actionName</Symbol>. If the <Emphasis>label_text</Emphasis> field does not
exist, the function returns the <Symbol Role="Variable">actionName</Symbol>.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.16">
<Title Id="PG.aIII.mkr.16">Invoking Actions</Title>
<Para>After your application has initialized the Desktop Services Library it can then
invoke an action.</Para>
</Sect2>
<Sect2 Id="PG.aIII.div.17" Role="Procedure">
<Title>To Invoke an Action</Title>
<OrderedList>
<ListItem>
<Para>Use the<Command Id="PG.aIII.mkr.17"> DtActionInvoke</Command> function to invoke an action.</Para>
<programlisting>DtActionInvokeID (<Symbol Role="Variable">widget</Symbol>, <Symbol Role="Variable">action</Symbol>, <Symbol Role="Variable">args</Symbol>, <Symbol Role="Variable">argCount</Symbol>, <Symbol Role="Variable">termOpts, execHost,</Symbol>
                       <Symbol Role="Variable">contexDir</Symbol>, <Symbol Role="Variable">useIndicator</Symbol>, <Symbol Role="Variable">statusUpdateCb</Symbol>, <Symbol Role="Variable">client_data</Symbol>)</programlisting>
</ListItem>
</OrderedList>
<Para><Filename>DtActionInvoke()</Filename> searches the action database for an entry that matches the
specified action name, and accepts arguments of the class, type, and count
provided. Remember that your application must initialize and load the database
before invoking an action.</Para>
</Sect2>
</Sect1>
<Sect1 Id="PG.aIII.div.18">
<Title Id="PG.aIII.mkr.18">Listing for actions.c</Title>
<ProgramListing>/*
 * (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 &lt;Xm/XmAll.h>
#include &lt;Dt/Dt.h>
#include &lt;Dt/Action.h>

#define ApplicationClass &ldquo;Dtaction&ldquo;

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(&amp;appContext, ApplicationClass, NULL, 0,

        &amp;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(&ldquo;Invoke&ldquo;);

    n = 0;
    XtSetArg(args[n], XmNdialogType, XmDIALOG_TEMPLATE); n++;
    XtSetArg(args[n], XmNokLabelString, labelString); n++;
    messageBox = XmCreateMessageBox(shell, &ldquo;messageBox&ldquo;, 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, &ldquo;workArea&ldquo;, args, n);
    XtManageChild(workArea);

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

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

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

    n = 0;
    XtSetArg(args[n], XmNcolumns, 12); n++;
    fileText = XmCreateTextField(workArea, &ldquo;fileText&ldquo;, 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, &ldquo;&ldquo;);
    XmTextFieldSetString(fileText, &ldquo;&ldquo;);

    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(&ldquo;&percnt;s(&percnt;s)\n&ldquo;,action,file);
    if (file != NULL &amp;&amp; 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);
}
</ProgramListing>
</Sect1>
</Chapter>
<!--fickle 1.14 mif-to-docbook 1.7 01/02/96 09:54:57-->
