Help Api for OpenServer
© 1992 The Santa Cruz Operation, Inc.

Introduction

Synopsis

This document describes the context-sensitive help functionality that is available for X clients in Everest. It provides some general background information, details about using help and the help api, and information about authoring help files. It is designed for both client developers and authors responsible for writing online help (although it does assume some level of knowledge about Motif/X).

This document does not cover adding help to vtcl applications, although the same document architecture applies.

Revision History

30 June 95
Created this document from Help Api Functional Specification for Everest

General Information

Graphical help is currently implemented as a separate client process, scohelp, which acts as a help server for a particular display. Scohelp is based on Mosaic, a general-purpose networked browser written by the National Center for Supercomputing Applications (NCSA). The following sections provide the general background information necessary to understand the api described in this document.

Summary of Terms

Following is a summary of some the most common terminology used throughout this document:
help server
General term for the client responsible for displaying help on a particular display, in this case scohelp. In the current implementation there is only one help server per display, per machine.

This should not be confused with the http server which is responsible for sending HTML documents to the scohelp (or mosaic) clients. The http server will be documented as part of the scohelp functional specification.

browser
Synonymous with help server in the context of this document.

viewer
Synonymous with help server in the context of this document.

client
Refers to any Motif/X application.

help api
A programmatic interface that enables a developer to add help to X/Motif applications.

hard-coded topic
A literal string representing the name of a topic within a help book.

topic name
Synonymous with hard-coded topic name.

hook file
A simple text file that provides a mechanism for mapping hard-coded topic names to actual topics.

help request
The request sent from the client to the help server indicating which help topic and book to display. The request is sent as a result of the user requesting help within an application (eg., via the Help menu).

help book
The online documentation unit that contains all the help information about a particular client or set of clients. In scohelp a help book is actually the name of a directory that contains all of the help topics contained within a particular book (eg., XDeskHelp).

help topic
A help topic is the unit of documentation displayed when a user requests help. In scohelp, the help topic is typically a single physical file that resides within the help book directory.

help window
A scohelp window, or document viewing area, that is associated with a particular client.

docServer
A SCOhelp resource used by the help viewer that specifies the location of help books. By default the documentation resides on the local machine (in /usr/lib/scohelp).

Help Requests

Since context-sensitive help is provided via a separate server process, when this document refers to the "help api" it is really referring to the set of routines that enable an X client to communicate with the help server. When a user requests help in a client, the help api is responsible for communicating this request to the server. Note that the descriptions provided here are meant to provide a basic understanding of the concepts, not a detailed technical explanation. Implementation and usage details are provided in later sections.

Using Hard-coded Topic Names

Most help systems only support the use of hard-coded, or literal, topic names. A hard-coded topic name is essentially just a string, or tag, that is associated with part of an application (such as a window or widget). This tag represents the name of a valid topic in a help book. When a user requests help from within a client this tag, or topic name, is what is sent to the help server. It is the responsibility of the application programmer to associate this topic name appropriately so that when the user requests help a meaningful help topic is displayed by the help viewer. This association is typically done through the use of the helpCallback facility provided by Motif.

Although using hard-coded topic names is fairly simple conceptually, there are some definite disadvantages to this approach:

Using Help

There are multiple ways that a user may request help from within a client:

All of these methods result in a request being sent to the help server indicating which help book and topic should be displayed. While this request is being sent, a wait cursor should be displayed to provide the user with visual feedback. General descriptions of the behaviour the user should see in various situations are provided in the following sections.

Note that a given client may support any, all, or none of the above methods. Any deviations from the functionality described here should ideally be documented in the functional specification for the client in question (at least in the case of clients actively supported by SCO). Also, the behaviour described here is dependent on the online documentation provided. If the online documentation is incorrect or incomplete then help will not work correctly.

The technical details about what the developer and author actually need to do to make this behaviour occur are provided in the sections below, "Adding Help to an X Client" and "Authoring Help Files".

The Help Menu

A Help pulldown menu is available in the menu bar of many scoclients. There are seven possible options to select from, although not all will necessarily be present in every client. The following lists the possible items along with a description of the behaviour that should occur when the item is selected from the Help menu:
On Context
Selecting On Context allows the user to select the context for which help is desired. The cursor is first changed to the standard Motif help cursor (a question mark with an arrow at the bottom indicating the hot spot). The user can then select a widget within the client by placing the cursor over the spot of interest and clicking the left mouse button. The help server should then display information about the particular widget (or general context) where the selection was made. The level of detail displayed depends on how the documentation for that particular client has been written and organized.

If the user makes a selection outside of the client window (or in the window border) an error message is displayed indicating that help must be requested from within the application.

On Window
Selecting this item should result in the help server displaying general information about the window from which the selection was made. In scomail, for example, selecting Help On Window from the "Create Message" window should display general information about creating mail messages.

On Keys
Should result in the help server displaying information about the accelerator keys and mnemonics available in the client.

Index
Should result in the display of the Index for that particular client's help book.

On Help
Selecting Help On Help should display general information about using the help system. The topic displayed should probably be the same for all clients that are using scohelp to provide help services.

Tutorial
Results in the help server bringing up a tutorial about the client.

On Version
Causes an application-specific dialog box containing version information about the client to come up. On Version is the only item in the Help menu that does not result in a request being sent to the help server.

None of the Help menu items described above are required, it is up to the client developer to decide which options are appropriate for each client, and create the specified user interface in a manner consistent with other X clients.

Help Buttons

Clients may provide Help buttons in dialog boxes or in place of the Help pulldown menu. Pressing a Help button should cause the help server to display general information about the dialog box or window from which the Help button was pressed.

Using the <F1> Key

The <F1> key provides equivalent functionality to Help On Context, that is, it should provide help on the specific context in which help is requested. Pressing <F1> when the mouse pointer is over a widget (in a client that has focus) should cause help for that particular widget or general context to be displayed. As with Help On Context, the level of detail that is actually displayed depends on how the documentation for the client has been written and organized. The primary difference between using <F1> and Help On Context is that <F1> allows you to request help in situations where Help On Context can't be used (eg., requesting help for an item in a pulldown menu).

The Help Server

This section contains general information about the behaviour of the help server, scohelp.

Standalone vs. Server Mode

When scohelp is started from the command line it is said to be running in standalone mode, when it is invoked from a client to provide help it is referred to as being in server mode. A scohelp client that is running standalone will never act as a help server. Consequently if scohelp is brought up from the command line and help is then requested from a client, the client would start up a second scohelp process to act as the help server rather than attempt to attach to the first process. On a given display there can be any number of standalone scohelp processes, but there should be at most one scohelp process acting as a help server.

The process command ps(C) will show that one of the command line arguments to the scohelp process is "-cshelpservermode" when it is in server mode.

Management of Help Windows

Each client process that requests help will automatically have a primary help window associated with it. Subsequent requests for help from the same client process will cause the contents of the primary help window to change rather than opening a new window (or replacing the contents of some arbitrary help window). In addition, any other help windows that are created from the primary help window of a client (ie., via the New Window command) will also be associated with that client. When a client exits, all of the help windows associated with that client should automatically close.

Selecting "Close Window" from the scohelp client will only close that particular help window. If the window that was closed was a primary help window for a client then subsequent help requests from that client will create a new primary help window, either by using one of the other windows associated with the client or by creating a new window if no others exist.

It is important to note that closing the last visible help window will not actually cause the scohelp client to exit. Scohelp will only exit when the last client connected exits.

Topic Selection

This section describes what actually happens when the help server receives a help request.

When the help server receives a request to open a hard-coded topic name it checks to see if an entry containing the hard-coded topic name exists in the hook file. If one does exist, it attempts to open the topic that it maps to, otherwise it will attempt to open the original topic directly.

Most SCO clients use widget tree sums instead of the hard-coded topic names, but this scheme is for internal SCO use only, and is not supported in this API, except that the sums are communicated to the help server.

Adding Help to an X Client

The following sections provide the information necessary to add help to a client. It provides general background along with the technical details about using the api.

The Motif helpCallback

The Motif helpCallback is the building block for providing help in most Motif clients. Most help requests rely on this callback to some degree. The helpCallback, if it exists, is automatically called by the Motif toolkit when the <F1> key is pressed over a widget. Even if there is no helpCallback associated with the widget where the event occurred, Motif will automatically go up the widget hierarchy until it either finds a widget that does have a helpCallback or until the widget hierarchy is exhausted.

This feature of Motif means that the helpCallback only needs to be added to certain key widgets. For example, a helpCallback could be added to the parent of the set of widgets for which you wanted to provide a common help topic.

Help Api

The help api provides a basic facility for sending help requests to the help server. It supports the use of both hard-coded topic names and widget tree names, although widget tree names are intended for SCO internal use only (this api does not provide the facilities for building widget tree names).

The three functions provided by this api are:

HelpStatus HelpOpen()	 Initalize data structures for communicating with server
HelpStatus HelpDisplay() Sends requests to the help server
HelpStatus HelpClose()	 Closes the help connection

Initialization

#include </usr/skunk/include/scohelp/api.h>

HelpStatus HelpOpen(client_context, toplevel, bookdir, 
                                  wait_cursor, error_handler)
XtPointer       *client_context;
Widget           toplevel;
char            *bookdir;
void            ((*wait_cursor)(Boolean));
void            ((*error_handler)(char *));
HelpOpen() performs the initialization necessary for communicating with the help server. It returns helpSuccess on success and helpCreateClientFailure if the initialization fails.

Upon successful return from this function, the address specified by client_context will point to an allocated and initialized structure containing information about the client. The pointer to this structure is used in subsequent calls to HelpDisplay() and HelpClose(). The memory allocated for this structure is automatically free'd when HelpClose() is called by the client. Note that client_context and the structure that it points to should not be modified by the client.

toplevel is the widget id of the calling application's toplevel widget (after Xt initalization). NOTE: In earlier versions of the api it was required that this widget be an always present, realized widget. This is no longer required.

bookdir is the name of the default book used by the client (eg., XDeskHelp). This value can be overriden in subsequent calls to HelpDisplay() if the client needs to open multiple books. Ibookdir is assumed to be the name of a valid help book, no checking is done by this routine. The client's default help book should ideally be specified via a resource named "helpBook" so that there is a consistent way of specifying books across the clients.

The name specified by bookdir is actually the name of a subdirectory where the topics contained in the client's help book reside. By default, this subdirectory resides on the clients machine in /usr/lib/scohelp (although this can be overridden via the scohelp docServer resource and/or by changing DocumentRoot on the server). For more information, see the section below, "Online Book Organization".

wait_cursor, if non-NULL, points to a function within the client that is responsible for turning the wait cursor on and off. The wait_cursor routine is called with a value of TRUE when the client should display a wait cursor (eg., when waiting for a response from the help server) and FALSE when the client should display its default cursor.

error_handler, if non-NULL, points to a function in the client responsible for displaying error messages (typically in an error dialog box). This routine will be called with a character string containing the error message that should be displayed. For example, if the help server is not installed this routine would be called with a message indicating that the help server is not available.

Sending a Help Request

#include </usr/skunk/include/scohelp/api.h>

HelpStatus HelpDisplay(client_context, bookdir, obj_type, entry)
XtPointer        client_context;
char            *bookdir;
HelpObject       obj_type;
char            *entry;

HelpDisplay() sends a request to the help server indicating which topic should be displayed. It would typically be called from a client's helpCallback. helpSuccess is returned upon success, otherwise it returns one of: helpBusy, helpStartupFailure, helpInvalidObject, helpSendEventFailure, or helpNoBookSpecified indicating that an error occurred while attempting to send a request.

client_context points to the data structure initialized in the call to HelpOpen(). Note that in this case the pointer to the structure is passed, not the address of the pointer.

bookdir, if non-NULL, specifies the name of the book to open. If this value is NULL, then the default book specified in the call to HelpOpen() will be used. If neither name is valid the function will return helpNoBookSpecified.

obj_type specifies what type of request is being made. Possible values for this parameter include: helpTopic for hard-coded topic names and helpWidget for widget tree names.

entry is a null-terminated string specifying the topic to be displayed. If the request is for a hard-coded topic name, as specified by the obj_type parameter, then this parameter contains the literal string representing the topic name to display. If the request is for a widget tree name, then this argument contains the full pathname of the widget for which help is desired. Widget trees are for internal SCO use only.

Closing the Help Server Connection

#include </usr/skunk/include/scohelp/api.h>

HelpStatus HelpClose(client_context)
XtPointer        client_context;

HelpClose() should be called when the client wants to close all of its associated help windows, typically when the client exits.

client_context points to the data structure initialized in the call to HelpOpen(). The space that was allocated for this structure in HelpOpen() is free'ed by this call. Note that in this case the pointer to the structure in passed, not the address of the pointer.

HelpClose() always returns helpSuccess.

Examples

Following are some example code fragments of using the low-level help api:
  1. Initializing help within a client:

      main()
      {
           XtPointer ClientInfo;
                .
                .
           TopLevel = XtAppInitialize(&appContext, CLASSNAME, NULL, 0, &argc, argv,
                                                                              NULL, NULL, 0);
           ret = HelpOpen(&ClientInfo, TopLevel, AppData.helpBook, displayWaitCursor, errHandler);
           if (ret != helpSuccess)
                .
                .
           XtRealizeWidget(TopLevel);
                .
                .
      }
     
      static void
      displayWaitCursor(on)
      Boolean on;
      {
                .
                .
           if (on)
                 XDefineCursor(display, XtWindow(TopLevel), WaitCursor);
           else
                 XUndefineCursor(display, XtWindow(TopLevel));
      }
    
      static void
      errHandler(message)
      char *message;
      {
                .
                .
            xm_errstr = XmStringCreateLtoR(message, XmSTRING_DEFAULT_CHARSET);
            XtVaSetValues(errorDialog, XmNmessageString, xm_errstr, NULL);
            XmStringFree(xm_errstr);
    
            if (!XtIsManaged(errorDialog))
                    XtManageChild(errorDialog);
      }
    
  2. Displaying a specific hard-coded topic name in the default book:

           extern XtPointer ClientInfo;
               .
               .
           ret = HelpDisplay(ClientInfo, NULL, helpTopic, "ReadingMail");
           if (ret != helpSuccess)
               .
               .
    
  3. Closing the help server connection:

      exitClient()
      {
            extern XtPointer ClientInfo;
                .
                .
            HelpClose(ClientInfo);
      }
    

Warnings

This api is being provided to SCO customers with the understanding that it or its underlying implementation may change in the future. Client developers should understand that if this happens, it may be necessary to rework their client to be compatible with future versions of scohelp.

This api currently uses a property on the root window to prevent multiple invocations of the help server from occurring. Although this property is present only temporarily, if something out of the ordinary happens (ie., the client or scohelp dies before the help server comes up) this property may be left around and will prevent the help server from ever starting. If help requests are failing silently, check for this property and remove it by using the xprop command as follows:

To check for the existence of this property:

xprop -root | grep -y "lock"

To remove the property:

xprop -root -remove "_SCO_HELP_SERVER_LOCK for "

where will look something like "ohlone.sco.com"

If you see this problem, please notify SCO.

Availability

The api described in this section is currently part of the libhelp.a library. It is available for SCO Development System customers as a TLS and is also on Skunkworks (in /usr/skunk/lib). This is not a published api, it is subject to change, use at your own risk.

Authoring Help Files

This section describes how to author help files. It is primarily intended for authors responsible for writing online-help.

Online Book Organization

As was mentioned in an earlier section a book in scohelp is just the name of a directory. A help topic within a particular book is the name of a physical file in that book directory.

The default location of all books is on the local machine in /usr/lib/scohelp. The docServer resource can be used to specify an alternative server. The server configuration files can set DocumentRoot to some other location besides /usr/lib/scohelp (but all the documentation must be in the same directory). The documentation can be viewed directly using scohelp in Web Browser Mode. The DocumentRoot is automatically inserted by the server. For example, using the default location of the topic "UsingTheDesktop" in the book "XDeskHelp" could be viewed by executing Open URL and specifying:

http://localhost/XDeskHelp/UsingTheDesktop.html
on the localmachine the file can be found in
/usr/lib/scohelp/XDeskHelp/UsingTheDesktop.html
For more information on the documentation architecture, see the scohttp(ADM) man page.

Hook Files

A hook file is an optional text file that provides a facility for mapping hard-coded topic names to the actual names of topics in books. It allows multiple symbols to represent a single help topic.

If a hook file does exist, it must be located on the client machine and in the directory specified by the scohelp resource hookPath (by default /usr/lib/scohelp) in a subdirectory with the same name as the book, and the hookfile must have the same name as the book plus a ".hk" extension (eg., "XDeskHelp.hk").

Hook File Syntax

Each line in a hook file is a separate entry. The first field on the line is the sum or topic name to be mapped. The second field, separated from the first by white space, is the name of the actual topic (ie., file) to display. This topic name cannot contain white space. A comment line can be specified by starting a line with '!'. Comments can also appear at the end of entries, as long as they are preceded by white space. A partial hook file might look as follows:

! XDeskHelp.hk
intro           UsingTheDesktop
icons           DesktopIcons               Describes icons available
mouse           ../GECG/UsingTheMouse      Describes the scomouse client
click           ../GECG/UsingTheMouse      Describes the scomouse client
color           Controls#ChangingPalettes  Using scocolor
paint           Controls#ChangingPalettes  Using scocolor
A1534898        UsingTheDesktop            SCO use only

Because the topic names specified in the second column are the name of actual physical files, it is possible to use relative pathnames in this field to specify topics that exist in other books. It is also possible to use the "#" syntax supported in scohelp cross references (HREF) to refer to a section in the middle of a file.

Note that only relative pathnames are supported, full pathnames should never be used in this context.

Return to Welcome Home Page or Continue to Browse