From: jan@ECHO.CANBERRA.EDU.AU (Jan Newmarch)
Newsgroups: comp.windows.x.motif
Subject: Motif FAQ (Part 2 of 5)
Keywords: FAQ question answer
Date: 17 Aug 92 14:51:51 GMT
Expires: 17 Oct 92 04:31:34 GMT
Reply-To: jan@ise.canberra.edu.au (Jan Newmarch)
Followup-To: comp.windows.x.motif
Distribution: inet
Organization: The Internet

Archive-name: motif-faq/part2
Last-modified: Tue July 14 1992
Version: 2.6



-------------------------------------------------------------------------------
Subject: 27) TOPIC: MOTIF GENERATORS

-------------------------------------------------------------------------------
Subject: 28)*  What prototyping tools are there to generate Motif code?


Answer: [An FAQ is for "personal opinions" on these tools.  I don't think it is
appropriate to give such opinions through this particular posting, so I haven't
included any.]

`Prototyping tools' come in two forms: those that can be used to design the
interface only (GUI builder), and those that go beyond this to give support for
application code (User Interface Management Systems).  There are a number of
commercial and non-commercial tools of both kinds that will support the Motif
interface.  They include:

GUI builders:

Builder Xcessory
X Build
ExoCODE/xm


UIMS:

WINTERP
ALEX
Widget Creation Library
UIMX
Serpent
TeleUse
X-Designer
XFaceMaker2
MOTIFATION


Some contact addresses are:

WINTERP: You may obtain the current source, documentation, and examples via
anonymous ftp from host export.lcs.mit.edu: in directory contrib/winterp you
will find the compress(1)'d tar(1) file winterp.tar.Z. If you do not have
Internet access you may request the source code to be mailed to you by sending a
message to winterp-source%hplnpm@hplabs.hp.com or hplabs!hplnpm!winterp-source.

Serpent: The S/W is free (anonymous ftp) from ftp.sei.cmu.edu.  For more info
contact erik/robert at serpent-info@sei.cmu.edu.

TeleUse: In the U.K., send mail to xtech@unipalm.co.uk or call +44 954 211862.
In the US contact Telesoft at:

TeleSoft, 5959 Cornerstone Court West, San Diego, CA 92121-9891
             Phone: +1 619-457-2700
                    +1 619-452-1334 Fax
             Email: guisales@telesoft.com (Sales),
                    guisupport@telesoft.com (Customer Support)


Builder Xcessory from ICS.  More details are available by sending a request to
info@ics.com.  Address: ICS Inc., 201 Broadway, Cambridge MA 02139, Tel. (617)
621-0060, Fax. (617) 621-9555

X-Designer: From Imperial Software Technology in the UK.  Email address is
sales@ist.co.uk.  (+44) 743 587055

Recently, V.I. Corporation have become the distributor for the X-Designer
product in the United States.  In addition, IST and V.I. Corporation have
developed a product called DVX-Designer that merges X-Designer with their GUI
product called DataViews.  Other merged products are in the works.  For more
information, people can contact:

        V.I. Corporation
        47 Pleasant Street
        Northampton, MA  01060
        Phone: (413) 586-4144
        Fax: (413) 586-3805
        Email: vi@vicorp.com


ExoCODE/xm: From Expert Object Corp., 7250 Cicero Avenue, Lincolnwood, IL 60646
(708)676-5555.

X Build: From Nixdorf Computer (Waltham, MA) xbuild@nixdorf.com


ExoCode: From EXOC (Chicago, IL)

UIMX: Visual Edge Software Limited, 3870 Cote Vertu, St Laurent, Quebec, H4R
1V4, Phone: (514) 332-6430, Fax:   (514) 332-5914, or: Visual Edge Software
Ltd., 101 First Street, Suite 443, Los Altos, CA 94022, Phone: (415) 948-0753,
Fax:   (415) 948-0843

The Widget Creation Library: The distribution is available in several ways.  The
preferred approach it for you to get the compressed tar file using anonymous ftp
from:

    export.lcs.mit.edu    (18.30.0.238) /contrib/Wcl.1.06.tar.Z


XFaceMaker2: NSL -  Non Standard Logics S.A., 57-59, rue Lhomond, 75005  Paris -
France, Phone: +33 (1) 43.36.77.50, Fax:   +33 (1) 43.36.59.78 email:
requests@nsl.fr or requests%nsl.fr@inria.fr for information.

Their North American office: Non Standard Logics, Inc., 4141 State Street, Suite
B-11, Santa Barbara CA 93110, Tel: 805 964 9599, Fax: 805 964 4367


MOTIFATION: AKA EDV, Universitaetsstrasse 125, 4630 Bochum, Germany, Tel: +49
(0) 234 / 33397-0, Fax: +49 (0) 234 / 33397-40


ALEX: For more information contact Michael Karliner on (+44) 81 566 2307 or E-
mail to alex@s-strat.co.uk.  ALEX Technologies, Waterman's Yard, 32a The Mall,
Ealing, London W5, UK.


-------------------------------------------------------------------------------
Subject: 29) TOPIC: TEXT WIDGET

-------------------------------------------------------------------------------
Subject: 30) Why does  pressing  <return> in a text widget do nothing?  This
happens using Motif 1.0 when I have a text widget inside a bulletin board (or
form) inside a dialog shell. (In Motif 1.1 it is fixed for both text and list
widgets.)

Answer: In single line mode, pressing the <return> key usually invokes the
activate() action, and in multi-line mode, the newline() action.  However,
whenever a widget is the child of a bulletin board widget which is the child of
a dialog shell, the bulletin board forces all of its children to translate
<return> to the bulletin board action Return() which is usually associated with
the default button of the dialog.  To restore the text actions of activate() or
newline(), you need to overide the Return() action of the bulletin board.


        /* declarations */
        /* for a single line widget */
        char newTrans[] = "<Key>Return : activate()";
        /* for a multi line widget */
        char newTrans[] = "<Key>Return : newline()";
        XtTranslations transTable;

        /* in executable section */

        transTable = XtParseTranslationTable(newTrans);

        /* after creating but before managing text widget */

        XtOverrideTranslations(textWidget, transTable);


-------------------------------------------------------------------------------
Subject: 31) When I add text to a scrolling text widget how can I get the new
text to show?

Answer: Use the call undocumented in Motif 1.0

        void XmTextShowPosition(w, position)
        Widget w;
        XmTextPosition position;

where the position is the number of characters from the beginning of the buffer
of the text to be displayed. If you don't know how many characters are in the
buffer, use another call undocumented in Motif 1.0

        position = XmTextGetLastPosition(w)


-------------------------------------------------------------------------------
Subject: 32) Does the text widget support 16 bit character fonts?

Answer: R5 will have support for 16 bit character sets, and Motif 1.2 will use
that. You will have to wait until then.

-------------------------------------------------------------------------------
Subject: 33) How can I stop the text widget from echoing characters typed?  I
need to turn off echo for password input.

Answer: Use the modifyVerifyCallback to tell when input is received. Set the
`doit' field in the XmTextVerifyCallbackStruct to False to stop the echo. In
Motif 1.0 this will cause a beep per character: Live with it, because at 1.1 you
can turn it off.  Note that password hiding is inherently insecure in X -
someone may have an X grab on the keyboard and be reading all characters typed
in anyway.

Another solution often proposed is to set the foreground and background colours
to be the same, effectively hiding the text.  This has a major flaw: someone may
select the text (triple click the mouse to get the line), and then paste the
password into say an xterm with *different* foreground and background colours.
This immediately shows the password.

-------------------------------------------------------------------------------
Subject: 34) How can I replace characters typed with say a `*'?  I want to
replace input for password entry.

Answer: In Motif 1.1 Use the modifyVerifyCallback to tell when input is
received.  Set text->ptr in the callback structure to '*'. This does not work
under 1.0 because of an oversight in which changes to this are ignored.  In
Motif 1.0, what you can do is set the doit flag to 'false' so the text is not
displayed. Then set a static boolean to True to prevent re-entrance.  Next call
XmTextReplace() to display your '*'.  then reset your re-entrance flag to False.
XmTextReplace() will call the XmNmodifyVerify callback.  To prevent getting into
an infinite loop, you need the re-entrance flag.

The following program from Dan Heller illustrates this:

----------------
/* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
 * This program is freely distributable without licensing fees and
 * is provided without guarantee or warranty expressed or implied.
 * This program is -not- in the public domain.  This program appears
 * in the Motif Programming Manual, O'Reilly Volume 6.
 */

/* passwd.c -- prompt for a passwd.  Meaning, all input looks like
 * a series of *'s.  Store the actual data typed by the user in
 * an internal variable.  Don't allow paste operations.  Handle
 * backspacing by deleting all text from insertion point to the
 * end of text.
 */
#include <Xm/Text.h>
#include <Xm/LabelG.h>
#include <Xm/RowColumn.h>
#include <ctype.h>

void check_passwd();
char *passwd; /* store user-typed passwd here. */

main(argc, argv)
int argc;
char *argv[];
{
    Widget        toplevel, text_w, rowcol;
    XtAppContext  app;

    toplevel = XtVaAppInitialize(&app, "Demos",
        NULL, 0, &argc, argv, NULL, NULL);

    rowcol = XtVaCreateWidget("rowcol",
        xmRowColumnWidgetClass, toplevel,
        XmNorientation, XmHORIZONTAL,
        NULL);

    XtVaCreateManagedWidget("Password:",
        xmLabelGadgetClass, rowcol, NULL);
    text_w = XtVaCreateManagedWidget("text_w",
        xmTextWidgetClass, rowcol, NULL);

    XtAddCallback(text_w, XmNmodifyVerifyCallback, check_passwd, NULL);
    XtAddCallback(text_w, XmNactivateCallback, check_passwd, NULL);

    XtManageChild(rowcol);
    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
}

void
check_passwd(text_w, unused, cbs)
Widget        text_w;
XtPointer     unused;
XmTextVerifyCallbackStruct *cbs;
{
    char *new;
    int len;

    if (cbs->reason == XmCR_ACTIVATE) {
        printf("Password: %s0, passwd);
        return;
    }

    if (cbs->text->ptr == NULL) { /* backspace */
        cbs->endPos = strlen(passwd); /* delete from here to end */
        passwd[cbs->startPos] = 0; /* backspace--terminate */
        return;
    }

    if (cbs->text->length > 1) {
        cbs->doit = False; /* don't allow "paste" operations */
        return; /* make the user *type* the password! */
    }

    new = XtMalloc(cbs->endPos + 2); /* new char + NULL terminator */
    if (passwd) {
        strcpy(new, passwd);
        XtFree(passwd);
    } else
        new[0] = NULL;
    passwd = new;
    strncat(passwd, cbs->text->ptr, cbs->text->length);
    passwd[cbs->endPos + cbs->text->length] = 0;

    for (len = 0; len < cbs->text->length; len++)
        cbs->text->ptr[len] = '*';
}


-------------------------------------------------------------------------------
Subject: 35) How can I best add a large piece of text to a scrolled text widget?
In some versions of Motif 1.0 even using XmTextSetString, it insists on adding
the text one line at a time, adjusting the scroll bar each time. It looks awful
and is slow.

Answer: If you don't have this problem, use XmTextSetString to set all of the
text in the widget.  If you do have this slowdown problem even using
XmTextSetString, unmanage the widget, add the text and then manage it again.
This may cause the window to blink, but you have to put up with that or switch
to a different version of Motif.

-------------------------------------------------------------------------------
Subject: 36) How can I highlight text in the Text widget?

Answer: From: argv@zipcode.com (Dan Heller)

If you don't need font or color changes, you can do all this using a Text widget
very easily [in Motif 1.1, anyway].

        loop() {
            pos = offset_of_pattern_in_text_widget(pattern, text_w);
            search_len = strlen(pattern);
            XmTextSetHighlight(text_w, pos, pos+search_len,
                        XmHIGHLIGHT_SELECTED);
        }


There are two choices for highlighting: reverse video (HIGHLIGHT_SELECTED) and
underlined (HIGHLIGHT_SECONDARY_SELECTED).  Be careful that your users won't
confuse your highlights with actual selections!

-------------------------------------------------------------------------------
Subject: 37)  How can I select all of the text in a widget programmatically?  So
that some initial text is displayed, but anything typed replaces it.

Answer: XmTextSetSelection(Text1, 0, XmTextGetLastPosition(Text1), event-
>xbutton.time);

where Text1 is the widget in question (obviously) and event is some event that
triggered this call.  You can use XtLastTimestampProcessed( display) instead of
xbutton.time if you don't happen to have an event pointer handy.




-------------------------------------------------------------------------------
Subject: 38) How can I change colours of text in the Text widget?  I want some
of the text in one colour, some in another.

Answer: You can't.  Text stores an ordinary string, and points where
`highlights' of various types begin and end.  These highlights are all the
control you have over components of the text.  See the previous question.


-------------------------------------------------------------------------------
Subject: 39) How can I change the font of text in the Text widget?  I want some
of the text in one font, some in another.

Answer: You can't in Text (see the previous question).  If you wanted readonly
text, you could do it by using a label instead.  Label uses XmStrings, which can
contain multiple character sets in the one string.

-------------------------------------------------------------------------------
Subject: 40) Is there an emacs binding for the text widget?

Answer: This set is due to Kee Hinckley (nazgul@alfalfa.com):

*XmText.translations: #override\n\
        Ctrl <Key>b:            backward-character()\n\
        Alt <Key>b:             backward-word()\n\
        Meta <Key>b:            backward-word()\n\
        Shift Alt <Key>b:       backward-word(extend)\n\
        Shift Meta <Key>b:      backward-word(extend)\n\
        Alt <Key>[:             backward-paragraph()\n\
        Meta <Key>[:            backward-paragraph()\n\
        Shift Alt <Key>[:       backward-paragraph(extend)\n\
        Shift Meta <Key>[:      backward-paragraph(extend)\n\
        Alt <Key><:             beginning-of-file()\n\
        Meta <Key><:            beginning-of-file()\n\
        Ctrl <Key>a:            beginning-of-line()\n\
        Shift Ctrl <Key>a:      beginning-of-line(extend)\n\
        Ctrl <Key>osfInsert:    copy-clipboard()\n\
        Shift <Key>osfDelete:   cut-clipboard()\n\
        Shift <Key>osfInsert:   paste-clipboard()\n\
        Alt <Key>>:             end-of-file()\n\
        Meta <Key>>:            end-of-file()\n\
        Ctrl <Key>e:            end-of-line()\n\
        Shift Ctrl <Key>e:      end-of-line(extend)\n\
        Ctrl <Key>f:            forward-character()\n\
        Alt <Key>]:             forward-paragraph()\n\
        Meta <Key>]:            forward-paragraph()\n\
        Shift Alt <Key>]:       forward-paragraph(extend)\n\
        Shift Meta <Key>]:      forward-paragraph(extend)\n\
        Ctrl Alt <Key>f:        forward-word()\n\
        Ctrl Meta <Key>f:       forward-word()\n\
        Ctrl <Key>d:            kill-next-character()\n\
        Alt <Key>BackSpace:     kill-previous-word()\n\
        Meta <Key>BackSpace:    kill-previous-word()\n\
        Ctrl <Key>w:            key-select() kill-selection()\n\
        Ctrl <Key>y:            unkill()\n\
        Ctrl <Key>k:            kill-to-end-of-line()\n\
        Alt <Key>Delete:        kill-to-start-of-line()\n\
        Meta <Key>Delete:       kill-to-start-of-line()\n\
        Ctrl <Key>o:            newline-and-backup()\n\
        Ctrl <Key>j:            newline-and-indent()\n\
        Ctrl <Key>n:            next-line()\n\
        Ctrl <Key>osfLeft:      page-left()\n\
        Ctrl <Key>osfRight:     page-right()\n\
        Ctrl <Key>p:            previous-line()\n\
        Ctrl <Key>g:            process-cancel()\n\
        Ctrl <Key>l:            redraw-display()\n\
        Ctrl <Key>osfDown:      next-page()\n\
        Ctrl <Key>osfUp:        previous-page()\n\
        Ctrl <Key>space:        set-anchor()\n


! If you'd like the Delete key to work like backspace instead of deleting
! backwards, add the following definition to the lines above.
!       <Key>osfDelete: delete-previous-character()\n\

! These aren't included because they could intefere with menu accelerators (or vice versa)
!       Alt <Key>p:             backward-paragraph()\n\
!       Meta <Key>p:            backward-paragraph()\n\
!       Shift Alt<Key>p:        backward-paragraph(extend)\n\
!       Shift Meta<Key>p:       backward-paragraph(extend)\n\
!       Alt <Key>w:             copy-clipboard()\n\
!       Meta <Key>w:            copy-clipboard()\n\
!       Ctrl Alt <Key>w:        cut-clipboard()\n\
!       Ctrl Meta <Key>w:       cut-clipboard()\n\
!       Alt <Key>y:             paste-clipboard()\n\
!       Meta <Key>y:            paste-clipboard()\n\
!       Alt <Key>f:             forward-word()\n\
!       Meta <Key>f:            forward-word()\n\
!       Alt <Key>n:             forward-paragraph()\n\
!       Meta <Key>n:            forward-paragraph()\n\
!       Shift Alt <Key>n:       forward-paragraph(extend)\n\
!       Shift Meta <Key>n:      forward-paragraph(extend)\n\
!       Shift Alt <Key>f:       forward-word(extend)\n\
!       Shift Meta <Key>f:      forward-word(extend)\n\
!       Alt <Key>d:             kill-next-word()\n\
!       Meta <Key>d:            kill-next-word()\n\
!       Alt <Key>h:             select-all()\n\
!       Meta <Key>h:            select-all()\n\

Similar sets of translations have been suggested by others.

-------------------------------------------------------------------------------
Subject: 41) How can I use a file as the text source for a Text widget?

Answer: You can't do it directly like you can with the Athena Text widget.
Instead, read the text from the file into a string (all of it!) and then use
XmTextSetString.  Alternatively, read blocks of characters and add them at the
end of the text using XmTextInsertString.  The following is an excerpt from Dan
Heller's "file_browser.c":

    /* file_browser.c -- use a ScrolledText object to view the
     * contents of arbitrary files chosen by the user from a
     * FileSelectionDialog or from a single-line text widget.
     */

    ...
    struct stat statb;

    /* make sure the file is a regular text file and open it */
    if (stat(filename, &statb) == -1 ||
            (statb.st_mode & S_IFMT) != S_IFREG ||
            !(fp = fopen(filename, "r"))) {
        if ((statb.st_mode & S_IFMT) == S_IFREG)
            perror(filename); /* send to stderr why we can't read it */
        else
            fprintf(stderr, "%s: not a regular file0, filename);
        XtFree(filename);
        return;
    }

    /* put the contents of the file in the Text widget by allocating
     * enough space for the entire file, reading the file into the
     * allocated space, and using XmTextFieldSetString() to show the file.
     */
    if (!(text = XtMalloc((unsigned)(statb.st_size+1)))) {
        fprintf(stderr, "Can't alloc enough space for %s", filename);
        XtFree(filename);
        fclose(fp);
        return;
    }

    if (!fread(text, sizeof(char), statb.st_size+1, fp))
        fprintf(stderr, "Warning: may not have read entire file!0);

    text[statb.st_size] = 0; /* be sure to NULL-terminate */

    /* insert file contents in Text widget */
    XmTextSetString(text_w, text);




-------------------------------------------------------------------------------
Subject: 42) How can put Text in overstrike mode instead of insert?

Answer: There is no direct way. This was posted by Edmond Pitt
(ejp@bohra.cpg.oz) The correct answer to the question is to put the following in
a modifyVerify callback, where 'mvcb' is the XmTextVerifyCallbackStruct, and
'overstriking' is defined by you:

    if (overstriking && mvcb->text->length == 1)
    {
        _XmTextDisableRedisplay(w,FALSE);
        XtCallActionProc(w,"delete-next-character",mvcb->event,0);
        _XmTextEnableRedisplay(w);
    }

_XmText{Dis,En}ableRedisplay() are XmText{Dis,En}ableRedisplay() in 1.0, but
X11R3 has no XtCallActionProc() anyway. For this environment you need my 1.0.3
Text widget patches posted last year & available on request.


-------------------------------------------------------------------------------
Subject: 43) How can I make the Delete key do a backspace?

Answer: Put this in your .Xdefaults

    *XmText.translations: #override <Key>osfDelete: delete-previous-character()


-------------------------------------------------------------------------------
Subject: 44) TOPIC: LIST WIDGET

-------------------------------------------------------------------------------
Subject: 45) How do I best put a new set of items into a list?

Answer: Set the new list count and list by XtSetArgs and install them by
XtSetValues.

    XmString list[SIZE];
    int list_size;

    XtSetArg (args[n], XmNitemCount, list_size); n++;
    XtSetArg (args[n], XmNitems, list); n++;
    XtSetValues (w, args, n);

Each time the list is reset by this the old contents are freed by the widget and
the new supplied list is copied.  Do *not* free the old list of items yourself
as this would result in the space being freed twice.  It is not necessary to
remove the items one at a time, nor to "zero" out the list first.

-------------------------------------------------------------------------------
Subject: 46)  Can I have strings with different fonts in a list?

Answer: Yes. The strings are XmStrings. Each one can be created using a
different character set using a different font.


-------------------------------------------------------------------------------
Subject: 47) Can I get a bitmap to show in a list item like I can in a Label?  I
want to place a bitmap along with some normal text in my list items.

Answer: No. The list contains XmStrings, and these only allow text in various
character sets. The workaround is to define your font containing the icons you
want. Then you can create a fontlist containing your icon font and the font you
want the text in, and then make your items multi-segment XmStrings where the
first segment contains the code of the icon you want with a charset that matches
the icon font in your fontlist and the second segment with a charset matching
the text font.


-------------------------------------------------------------------------------
Subject: 48) Can I have items with different colours in a list?

Answer: No.  The list contains XmStrings, and these only allow text in various
character sets. Since the items are XmStrings, you can already change the font
of an item by replacing it with an item with the same text and a different
charset tag.  Adding support for color would require modification of the
internal data structure in XmList as well as modification to the drawing
routines.  A possible workaround is to use a rowcolumn of buttons which can be
individually set.  However, you would have to do all list functionality
yourself.


-------------------------------------------------------------------------------
Subject: 49) Can I grey out an item in a list?  I want to make insensitive items
in a list so that they cannot be selected.

Answer:

From W. Scott Meeks of OSF:

Unfortunately, you can't do it directly since the list items aren't individual
widgets.  We've had other requests for this technology, but it didn't make the
cut for 1.2; it should be in some future release.

However, you can probably fake it in your application with some difficulty.
First, a list item is an XmString, so you can specify a different charset for
the item than for other items in the list and then specify a font in the list's
fontlist that matches the charset and gives you the visual you want.  The next
problem is making the item unselectable.  One idea would be to have the
application keep track of the insensitive items and the items currently
selected.  Then you would set up a selection callback that when called would
check the item selected against the list of insensitive items and if the
selected item matched would deselect that item and reselect the previously
selected items.  Otherwise it would just update the application's list of
selected items.  The major drawback with this approach is that you'll get
flashing whenever the list selects an item and your application immediately de-
selects.  Unfortunately I can't think of a way around this without mucking with
the list internals.

Another alternative suggested is to use instead a column of say read only text
widgets which you can make insensitive.

-------------------------------------------------------------------------------
Subject: 50) TOPIC: FILE SELECTION BOX WIDGET

-------------------------------------------------------------------------------
Subject: 51) What is libPW.a and do I need it?  My manual says I need to link in
libPW.a to use the File Selection Box.  I can't find it on my system.

Answer: The libPW.a is the Programmers Workbench library which is an ATT product
not included in Berkeley based systems, hence it is not found in SunOS or
Ultrix, but is found on HP-UX (a Berkeley/ATT hybrid which chose ATT in this
case).  It contains the regex(3) routines (regcmp, regex).  Some systems which
don't have these in the libc.a need to link with -lPW.  Some systems which have
the regex(3) routines in there also have the libPW.a.  If you have regex(3) in
libc, and it works, don't link with libPW.  If you don't have regex(3) in libc,
and you don't have a libPW, then check some sites on the net for public domain
replacements (several exist), or call your vendor.

In most versions of Motif (see the doco), you can compile FileSB.c with
-DNO_REGEX if you don't have it.

-------------------------------------------------------------------------------
Subject: 52) What are these compile errors: Undefined symbol _regcmp?

Answer: You need to link in the libPW library - see previous question.


-------------------------------------------------------------------------------
Subject: 53) What's wrong with the Motif 1.0 File Selection Box?  I can't set
the directory, change the directory or get the file mask to work.

Answer: The 1.0 File Selection Box is broken, and these don't work.  They
weren't fixed until Motif 1.04.  Use these later versions of 1.0 or switch to
Motif 1.1 where it changed a lot.

Joe Hildebrand has a work-around for some of this: Before popping up an
XmFileSelectionDialog, change to the directory you want.  When a file is
selected, check if it is a directory, so that we can change to it.  i.e.

static void show_file_box_CB(w, client_data, call_data)
   Widget               w;
   Widget               client_data;
   XmAnyCallbackStruct  *call_data;
{
   chdir("/users/hildjj/files");
   XtManageChild(client_data);
}

static void val_save(w, client_data, call_data)
   Widget       w;
   Widget       client_data;
   XmSelectionBoxCallbackStruct *call_data;
{
   struct stat buf;  /* struct stat is defined in stat.h */
   char *filename;

   /* get the file name from the FileSelectionBox */
   filename = SmX(call_data->value);

   /* get the status of the file named filename, and put it into buf */
   if (!stat(filename, &buf))
   {
      /* if it's a directory */
      /* if it's a directory */
      if(S_ISDIR(buf.st_mode))
      {
         /* change to that directory, and update the FileSelectionBox */
        chdir(filename);
        XmFileSelectionDoSearch(w, NULL);
      }
      else
         /* if it's a regular file */
         if(S_ISREG(buf.st_mode))
            /* ask if it should be overwritten */
            XtManageChild(valbox);
         else
            /* it's another kind of file.  What type, i can't think of,
               but it might happen */
            pop_up_error_box(client_data, "Error saving file");
   }
   else  /* we couldn't get the file status */
   {
      /* if it's because the file doesn't exist, we're golden */
      if (errno == ENOENT)
         save_file();
      else   /* there is some other problem getting the status.
                e.g. bad path */
         pop_up_error_box(client_data, "Error saving file");
   }
}

this still doesn't implement the file masking stuff.


-------------------------------------------------------------------------------
END OF PART TWO