[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 34. 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.

## 34.1 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

    void 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 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.

### 34.1.1 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-and-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.

## 34.2 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`.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by Jens Thoms Toerring on January 5, 2014 using texi2html 1.82.