.NH 1 "XVFORMS LIBRARY"
.XS
\s12\*(SN  XVFORMS LIBRARY\s0
.XE
.sp 2
.NH 2 "INTRODUCTION TO THE XVFORMS LIBRARY"
.XS
      \*(SN  INTRODUCTION
.XE
.sp 2
.PP
\fIxvforms\fP is the Khoros Library which contains all routines to 
create and maintain graphical user interfaces (otherwise known as 
\fIforms\fP), with the exception of independent utilities found in 
the \fIxvutils\fP library. The \fIxvforms\fP library is always used 
in conjunction with the \fIxvutils\fP library, as applications using 
the \fIxvforms\fP graphical user interface will often use the utilities 
provided there for displaying pop-up error messages, warning messages, 
and the like.  Note that all these routines use the X Toolkit 
and/or the Athena Widget set.   Routines available include routines to 
initialize the display, create the forms, map the forms, run the forms, 
and others.  
.PP
Descriptions of the routines in the \fIxvforms\fP library available 
to the user are provided here so that the application programmer may 
gain a more thorough understanding of how an application in the Khoros 
system which uses a graphical user interface operates;  however, you should 
note that a skeleton driver for an application program, with correct calls 
to most of the routines described here can be generated by the \fBconductor\fP 
automatic code generation program.  Novice application programmers are 
encouraged to read the documentation on \fBconductor\fP, use the
\fBconductor\fP program to generate a driver for a simple application, 
and use the generated code to look at while reading this documentation 
(as opposed to attempting to use the descriptions here to create
a driver from scratch). 
.sp 2
ALL programs that utilize these routines MUST link against:
.sp
-lXaw -lXmu -lXt -lXext -lX11
.sp 2
ALL programs that utilize these routines MUST include the statement:
.sp
#include "xvforms.h"
.sp 3
.NH 2 " xvf_strcpy()"
.XS
      \*(SN   xvf_strcpy()
.XE
.sp
.LP
This routine is a more robust version of \fIstrcpy()\fP.  It will allocate
the necessary number of bytes for you, and return a pointer to the copy of
the string passed in.  Passing a NULL string will cause a segmentation fault.
Note that the application is responsible for freeing memory 
allocated by xvf_strcpy.
.sp
.LP
=====================================================================
.B
.sp
char *xvf_strcpy(string);
.sp
char *string;
.R
.sp 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP string: 10
The string to be copied.
.sp
.LP
=====================================================================
.sp 3
.NH 2 " xvf_strlen()"
.XS
      \*(SN   xvf_strlen()
.XE
.sp
.LP
This routine is a more robust version on \fIstrlen()\fP.  It returns the 
integer length of the string passed in; it will return 0 if the string passed 
in is NULL. 
.sp
.LP
=====================================================================
.B
.sp
int xvf_strlen(string);
.sp
char *string;
.R
.sp
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP string: 10
The string to which is to have its characters counted.
.sp
.LP
=====================================================================
.sp
.LP
\fIEXAMPLE:
.br
This example uses xvf_strcpy to make a copy of a string, and xvf_strlen to
get the length of the string.\fP
.sp
char *string;
.br
int  length;
.sp
string = xvf_strcpy("This is a test of xvf_strcpy");
.br
length = xvf_strlen(string);
.bp
.sp 3
.NH 2 " xvf_initialize()"
.XS
      \*(SN   xvf_initialize()
.XE
.sp
.LP
Does all necessary initializations in preparation for using the graphical user
interface.  Opens the workstation display for use with the X windowing system,
version 11, release 4, and returns a pointer to the \fIDisplay\fP structure
(see Xlib.h).  It also creates an application context for the user interface
to be created by \fIxvforms\fP and initializes various internal parameters.
This routine MUST be called before any other calls to the \fIxvforms\fP
library are made (excepting calls to \fIxvf_strcpy\fP and \fIxvf_strlen\fP).
.sp
.LP
=====================================================================
.B
.sp
Display *xvf_initialize(argc, argv, program_name)
.sp
unsigned int argc;
.br
char *argv[];
.br
char *program_name;
.R
.sp
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP argc: 10
The number of command line arguments
.sp
.IP argv:
The command line arguments
.sp
.IP program_name: 13
The name of the program, or argv[0]
.sp
.LP
=====================================================================
.sp
.LP
\fIEXAMPLE:
.br
This example uses xvf_initialize() to initialize the display and the forms \fP
.sp
/* these must be GLOBAL declarations */
.br
Display display;  /* Display is defined in Xlib.h */
.br
unsigned int ac;  /* copy of argc, used also by the vgparms library */
.br
unsigned int av;  /* copy of argv, used also by the vgparms library */
.br
char *program;    /* program name, or argv[0] */
.sp
program = xvf_strcpy(argv[0]);
.br
ac = argc;
.br
av = argv;
.sp
display = xvf_initialize(ac, av, program);
.br
if (display == NULL)            /* If an error on the open */
.br
{
.br
    mesg = xvf_strcpy("Could not open connection to server");
.br
    fprintf(stderr,"%s:\t%s.",program, mesg);
.br
    free(mesg);
.br
    exit(1);
.br
}
.bp
.sp 3
.NH 2 " xvf_create_form()"
.XS
      \*(SN   xvf_create_form()
.XE
.sp
.LP
Creates the internal abstract data structure that will be used for managing and
maintaining the graphical user interface for the application program; also
creates the physical representation of the graphical user interface through use
of the Athena Widget set. Both are based on the specification provided in
the user interface specification file passed in.  The pointer to the
\fIxvf_form\fP produced is returned for the application program to use with
later calls to other \fIxvform\fP routines.
.sp
.LP
=====================================================================
.B
.sp
xvf_form *xvf_create_form(filename, argv, argc,
.br
				glyph_type, callback_routine, x, y)
.sp
char *filename;
.br
char **argv;
.br
unsigned int argc;
.br
int glyph_type;
.br
void (* callback_routine)();
.br
int x, y;
.R
.sp 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 10
The name of the UIS file that describes the graphical
user interface (note that this file should be postfixed with ".pane" or 
".form"-- in general, when the UIS file is being used with an application 
program, the convention is to use the ".form" postfix).
.sp
.IP argv:
The command line arguments
.sp
.IP argc:
The number of command line arguments
.sp
.IP glyph_type:
Type of glyph to use with the form; it may be one of:
.IP
SIMPLE  - will create a simple glyph, like that used in \fIxprism\fP 
.IP
NONE - no glyph will be used
.sp
.IP callback_routine:
The callback routine (if any) to be executed when the form is activated
.sp
.IP x:
The x position (in pixels) of the initial location of the form, if manual
placement is not used. If manual placement is to be used, this value must
be (-1).
.sp
.IP y:
The y position (in pixels) of the initial location of the form, if manual
placement is not used.  If manual placement is to be used, this value must
be (-1).
.sp
.LP
=====================================================================
.bp
.sp
.LP
\fIEXAMPLE:
.br
Here is an example of how forms are created in an application program.  The
application will have manual placement, and no callback routine is to be
used with its forms. The user interface specification file (UIS file) for
our example is called, "our_program.form". Note that a previous call to
xvf_initialize() is assumed.\fP
.sp
char *uis_filename;
.br
char *uis_filepath;
.br
xvf_form *form;
.sp
uis_filename = xvf_strcpy("our_program.form");
.br
uis_filepath = xvf_strcpy("./");
.br
/* vfullpath is defined in the vgparms library*/
.br
uis_filename = vfullpath(uis_filename, uis_filepath, NULL); 
.sp
if (!(form = xvf_create_form(form_filename, argc, argv, SIMPLE, NULL, -1, -1)))
.br
      exit(1);
.br
.bp
.sp 3
.NH 2 " xvf_change_active()"
.XS
      \*(SN   xvf_change_active()
.XE
.sp
.LP
Allows the applications programmer to specify "turn on" or "turn off" a form.  
Should be called with \fIactive\fP = true (1) to map the forms after the 
call to xvf_create_form(), but before the call to xvf_run_wait().
During run-time, if the application needs to force a form to be unmapped, 
a call should be made to xvf_change_active() with \fIactive\fP = false.
.sp
.LP
=====================================================================
.B
.sp
xvf_change_active(form, active)
.sp
xvf_form *form;
.br
int      active;
.R
.sp
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP form: 10
The pointer to the \fIxvf_form\fP structure, returned by a previous
call to xvf_create_form(). \fP
.IP active:
Whether forms are to be active (mapped) or unactive (unmapped). Allowed values
are "True" (1), or "False" (0).
.sp
.LP
=====================================================================
.sp
.LP
\fIEXAMPLE:  
.br
This example shows the use of xvf_change_active() to map forms that have
already been initialized with xvf_initialize(), and created using 
xvf_create_form(). \fP
.sp
xvf_form *form;
.sp
xvf_change_active(form, true);
.bp
.sp 3
.NH 2 " xvf_run_form()"
.XS
      \*(SN   xvf_run_form()
.XE
.sp
.LP
This routine runs the graphical user interface.  It gets events and dispatches
them until some action by the user (e.g, a click on an action button, a <cr>
in a live selection, etc) indicates that software control is to be returned to
the application program.  It returns a pointer to the current \fIxvf_form\fP
structure (note that in a few very rare cases, an application may use more 
than one set of forms)
.sp
.LP
=====================================================================
.B
.sp
xvf_form *xvf_run_form()
.R
.sp
=====================================================================
.sp
.LP
\fIEXAMPLE:
.br
Here is an example of how xvf_run_form() is used to run the forms - note that
previous calls to xvf_initialize (to initialize the display and the forms), 
xvf_create_form (to create the form) and xvf_change_active (to map the forms)
are assumed. \fP
.sp
xvf_form *form;
.br
Master master; /* this is the structure generated by \fIconductor\fP */
.sp
/* loop until the user clicks on the "Quit" button */
.br
do
.br
{
.br
    /* run the graphical user interface */
.br
    form = xvf_run_form();
.br
    if (form == NULL) break;
.sp
    /* get information from the graphical user interface */
.br
    _xvf_get_form(form, &master);  /* this is code generated by \fIconductor\fP */
.sp 2
    /* 
.br
     * take appropriate action according to information in the \fImaster\fP structure 
.br
     */
.sp 2
     /* re-initialize values in the \fImaster\fP structure for next time */
.br
     xvf_clear_selections(form->db, form->line_num);
.sp
} while (!master.quit);
.bp
.sp 3
.NH 2 " xvf_change_unmap()"
.XS
      \*(SN   xvf_change_unmap()
.XE
.sp
.LP
This routine lets the applications programmer specify if the form is to be
unmapped when run_form_wait() is finished and control is returned to the
application program.
.sp
.LP
=====================================================================
.B
.sp
xvf_change_active(form, active)
.sp
xvf_form *form;
.br
int      active;
.R
.sp
=====================================================================
.sp
.LP
\fIEXAMPLE:
.br
Here is an example of how xvf_change_unmap is used to tell the forms to unmap
each time control is returned to the application program. \fP
.sp
xvf_form *form;
.br
int unmap = true;
.sp
xvf_change_unmap(form, unmap);
.bp
.sp 3
.NH 2 " xvf_change_input()"
.XS
      \*(SN   xvf_change_input()
.XE
.sp
.PP
Often, situations occur in which the functionality and/or user understanding
of the application program would be enhanced by the ability to change
the appearance of its graphical user interface while it is running.
The \fIxvforms\fP graphical user interface library provides a utility routine,
\fIxvf_change_input()\fP, that is meant specifically for this purpose.
For example, programs like \fBeditimage\fP and \fBxprism2\fP will change
the contents of selection widgets according to command line arguments.
This explanation of xvf_change_input() assumes that the reader is already 
familiar with the use of User Interface Specification (UIS), and has experience 
using the program \fIconductor\fP to generate initialization and extraction 
code for use with the \fIxvforms\fP library.  
.sp
.PP
Changing the physical appearance of the graphical user interface "on the fly"
can be useful in a variety of situations.  Some changes that the application
programmer may want to make to the graphical user interface during runtime
might include:
.sp
\(bu
changing the values displayed in the parameter boxes of integer, float,
or string selections.
.sp
\(bu
changing the title of a selection
.sp
\(bu
changing the title of a master form, subform, or pane
.sp
\(bu
changing the text displayed by "blank" selections (so that they may be
used to display current values, parameter settings, or other
pertinent information - this is the most commonly used)
.sp
\(bu
initiating deactivation or re-activation of a particular button or selection
depending on some other action by the user
.sp
\(bu
updating current paths in the input/output selections
.sp
\(bu
making certain selections optional depending on other input parameters
.sp
\(bu
automatically changing the subform that is currently displayed
.sp 2
.PP
For these and other reasons, the application programmer may want to
call \fIxvf_change_input()\fP to change the physical appearance of the
forms as a reaction to certain events initiated by the user.
.sp 2
.LP
=====================================================================
.B
.sp
int  xvf_change_input(formptr, index, change_code, string, max_strlen)
.br
xvf_form *formptr;
.br
int       index;
.br
int       change_code;
.br
char     *string;
.br
int       max_strlen;
.R
.bp
.sp
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP formptr: 10
this is the pointer to the form tree obtained by calling
\fIxvf_create_form()\fP.
.sp
.IP index:
When the Form Information structure is generated in "form_info.h"
by \fIconductor\fP, there will be generated many variables with "_index"
tacked onto the end of the variable name.  These variables are
initialized with the appropriate call to "_xvf_init_XXX()",
where XXX is the name provided at the end of the (-F) StartForm line
of the User Interface Specification.
.IP
Each  "xxx_index" variable is set to the line number of the database
line for which it was generated.  These variables are created & set
specifically generated for calls to \fIxvf_change_input()\fP, so that the
application program may change the physical appearance of
the forms during runtime. Here is the place to use them.
.sp
.IP change_code:
The "change_code" parameter is a flag to xvf_change_input, indicating
what change is to be made.  A list of the change codes follows:
.sp
\fIxvf_inputfile_chng:\fP Change input file string of an InputFile selection
.br
\fIxvf_outputfile_chng:\fP Change output file string of an OutputFile selection
.br
\fIxvf_intval_chng:\fP Change the displayed integer value of
an Integer selection
.br
\fIxvf_floatval_chng:\fP Change the displayed float value of a Float selection
.br
\fIxvf_stringval_chng:\fP Change the displayed string value of a String
selection
.br
\fIxvf_toggleval_chng:\fP Change the current value of a Toggle
.br
\fIxvf_logicalval_chng:\fP Change the displayed boolean value of a Logical
selection
.br
\fIxvf_activation_chng:\fP Cause activation or deactivation of any item
.br
\fIxvf_guide_chng:\fP Turn a GuideButton on/off, and switch the pane
that is currently displayed.
.br
\fIxvf_optsel_chng:\fP Only valid for optional selections -- turn
optional selection box on/off
.br
\fIxvf_title_chng:\fP Change the title of the item, which may be one of:
StartForm, StartSubForm, StartPane, StartGuide, GuideButton, SubformButton,
InputFile, OutputFile, Integer, Float, String, Logical, Toggle, MasterAction,
SubformAction, PaneAction, or Routine.
.sp
.IP string:
This is the string that will take the place of the displayed string,
the new label, or pathname, or parameter value.  If value to be changed is
an integer (as for booleans such as the 'activate' field), or a float
(as in the float value of a float selection) the string representation of
the integer or float should be passed in, (eg, "1" instead of 1, "0" 
instead of 0).
.sp
.IP max_strlen:
This argument is only used if the change_code is xvf_title_chng.  In this case,
the application program may specify the maximum number of characters
that the label will ever be, over the course of the run of the program. When
max_strlen is used with a change code of xvf_title_chng,
\fIxvf_change_input()\fP will make sure that the size of the widget containing
this label is always large enough to accommodate a string of size
\fImax_strlen\fP;  otherwise, the new label may be longer than will fit
inside the widget.
.IP
Note: passing in 0 for \fImax_strlen\fP causes the label to be made
just large enough for the first (original) label.  Future calls
to by the application program to \fIxvf_change_input()\fP may  cause
new labels to be truncated.  For this reason, it is recommended that the user
specify \fImax_strlen\fP as long enough to reasonably fit most expected
strings, but not so long as to have the widgets grow unnecessarily,
possibly obscuring other items on the pane.
.sp
.LP
=====================================================================
.sp
.LP
\fIEXAMPLE:
.br
Here is an example of how xvf_change_input() is used to change the default
value of a toggle from the first selection to the fifth selection.  Note
that previous calls to xvf_initialize(), xvf_create_form(), and 
xvf_change_active() are assumed.\fP
.sp
xvf_form *form,
.br
Master  master;  /* this is the structure generated by \fIconductor\fP */
.sp
/* change the currently highlighted toggle choice to the 5th toggle element */
.br
xvf_change_input(form, master.subform->pane->type_toggle_index,
.br
			xvf_toggleval_chng, "5", 0);
.sp
.PP
Note that the second argument is the "_index" variable generated for the "type"
toggle on a pane named "pane", on a subform named "subform", on a form named
"master", in the "form_info.h" file which is generated by conductor.  For more
information on this automatically generated structure, see the documentation
on \fIconductor\fP.
