Resources for Forms Library
***************************

Managing resources is an important part of programming with X. Typical X programs use extensive resource database/management to customize their appearances. With the help of the Form Designer there is little or no need to specify any resources for the default appearance of an application written using the Forms Library. Because of this, complete resource support is a somewhat low-priority task and currently only minimal support is available. Nevertheless, more complete and useful resource management system specific to the Forms Library can be implemented using the services provided by the XForms.

Current Support
===============

At the moment all built-in XForms resources have a top level class name XForm and a resource name xform. Because of this incomplete specification most of the current resources are "global", in the sense that they affect all form windows. Eventually all resources will be fully resolved, e.g., to specify attribute foo of form formName, the resource name can be appName.formName.foo instead of (the current incomplete) appName.xform.foo.

The argument app_opt passed to fl_initialize() is a table of structures listing your applications command line options. The structure is defined as follows

     typedef struct {
         char          * option;
         char          * specifier;
         XrmOptionKind   argKind;
         void          * value;
     } XrmOptionDescList, FL_CMD_OPT;

See XrmGetResource() for details.

After the initialization routine is called all command line arguments, both XForms built-in and application specific ones, are removed from argc and argv and parsed into a standard XResources database. To read your application specific options follow fl_initialize() with the following routine

     int fl_get_app_resources(FL_RESOURCE *resource, int nresources);

Here resource is a table containing application specific resources in the following format:

     typedef struct {
         char     * res_name;  /* resource name without application name */
         char     * res_class; /* resource class */
         FL_RTYPE   type;      /* C type of the variable */
         void     * var        /* variable that will hold the value */
         char     * defval;    /* default value in string form */
         int        nbytes;    /* buffer size for string var. */
     } FL_RESOURCE;

and the resource type FL_RTYPE type is one of the following

FL_SHORT
     for short variable

FL_BOOL
     for boolean variable (int)

FL_INT
     for int variable

FL_LONG
     for long variable

FL_FLOAT
     for float variable

FL_STRING
     for char[] variable

FL_NONE
     for variables not to be used (or not available)

Note that the variable for FL_BOOL must be of type int. It differs from FL_INT only in the way the resources are converted, not in the way their values are stored. A boolean variable is considered to be true (1) if any one of True, true, Yes, yes, On, on, or 1 is specified as its value. For string variables, the length for the destination buffer must be specified.

fl_get_app_resources() simply looks up all entries specified in the FL_RESOURCE structure in all databases after prefixing the resource name with the application name, which can be the new name introduced by the -name command line option.

Summarized below are the currently recognized Forms Library built-in resources:

Resource Name
Class
Type
Default values
rgamma
Gamma
float
1.0
ggamma
Gamma
float
1.0
bgamma
Gamma
float
1.0
visual
Visual
string
best
depth
Depth
int
best
doubleBuffer
DoubleBuffer
bool
true
privateColormap
PrivateColormap
bool
false
standardColormap
StandardColormap
bool
false
sharedColormap
SharedColormap
bool
false
pupFontSize
PupFontSize
int
12pt
buttonFontSize
FontSize
int
10pt
sliderFontSize
FontSize
int
10pt
inputFontSize
FontSize
int
10pt
browserFontSize
FontSize
int
10pt
menuFontSize
FontSize
int
10pt
choiceFontSize
FontSize
int
10pt
ulPropWidth
ULPropWidth
bool
true
ulThickness
ULThickness
int
1
scrollbarType
ScrollbarType
string
thin
coordUnit
CoordUnit
string
pixel
borderWidth
BorderWidth
int
1

Again, "best" means that the Forms Library by default selects a visual that has the most depth.

By default, resource files are read and merged in the order as suggested by X11 R5 as follows:

  * /usr/lib/X11/app-defaults/<AppClassName>

  * $XAPPRLESDIR/<AppClassName>

  * RESOURCE_MANAGER property as set using xrdb if RESOURCE_MANAGER is empty, ~/.Xdefaults

  * $XENVIRONMENT if $XENVIORONMENT is empty, ~/.Xdefaults-hostname

  * ommand line options

All options set via resources may not be the final values used because resource settings are applied at the time an object/form is created, thus any modifications after that override the resource settings. For example buttonLabelSize, if set, is applied at the time the button is created (fl_add_button()). Thus altering the size after the button is created via fl_set_object_lsize() overrides whatever is set by the resource database.

To run your application in PseudoColor with a depth of 8 and a thicker underline, specify the following resources

     appname*visual:      PseudoColor
     appname*depth:       8
     appname*ulThickness: 2

Since resources based on a form by form basis are yet to be implemented, there is no point specifying anything more specific although also appname.XForm.depth etc. would work correctly.

Resources Example
-----------------

Let us assume that you have an application named myapp and it accepts the options -foo level and -bar plus a filename. The proper way to initialize the Forms Library is as follows

     FL_CMD_OPT cmdopt[] = {
       {"-foo", "*.foo", XrmoptionSepArg, 0     },
       {"-bar", ".bar",  XrmoptionNoArg,  "True"}
     };

     int foolevel, ifbar;
     int deftrue;      /* can only be set thru resources */

     FL_resource res[] = {
       {"foo",     "FooCLASS", FL_INT,  &foolevel, "0"},
       {"bar",     "BarCLASS", FL_BOOL, &ifbar,    "0"},
       {"deftrue", "Whatever", FL_BOOL, &deftrue,  "1"}
     };

     int main(int argc, char *argv[]) {
         fl_initialize(&argc, argv ,"MyappClass", cmdopt, 2);
         fl_get_app_resources(res, 3);
         if (argc == 1)   /* missing filename */
             fprintf(stderr, "Usage %s: [-foo level][-bar] "
                     "filename\n","myapp");
         /* rest of the program */
     }

After this, both variables foolevel and ifbar are set either through resource files or command line options, with the command line options overriding those set in the resource files. In case neither the command line nor the resource files specified the options, the default value string is converted.

There is another routine, a resource routine of the lowest level in XForms, which might be useful if a quick&dirty option needs to be read:

     const char *fl_get_resource(const char *res_name,
                                 const char *res_class,
                                 FL_RTYPE type, char *defval,
                                 void *val, int nbytes);

res_name and res_class must be complete resource specifications (minus the application name) and should not contain wildcards of any kind. The resource will be converted according to the type and result stored in type, which is an integer of type FL_RTYPE. nbytes is used only if the resource type is FL_STRING. The function returns the string representation of the resource value. If a value of FL_NONE is passed for type the resource is not converted and the pointer val is not dereferenced.

There is also a routine that allows the application program to set resources programmatically:

     void fl_set_resource(const char *string, const char *value);

where string and value are a resource-value pair. The string can be a fully qualified resource name (minus the application name) or a resource class.

Routines fl_set_resource() and fl_get_resource() can be used to store and retrieve arbitrary strings and values and may be useful to pass data around.

Going Further
=============

It is possible to implement your own form/object specific resources management system using the services mentioned above. For example, to implement a user-configurable form size, code similar to the following can be used, assuming the form is named "myform":

     struct fsize {
         int width,
             height;
     } myformsize;

     FL_RESOURCE res[] = {
       {"myform.width", "XForm.width",  FL_INT, &myform.width,  "150"},
       {"myform.height","XForm.height", FL_INT, &myform.height, "150"}
     };

     fl_initialize(&argc, argv, app_class, 0, 0);
     fl_get_app_resources(res, 2);

     /* create the forms */

     myform = fl_bgn_form(myformsize.width, myformsize.height,.....);

Or (more realistically) you create the form first using fdesign and then scale it before it is shown:

     fl_initialize(&argc, argv, app_class, 0, 0);
     fl_get_app_resources(res, 2);

     /*create_all_forms here */

     fl_set_form_size(myform, mysformsize.width, myformsize.height);
     fl_show_form(myform, ...);

Since eventually form geometry and other things might be done via XForms internal routines it is recommended that you name your form to be the form title with all spaces removed and the first letter lower-cased, i.e., if a form is shown with a label Foo Bar, the name of the form should be fooBar.