89/10/13

Here's a brief description of the functions available in
MotifUtilities.  (MotifUtilities is a library of useful motif-related
functions which may be called either from uil or C or both.)

To link against MotifUtilities library, please add "-lMu" to your list
of libraries in your makefile and please include the file Mu.h in your
C files (Mu.h is in /afs/athena/astaff/project/motifdev/include
directory).

Note: If you try to load libMu.a or any object file compiled by gcc 
      with -g into saber, it won't work.  To fix this use "load -G" 
      in saber.  This tells saber to ignore debugging information, 
      which is what messes it up with gcc-compiled stuff.


Please send any bug reports to "djf".  Carbon-copy to "vanharen".

 ************************************************************************** 
 **************************************************************************

	void MuInitialize(toplevel)

Everyone using MotifUtilities must call MuInitialize(toplevel) 
after you XtInitialize your toplevel and before you call "MrmOpenHierarchy."

You pass your toplevel widget as an argument.

    e.g. 
         Widget toplevel;

         toplevel = XtInitialize(
         "test",
         "testclass",
          NULL, 0,
          &argc, argv);
  
         MuInitialize(toplevel);
   
 ************************************************************************

	void MuRegisterNames()

If you are using any of the MotifUtilities functions which can be
called from uil, you must call this function.  It will automatically
register all MotifUtilities Callback functions in uil so that you
won't have to add them on to your MRMRegisterArg.

Note:  MuRegisterNames() should go before the "MrmFetchWidget" and
after "MrmOpenHierarchy".

    e.g. 
             if (MrmOpenHierarchy (1,
                       vec,
                       NULL,
                       &s_MrmHierarchy)  != MrmSUCCESS) {
               printf ("cant' open hierarchy. . . \n");
             }

             MuRegisterNames();

The functions which can be called directly from uil are:

        void
                MuSetEmacsBindings(),
               	MuSetSingleLineEmacsBindings(),
               	MuSetStandardCursor(),
               	MuSetCursor(integer),
       		MuSetWaitCursor(),
                MuHelp(),
           	MuRegisterWidget(),
                and
       	        MuSetSensitive() .
 *************************************************************************

	void MuSetEmacsBindings(text_widget)  and 
        void MuSetSingleLineEmacsBindings(text_widget)

These functions add emacs bindings to your text widgets' translation
table so that you can back space, <Ctrl>d, <Ctrl>d, etc. 
From your C file you pass the text_widget you want the emacs bindings
for.  MuSetEmacsBindings takes multi-line text widgets, and
MuSetSingleLineEmacsBindings take single-line text widgets.  You will
get an error message if the widget you pass is NULL or not a text
widget.

 ----------------------------------------------------------------------
	void MuSetEmacsBindings() and
        void MuSetSingleLineEmacsBindings()

These functions are to be used in the uil file with the create
callbacks of your text widgets. 

        e.g.

        object textbox : XmScrolledText {
        arguments {
               XmNeditable = true;
               XmNedit_mode = XmMULTI_LINE_EDIT;
               XmNword_wrap = true;
               	};
        callbacks {
                XmNcreateCallback = procedure MuSetEmacsBindings();
                };
     };

 *************************************************************************
	
	void MuSetStandardCursor(widget),
	void MuSetWaitCursor(widget),

	void MuSetCursor(widget, cursorshape)
              Widget widget;
              unsigned int cursorshape;

These functions set the cursor shape in your interface window.
(Standard cursor is an arrow, and the Wait cursor is a watch.)  You
can pass any widget to these functions, and they will set the cursor
shape in the shell ancestor (parent, grandparent,
great-grandparent...) of the widget passed.  MuSetCursor sets any
cursor shape (from cursor font) passed.  

(If you do "xfd cursor", you'll get a window with all the cursor
shapes available in font cursor.  Click on a cursor shape with your
middle button, and you'll get the number description of the cursor
shape.) 
 ----------------------------------------------------------------------
 	void MuSetStandardCursor(),
	void MuSetWaitCursor(),
	void MuSetCursor(tag)

Note:  Djf recommends calling these functions from uil because he
feels that the cursor is really part of the interface and as such
belongs in the uil file rather than the C file.

** These functions are to be used in the uil file with the activate
callbacks.  MuSetCursor takes an integer tag which is the
number description of the cursor shape from the cursor font.

         e.g.

         object button : XmPushButton {
         arguments {
                      XmNlabelString = compound_string('Button');
                  };
         callbacks {
                 XmNactivateCallback = procedures { MuSetWaitCursor();
                                         Do_some_procedure();
                                         MuSetStandardCursor(); 
                    };
                 };
            }; 
 ***************************************************************************

	void MuError(string)
             char *string;

	void MuWarning(string)
             char *string;
   
/*  MuHelp(string) can also be called from uil.  */
     
        void MuHelp(string)    
             char *string;
 
         
These functions put up an error dialog box and a warning dialog box   
when passed a string (can include " \n " in the string to get a new
line).  (The dialog boxes will have a standard cursor.) 

Note: MuError and MuWarning pop up modal dialog boxes while MuHelp
      pops up a modeless dialog box (see below for more info).

 ----------------------------------------------------------------------

  You can call MuHelp("help string") from uil as well as from C files. 

                void MuHelp(string)
                   char *string;

MuHelp puts up a help message box with your choice of help string.
These are "modeless" dialog boxes, and you can have as many as 25
different help dialog boxes managed at once. (If you try to manage
more than 25 at once, you will get an error message.)

Don't forget to call MuRegisterNames() before MrmFetchWidget(...) if
you call MotifUtilities functions from uil.

 *************************************************************************
 
     void MuErrorSync(string)
          char *string

     void MuWarningSync(string)
          char *string

     void MuHelpSync(string)
          char *string

MuWarningSync and MuErrorSync are synchronous versions of the
MuWarning and MuError functions.

MuHelpSync is similar to MuWarningSync and MuErrorSync, but not
similar to MuHelp at all.  MuHelpSync does not provide multiple
help dialogs the way MuHelp does, it provides only one, synchronous
dialog box the way that MuErrorSync and MuWarningSync do.

They popup up and wait for the user to click on "OK" before continuing
with the next line of code (which may well be "exit()").  This is 
accomplished by invoking a recursive copy of XtMainLoop inside of the
utility routine and using longjmp() from the Ok callback to abort from
the recursive copy.  

They are great for dealing with fatal errors and the like  -- in the
event of a fatal error where the user cannot continue the program, you
can warn the person before taking down the program using MuErrorSync
or MuWarningSync (the function will wait for the OK button, then exit
or do whatever you want it to do).

 *************************************************************************

         void MuSetTextTraversal(widgets, number, subtree) 
                WidgetList widgets;
                int number;
                Widget subtree;

  widgets: array of text widgets

  number: number of text widgets in the array

  subtree: subtree of the hierarchy for which the keyboard focus is to
           be set.  (e.g.  It'll probably be "toplevel".)

This function enables traversal among a group of text widgets using
the up arrow, down arrow, and the return key.  This is useful for text
widgets used for field input.

The function checks to see if the text widgets passed are
single-line or multi-line text widgets.  The Return key binding is not
changed for multi-line text widgets (this is for those of you who
have a scrolled, multi-line text widget, and you want the up and down
arrow keys to be "traversal keys", while the Return key still behaves	
like a normal return key).

The function also checks for sensitivity.  Therefore, if a text
field is not "sensitive", it will be skipped during traversal.

** You can have more than one set of text widgets for traversal.  
   i.e.   If you call MuSetTextTraversal(widgets1, 3, toplevel) and
          MuSetTextTraversal(widgets2, 4, toplevel), traversal among
          the text widgets in widgets1 will be set independent of the
          text widgets in widgets2.
 ***************************************************************************

	About MuGetBoolean, MuGetFileName, and MuGetString ...

 * This is a general description of MuGetBoolean, MuGetFileName, and 
 * MuGetString.   These popup a modal dialog box for communication with
 * the user.  They provide a synchronous interface to the programmer.
 * That is, like gets() or scanf() they return the desired value
 * directly to the programmer, without any intervening callbacks.
 * This is accomplished by invoking a recursive copy of XtMainLoop
 * inside of the each utility routine, and using longjmp() from within
 * the ok and cancel callbacks to abort from that recursive copy.
 * This is witchcraft, but provides powerful interface tools to the
 * programmer.
 * For additional convenience, these functions never take compound
 * strings as arguments.  All strings are passed as char *.

  ------------------------------------------------------------------------

Boolean MuGetBoolean(prompt, yeslabel, nolabel, helptext, 
                                            defaultbutton, poup_control)
        char *prompt, *yeslabel, *nolabel;
        char *helptext;
        Boolean defaultbutton;
        int poup_control;

 * Uses an XmMessageDialog widget to prompt the user for an answer to
 * a yes-or-no type question.
 * Inputs:
 *      prompt          The question to present the user.
 *      yeslabel        The text to appear on the "True" button.
 *      nolabel         The text to appear on the "False" button.
 *      helptext        The text to appear when the "Help" button is clicked.
 *                      If NULL is specified, the help button will not appear.
 *      defaultbutton   A Boolean indicating which button should be the default
 *                      -- the "Ok" or the "Cancel" button
 *      poup_control    An integer which specifies the position to
 *                      popup the dialog box (see "popup control
 *                      argument for MuGetBoolean, MuGetString, and 
 *                      MuGetFileName" below)
 *
 * Returns:
 *      a Boolean indicating which button was pressed.
 *

 ----------------------------------------------------------------------- 

Boolean MuGetString(prompt, buffer, bufsize, helptext, popup_control)
	char *prompt;
	char *buffer;
	int bufsize;
	char *helptext;
        int popup_control;

 * MuGetString
 * Uses a PromptDialog convenience widget to prompt the user to input
 * a string.  The string is returned in a passed buffer, and the
 * function returns a Boolean indicating whether the "Ok" or the
 * "Cancel"  button was pressed.
 * Inputs:
 *      prompt          The string to prompt the user with.
 *      buffer          A pointer to a buffer to return the string in.
 *                      The contents of the buffer will be displayed as
 *                      the default string. 
 *      bufsize         The size in bytes of the buffer.
 *                      This will determine the maximum length of the
 *                      text string, which will be bufsize - 1.
 *      helptext        The text to display if the help button is
 *                      clicked.  If NULL, no Help button will be
 *                      displayed.
 *      popup_control   An integer which specifies the position to
 *                      popup the dialog box (see "popup control
 *                      argument for MuGetBoolean, MuGetString, and 
 *                      MuGetFileName" below)
 *
 * Outputs:
 *      buffer          Contains the NULL-terminated string the user
 *                      selected.
 * Returns:
 *      a Boolean indicating whether the user clicked the "Ok"
 *      button  (True) or the "Cancel" button (False).  If False is
 *      returned, then the contents of buffer should be ignored.
 */

 ------------------------------------------------------------------------

Boolean MuGetFileName(buffer, bufsize, dirmask, 
                              dirmasksize, helptext, popup_control)
	char *buffer;
	int bufsize, dirmasksize;
	char *dirmask; 
	char *helptext;
        int popup_control;

 * Uses a FileSelectionDialog widget to prompt the user to select a file.
 * The string is returned in a passed buffer, and the
 * function returns a Boolean indicating whether the "Ok" or the
 * "Cancel"  button was pressed.
 * Inputs:
 *      buffer          A pointer to a buffer to return the file name in.
 *                      (e.g.   in your c file,
 *                              declare buffer to be something like ..
 *                                   char buffer[50];                  )
 *                    
 *      bufsize         The size in bytes of the buffer.
 *                      This will determine the maximum length of the 
 *                      text string -- the maximum will be bufsize - 1.
 *                      
 *      dirmask         A pointer to a buffer to return the value of the
 *                      directory mask. The contents of dirmask will
 *                      be used as the default. 
 *
 *      dirmasksize     The size in bytes of the dirmask.
 *                      This will determine the maximum length of the
 *                      text string for the dirmask.
 *      helptext        The text to display if the help button is
 *                      clicked.  If NULL, no Help button will be
 *                      displayed.
 *      popup_control   An integer which specifies the position to
 *                      popup the dialog box (see "popup control
 *                      argument for MuGetBoolean, MuGetString, and 
 *                      MuGetFileName" below)
 * Outputs:
 *      buffer          Contains the NULL-terminated file name the user
 *                      selected.
 *      dirmask         Contains the NULL-terminated directory mask used.
 * Returns:
 *      a Boolean indicating whether the user clicked the "Ok"
 *      button  (True) or the "Cancel" button (False).  If False is
 *      returned, then the contents of buffer should be ignored.
 */

 Note:  The default value of dirmask in the FileSelectionDialog
resources is " * ".  FileSelectionDialog believes that this indicates
the current directory you are in.  (i.e.  If you're in /mit/motifdev,
it will display all the files in /mit/motifdev .)  Changing the
dirmask to be "*.c" or something like that will NOT do what you expect
it to do, which is to display all the c files in the current directory.
However, changing the dirmask to be "/mit/motifdev/projects" will make it
display all the files in /mit/motifdev/projects .

 ------------------------------------------------------------------------   
 **  popup control argument for MuGetBoolean, MuGetString, and 
 **  MuGetFileName             

      The options for the popup control are:

      Mu_Popup_Left --      popup to the left of parent,
      Mu_Popup_Right --     popup to the right of parent,
      Mu_Popup_Bottom --    popup at the bottom of the parent,
      Mu_Popup_Top --       popup at the top of the parent,
      Mu_Popup_Center --    popup at the center of the parent
                            (same as passing NULL),
      Mu_Popup_Pointer --   popup directly underneath the pointer,
      Mu_Popup_Previous --  popup at the same coordinates as the
                            last "management" of the dialog box
                            (therefore, if a user moves the dialog box
                            to a location on the screen different
                            from where it had popped up, that would be
                            the coordinates of the last "management"
                            of the dialog box),

      NULL -- if you want the default behavior, which is popping up in
               the center of the parent (same as Mu_Popup_Center).

   Note:  If there is not enough room on the screen for a dialog box to
   popup on top, bottom, left or right of the parent, then the dialog box
   will overlap the parent interface.  Also, if you specify
   Mu_Popup_Previous and the dialog box had never been managed before
   (i.e first time it's being called), it will popup in the upper left
   corner of the screen.

   Bug:  If you are using mwm, you may notice that the popup dialog box
         sometimes will not popup in the correct position. You may see
         this problem if you resize your application window after the
         dialog box had already been managed once.  This behavior may go
         away after a couple of popups.  Since this problem doesn't occur
         in uwm, it's probably an mwm quirk.  This bug will be corrected
         once we figure out what's going on.

 *****************************************************************************

              void MuRegisterWidget(string)  /* called from uil
                   and
               Widget MuGetWidget(string)    /* called from C

                  char *string;

These two functions were written so that you can get a widget id
without using XtNameToWidget() and without having to write a procedure
in your C file to take care of the create callbacks from uil.

You call MuRegisterWidget from uil, passing it a string (any name you
want to call it) which identifies the widget you want to know the 
widget id of in C.

               e.g. 
	 object textbox1 : XmText {
         	arguments { 
			XmNtopAttachment = XmATTACH_FORM;
                        XmNrightAttachment = XmATTACH_FORM;
                	XmNleftAttachment = XmATTACH_FORM;
                	};
        	 callbacks {
                	XmNcreateCallback = procedure MuRegisterWidget("box1");
                	};
       		  };

Then, in C you can get the widget id of the widget by calling
MuGetWidget, passing it the same string.  

                 e.g.

                        Widget w;
                
                        w = MuGetWidget("box1");

 ****************************************************************************

         void MuSetSensitive(string) /* to be used from UIL only */
               char *string;

MuSetSensitive is to be used from UIL only.  It sets a widget to be
sensitive (the widget should receive keyboard and pointer events) if
it's not currently sensitive, or it sets it to be insensitive
if it's currently sensitive.  This is useful if you want to make
some button insensitive or sensitive when a certain process is
called.  You pass it a string description of the widget that you had
registered with MuRegisterWidget.

          e.g.

         object button : XmPushButton {
         arguments {
                  XmNlabelString = compound_string('Does something');
                  };
         callbacks {
                 XmNcreateCallback = procedure MuRegisterWidget("p_button");
                 XmNactivateCallback = procedures {
                                          MuSetSensitive("p_button");
                                          Do_something();
                                       };
                 };
         };

In this example after the push button is activated, the button will
become insensitive, and the application will "Do_something()".

 *****************************************************************************

	void MuSetAppPath(path)
		char *path;
/*
 * Takes a path and sets the application defaults directory variable
 * XAPPLRESDIR to that path.  Assumes that the path passed in is
 * terminated by a /.
 */

This should be called before XtInitialize().

e.g.:
	MuSetAppPath("/some/path/name/");
	toplevel = XtInitialize("toplevel", "Appname", NULL, 0, &argc, argv);

 *****************************************************************************

	void MuSetUidPath(path)
		char *path;
/*
 * Takes a path and adds path/%N.uid to UIDPATH if it already exists,
 * or creates a new UIDPATH with that in it if it doesn't.  Assumes
 * that the path passed in is terminated by a /.
 */

This should be called before MrmOpenHierarchy().  The name-list passed
to MrmOpenHierarchy should NOT contain the ".uid" extension.

e.g.:
	MuSetPath("/some/path/name/");
	MrmOpenHierarchy((MrmCount) 1, "myapplication", NULL, &Hierarchy);

 *****************************************************************************

	int MuSetIconPixmap(w, path, file)
		Widget w;
		char *path;
		char *file;
/*
 * Takes a widget (the top-level widget of the application), a path
 * and a bitmap filename and installs the file as the icon pixmap for
 * the program.  Assumes that the path passed in is terminated by a /.
 * Returns MrmSUCCESS if it succeeds, MrmFAILURE otherwise.
 */

 *****************************************************************************

	void MuHelpFile(filename)
		char *filename;
/*
 *  This function takes a filename as its argument, stats the file to find
 *  it's length, malloc's enough space to hold the text, reads it in,
 *  then calls MuHelp with that string.
 */

 ************************ END ** END ** END ** END ***********************
