Initialization (XForms (Forms Library) - Version 1.2 (Rev. 4) A Graphical User Interface Toolkit for X)

Next: Creating Forms, Previous: Version Information, Up: Part V Overview of Main Functions [Contents][Index]

### 32.2 Initialization

The routine

    Display *fl_initialize(int *argc, char *argv[], const char *appclass,
                           XrmOptionDescList app_opt, int n_app_opt);

initializes the Forms Library and returns a pointer to the `Display` structure if a connection could be made, otherwise `NULL`. This function must be called before any other calls to the Forms Library (except `fl_set_defaults()` and a few other functions that alter some of the defaults of the library).

The meaning of the arguments is as follows

`argc, argv`

  Number and array of the command line arguments the application was started with. The application name is derived from `argv[0]` by stripping leading path names and trailing period and extension, if any. Due to the way the X resources (and command line argument parsing) work, the executable name should not contain a dot `.` or a star `*`.

`appclass`

  The application class name, which typically is the generic name for all instances of this application. If no meaningful class name exists, it is typically given (or converted to if non given) as the application name with the first letter capitalized (second if the first letter is an X).

`app_opt`

  Specifies how to parse the application-specific resources.

`n_app_opt`

  Number of entries in the option list.

The `fl_initialize()` function builds the resource database, calls the Xlib `XrmParseCommand()` function to parse the command line arguments and performs other per display initialization. After the creation of the database, it is associated with the display via `XrmSetDatabase()`, so the application can get at it if necessary.

All recognized options are removed from the argument list and their corresponding values set. The XForms library provides appropriate defaults for all options. The following are recognized by the library:

Option | Type | Meaning | Default
`-fldebug` level | int | Print debug information | 0 (off)
`-name` appname | string | Change application name | none
`-flversion` |  | Print version of the library |
`-sync` |  | Synchronous X11 mode (debug) | false
`-display` host:dpy | string | Set (remote) host | `$DISPLAY`
`-visual` class | string | TrueColor, PseudoColor... | best
`-depth` depth | int | Set prefered visual depth | best
`-vid` id | long | Set prefered visual ID | 0
`-private` |  | Force use of private colormap | false
`-shared` |  | Force use of shared colormap | false
`-stdcmap` |  | Force use of standard colormap | false
`-double` |  | Enable double buffering for forms | false
`-bw` width | int | Set object border width | 1
`-rgamma` gamma | float | Set red gamma | 1.0
`-ggamma` gamma | float | Set green gamma | 1.0
`-bgamma` gamma | float | Set blue gamma | 1.0

In the above table "best" means the visual that has the most colors, which may or may not be the server’s default. There is a special command option `-visual Default` that sets both the visual and depth to the X servers default. If a visual ID is requested, it overrides depth or visual if specified. The visual ID can also be requested programmatically (before `fl_initialize()` is called) via the function

    void fl_set_visualID(long id);

Note that all command line options can be abbreviated, thus if the application program uses single character options, they might clash with the built-ins. For example, if you use `-g` as a command line option to indicate geometry, it might not work as `-g` matches `-ggamma` in the absence of `-ggamma`. Thus you should avoid using single character command line options.

If the border width is set to a negative number, all objects appear to have a softer appearance. Older version of the library used a larger default for the border width of 3.

As mentioned the `fl_initialize()` function removes all the above listed values from the command line arguments, leaving you with a cleaned-up list. To get again at the complete list you can use the function

    char **fl_get_cmdline_args( int *arg_cnt );

returning a copy to the values from the original list and their number via the `arg_cnt` argument.

Depending on your application XForms defaults may or may not be appropriate. E.g., on machines capable of 24 bits visuals, Forms Library always selects the deeper 24 bits visual. If your application only uses a limited number of colors, it might be faster if a visual other than 24 bits is selected.

There are a couple of ways to override the default settings. You can provide an application specific resource database distributed with your program. The easiest way, however, is to set up your own program defaults programmatically without affecting the users’ ability to override them with command line options. For this, you can use the following routine before calling `fl_initialize()`:

    void fl_set_defaults(unsigned long mask, FL_IOPT *flopt);

In addition to setting a preferred visual, this function can also be used to set other program defaults, such as label font size, unit of measure for form sizes etc.

The following table lists the fields, masks and their meanings of `FL_IOPT`:

Structure | Mask Name | Meaning
--- | --- | ---
`typedef struct {` |  |
`int debug;` | `FL_PDDebug` | Debug level (0-5)
`int depth;` | `FL_PDDepth` | Preferred visual depth
`int vclass;` | `FL_PDVisual` | Prefered visual, `TrueColor` etc.
`int doubleBuffer;` | `FL_PDDouble` | Simulate double buffering
`int buttonFontSize;` | `FL_PDButtonFontSize` | Default button label font size
`int menuFontSize;` | `FL_PDMenuFontSize` | Menu label font size
`int choiceFontSize;` | `FL_PDChoiceFontSize` | Choice label and choice text font size
`int browserFontSize;` | `FL_PDBrowserFontSize` | Browser label and text font size
`int inputFontSize;` | `FL_PDInputFontSize` | Input label and text font size
`int labelFontSize;` | `FL_PDLabelFontSize` | Label font size for all other objects (box, pixmap etc.)
`int pupFontSize;` | `FL_PDPupFontSize` | Font size for pop-ups
`int privateColormap;` | `FL_PDPrivateMap` | Select private colormap if appropriate
`int sharedColormap;` | `FL_PDSharedMap` | Force use of shared colormap
`int standardColormap;` | `FL_PDStandardMap` | Force use of standard colormap
`int scrollbarType;` | `FL_PDScrollbarType` | Scrollbar type to use for browser and input
`int ulThickness;` | `FL_PDULThickness` | Underline thickness
`int ulPropWidth;` | `FL_PDULPropWidth` | Underline width, 0 for const. width fonts
`int backingStore;` | `FL_PDBS` | Turn BackingStore on or off
`int coordUnit;` | `FL_PDCoordUnit` | Unit of measure: pixel, mm, point
`int borderWidth;` | `FL_PDBorderWidth` | Default border width
`} FL IOPT;` |  |

A special visual designation, `FL_DefaultVisual` and a command line option equivalent, `-visual Default` are provided to set the program default to the server’s default visual class and depth.

If you set up your resource specifications to use class names instead of instance names, users can then list instance resources under an arbitrary name that is specified with the `-name` option.

Coordinate units can be in pixels, points (1/72 inch), mm (millimeters), cp (centi-point, i.e., 1/100 of a point) or cmm (centi-millimeter). The the type of unit in use can be queried or set via the functions

    int fl_get_coordunit(void);
    void fl_set_coordunit(int coordUnit);

`coordUnit` can have the following values: `FL_COORD_PIXEL`, `FL_COORD_POINT`, `FL_COORD_MM`, `FL_COORD_centiPOINT` and `FL_COORD_centiMM`.

The unit in use can be changed anytime, but typically you would do this prior to creating a form, presumably to make the size of the form screen resolution independent. The basic steps in doing this may look something like the following:

    int oldcoordUnit = fl_get_coordunit();
    fl_set_coordunit(FL_COORD_POINT);
    fl_bgn_form(...);    /* add more objects */
    fl_end_form();
    fl_set_coordunit(oldcoordunit);

Some of the defaults are "magic" in that their exact values depend on the context or platform. For example, the underline thickness by default is 1 for normal fonts and 2 for bold fonts.

There exists a convenience function to set the application default border width

    void fl_set_border_width(int border_width)

which is equivalent to

    FL_IOPT fl_cntl;
    fl_cntl.borderWidth = border_width;
    fl_set_defaults(FL_PDBorderWidth, &fl_cntl);

Typically this function, if used, should appear before `fl_initialize()` is called so the user has the option to override the default via resource or command line options.

The cirrent setting of the borderwidth can also tested via

    int fl_get_border_width(void);

To change the default scrollbar type (which is `THIN_SCROLLBAR`) used in browser and input object, the following convenience function can be used:

    void fl_set_scrollbar_type(int type);

where `type` can be one of the following

`FL_NORMAL_SCROLLBAR`

  Basic scrollbar

`FL_THIN_SCROLLBAR`

  Thin scrollbar

`FL_NICE_SCROLLBAR`

  Nice scrollbar

`FL_PLAIN_SCROLLBAR`

  Similar to thin scrollbar, but not as fancy

Setting the scrollbar type before calling `fl_initialize()` is equivalent to

    FL_IOPT fl_cntl;
    fl_cntl.scrollbarType = type;
    fl_set_defaults(FL_PDScrollbarType, &fl_cntl);

It is recommended that this function be used before `fl_initialize()` so the user has the option to override the default through application resources.

Prior to version 0.80 the origin of XForms’ coordinate system was at the lower left-hand corner of the form. The new Form Designer will convert the form definition file to the new coordinate system, i.e., with the origin at the upper left-hand corner, so no manual intervention is required. To help those who lost the `.fd` files or otherwise can’t use a newer version of `fdesign`, a compatibility function is provided

    void fl_flip_yorigin(void);

Note however that this function must be called prior to `fl_initialize()` and is a no-op after that.

If this function has been called functions like `fl_get_object_position()` or `fl_get_object_bbox()`, reporting an objects positions and bounding box, will return `y`-coordinates in the old-fashioned coordinate system with the origin at the left bottom corner of the form. Similarly, the functions for setting or changing an objects position (`fl_set_object_position()` and `fl_move_object()`) then expect to receive arguments for the `y`-coordinates in this system. The `y`-coordinate stored in the object itself (i.e., `obj->y`) is always for the normal coordinate system with the origin at the top left corner.

For proportional font, substituting tabs with spaces is not always appropriate because this most likely will fail to align text properly. Instead, a tab is treated as an absolute measure of distance, in pixels, and a tab stop will always end at multiples of this distance. Application program can adjust this distance by setting the tab stops using the following routine

    void fl_set_tabstop(const char *s);

where `s` is a string whose width in pixels is to be used as the tab length. The font used to calculate the width is the same font that is used to render the string in which the tab is embedded. The default `"aaaaaaaa"`, i.e., eight `'a'`s.

Before we proceed further, some comments about double buffering are in order. Since Xlib does not support double buffering, Forms Library simulates this functionality with pixmap bit-bliting. In practice, the effect is hardly distinguishable from double buffering and performance is on par with multi-buffering extensions (It is slower than drawing into a window directly on most workstations however). Bear in mind that a pixmap can be resource hungry, so use this option with discretion.

In addition to using double buffering throughout an application, it is also possible to use double buffering on a per-form or per-object basis by using the following routines:

    void fl_set_form_dblbuffer(FL_FORM *form, int yes_no);
    void fl_set_object_dblbuffer(FL_OBJECT *obj, int yes_no);

Currently double buffering for objects having a non-rectangular box might not work well. A nonrectangular box means that there are regions within the bounding box that should not be painted, which is not easily done without complex and expensive clipping and unacceptable inefficiency. XForms gets around this by painting these regions with the form’s backface color. In most cases, this should prove to be adequate. If needed, you can modify the background of the pixmap by changing `obj->dbl_background` after switching to double buffer.

Normally the Forms Library reports errors to `stderr`. This can be avoided or modified by registering an error handling function

    void fl_set_error_handler(void (*user_handler)(const char *where,
                                                   const char *fmt,...));

The library will call the `user_handler` function with a string indicating in which function an error occured and a formatting string (see `sprintf()`) followed by zero or more arguments. To restore the default handler, call the function again with `user_handler` set to `NULL`. You can call this function anytime and as many times as you wish.

You can also instruct the default message handler to log the error to a file instead of printing to `stderr`

    void fl_set_error_logfp(FILE *fp);

For example

    fl_set_error_logfp(fopen("/dev/null","w"));

redirects all error messages to `/dev/null`, effectively turning off the default error reporting to `stderr`.

In XForms versions older than 1.0.01 for some error messages, in addition to being printed to stderr, a dialog box were shown that requires actions from the user. This could be turned off and on with the function

    void fl_show_errors(int show);

where `show` indicates whether to show (1) or not show (0) the errors. With newer versions of the Forms Library this function has no effect.

The fonts used in all forms can be changed using the routines

    int fl_set_font_name(int n, const char *name);
    int fl_set_font_name_f(int n, const char *fmt, ,,,);

The first function just accepts a simple string while the second constructs the font name from a format string just as it’s used for `printf()` etc. and the following arguments. The first argument, `n`, must be a number between 0 and `FL_MAXFONTS-1`. The function returns `0` on success, `1` if called before proper initialization of the library and `-1` for either invalid arguments (`name` or the result of the expansion of the format string doesn’t name an available font, `n` negative or not less than `FL_MAXFONTS`). See Label Attributes and Fonts, for details. A redraw of all forms is required to actually see the change for visible forms.

Since the dimension of an object is typically given in pixels, depending on the server resolution and the font used, this can lead to unsatisfactory user interfaces. For example, a button designed to (just) contain a label in a 10 pt font on a 75 DPI monitor will have the label overflow the button on a 100 DPI monitor. This comes about because a character of a 10 pt font when rendered with `75 DPI` resolution may have 10 pixels while the same character in the same 10 pt font with 100 DPI resolution may have 14 pixels. Thus, when designing the interfaces, leave a few extra pixels for the object. Or use a resolution independent unit, such as point, or centi-point etc.

Using a resolution independent unit for the object size should solve the font problems, theoretically. In practice, this approach may still prove to be vulnerable. The reason is the discreteness of both the font resolution and the monitor/server resolutions. The standard X fonts only come in two discrete resolutions, 75 DPI and 100 DPI. Due to the variations in monitor resolutions, the theoretically identical sized font, say a 10 pt font, can vary in sizes (pixels) by up to 30%, depending on the server (rendering a font on a 80 DPI monitor will cause errors in sizes regardless if a 75 DPI or 100 DPI font is used.) This has not even taken into account the fact that a surprising number of systems have wrong font paths (e.g., a 90 DPI monitor using 75 DPI fonts etc.).

With the theoretical and practical problems associated with X fonts, it is not practical for XForms to hard-code default font resolution and it is not practical to use the resolution information obtained from the server either as information obtained from the server regarding monitor resolution is highly unreliable. Thus, XForms does not insist on using fonts with specific resolutions and instead it leaves the freedom to select the default fonts of appropriate resolutions to the system administrators.

Given all these uncertainties regarding fonts, as a workaround, XForms provides a function that can be used to adjust the object size dynamically according to the actual fonts loaded:

    double fl_adjust_form_size(FL_FORM *form);

This function works by computing the size (in pixels) of every object on the form that has an inside label and compares it to the size of the object. Scaling factors are computed for all object labels that don’t fit. The maximum scaling factor found is then used to scale the form so every object label fits inside the object. It will never shrink a form. The function returns the resulting scaling factor. In scaling the aspect ratio of the form is left unmodified and all object gravity specifications are ignored. Since this function is meant to compensate for font size and server display resolution variations, scaling is limited to 125% per invocation. The best place to use this function is right after the creation of the forms. If the forms are properly designed this function should be a no-op on the machine the forms were designed on. Form Designer has a special option `-compensate` and resource `compensate` to request the emission of this function automatically for every form created. It is likely that this will become the default once the usefulness of it has been established.

There is a similar function that works the same way, but on an object-by-object basis and further allows explicit margin specifications:

    void fl_fit_object_label(FL_OBJECT *obj, FL_Coord hm, FL_Coord vm);

where `hm` and `vm` are the horizontal and vertical margins to leave on each side of the object, respectively. This function works by computing the object labels size and comparing it to the object size. If the label does not fit inside the object with the given margin, the entire form the object is on is scaled so the object label fits. In scaling the form, all gravity specification is ignored but the aspect ratio of the form (and thus of all objects) is kept. This function will not shrink a form. You can use this function on as many objects as you choose. Of course the object has to have a label inside the object for this function to work.

All colors with indices smaller than `FL_FREE_COL1` are used (or can potentially be used) by the Forms Library. If you wish they can be changed using the following function prior to `fl_initialize()`:

    void fl_set_icm_color(FL_COLOR index, int r, int g, int b);

Using this function you can actually change all entries in the internal colormap (with `index` going up to `FL_MAX_COLORS-1`). You may also inspect the internal colormap using

    void fl_get_icm_color(FL_COLOR index, int *r, int *g, int *b);

In some situations Forms Library may modify some of the server defaults. All modified defaults are restored as early as possible by the main loop and in general, when the application exits, all server defaults are restored. The only exception is when exiting from a callback that is activated by shortcuts. Thus it is recommended that the cleanup routine `fl_finish()` is called prior to exiting an application or register it via `atexit()`.

    void fl_finish(void);

In addition to restoring all server defaults, `fl_finish()` also shuts down the connection and frees dynamically allocated memory.

Next: Creating Forms, Previous: Version Information, Up: Part V Overview of Main Functions [Contents][Index]