Next: , Previous: , 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:

OptionTypeMeaningDefault
-fldebug levelintPrint debug information0 (off)
-name appnamestringChange application namenone
-flversionPrint version of the library
-syncSynchronous X11 mode (debug)false
-display host:dpystringSet (remote) host$DISPLAY
-visual classstringTrueColor, PseudoColor...best
-depth depthintSet prefered visual depthbest
-vid idlongSet prefered visual ID0
-privateForce use of private colormapfalse
-sharedForce use of shared colormapfalse
-stdcmapForce use of standard colormapfalse
-doubleEnable double buffering for formsfalse
-bw widthintSet object border width1
-rgamma gammafloatSet red gamma1.0
-ggamma gammafloatSet green gamma1.0
-bgamma gammafloatSet blue gamma1.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:

StructureMask NameMeaning
typedef struct {
int debug;FL_PDDebugDebug level (0-5)
int depth;FL_PDDepthPreferred visual depth
int vclass;FL_PDVisualPrefered visual, TrueColor etc.
int doubleBuffer;FL_PDDoubleSimulate double buffering
int buttonFontSize;FL_PDButtonFontSizeDefault button label font size
int menuFontSize;FL_PDMenuFontSizeMenu label font size
int choiceFontSize;FL_PDChoiceFontSizeChoice label and choice text font size
int browserFontSize;FL_PDBrowserFontSizeBrowser label and text font size
int inputFontSize;FL_PDInputFontSizeInput label and text font size
int labelFontSize;FL_PDLabelFontSizeLabel font size for all other objects (box, pixmap etc.)
int pupFontSize;FL_PDPupFontSizeFont size for pop-ups
int privateColormap;FL_PDPrivateMapSelect private colormap if appropriate
int sharedColormap;FL_PDSharedMapForce use of shared colormap
int standardColormap;FL_PDStandardMapForce use of standard colormap
int scrollbarType;FL_PDScrollbarTypeScrollbar type to use for browser and input
int ulThickness;FL_PDULThicknessUnderline thickness
int ulPropWidth;FL_PDULPropWidthUnderline width, 0 for const. width fonts
int backingStore;FL_PDBSTurn BackingStore on or off
int coordUnit;FL_PDCoordUnitUnit of measure: pixel, mm, point
int borderWidth;FL_PDBorderWidthDefault 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: , Previous: , Up: Part V Overview of Main Functions   [Contents][Index]