Home ProtocolsProtocols XAccXAcc XSSI protocolXSSI protocol

15.14 xFSL interface

GDOS, which for years suffered a shadowy existence on the Atari platform, has enjoyed rising popularity since the introduction of vector fonts at the latest. Ever more programs offer the possibility to use a font different from the system font for output (and partly also for input).

Now to be able to select a font, one needs a font-selector. And so that not every programmer had to concoct his own brew, and to obtain consistent operation, there grew a desire for a system extension that made a font-selector available to all programs - just like a file- selector.

The first program of this type was the 'UFSL' by Michael Thänitz. Via a cookie it makes available routines for calling a font-selector. This interface is already being used by a number of programs, and there are also further font-selectors that can be called via this interface.

Although one can now call a font-selector via the UFSL interface, it has already been subject to a number of - partly incompatible - alterations and extensions. That is why most programs today assume that they have only the original, simple UFSL interface available to them. The result is therefore that the extensions remain unused, and when a somewhat more powerful font-selector is required in a program, one is thrown back to having to write a new one specially for that program. In a somewhat exaggerated form there is presented here the idea of an external font-selector ad absurdum ...

Due to the 'wild growth' of the UFSL interface it seemed more sensible to draw a clear line under this and develop a completely new interface that is then also offered via a new cookie.

This text describes this new interface, which can not simply call a font-selector, but can also exert an influence on it in many ways.


15.14.1 About the xFSL interface

With the xFSL interface, the caller (i.e. the program that calls the font-selector) has appreciably more influence on the font-selector, its behaviour, and on the fonts offered for selection.

During the conception of the new interface, the attempt was made to pay regard to the capabilities of various programming languages (e.g. the avoidance of pointers to functions), and at the same time to be prepared for possible extensions of the interface.

The adaptation of a program to the xFSL interface should be a matter of a few minutes, specially as sample calls in various programming languages are provided. The conversion of special requests may require somewhat more effort, of course, but should not present an insoluble problem.

There follows a description of the xFSL cookie as well as the various xFSL calls and parameters ...


15.14.1.1 The xFSL cookie

If a font-selector is installed that supports the xFSL interface, then a cookie 'xFSL' exists whose value is a pointer to the following structure:

typedef struct
{
  unsigned long xfsl;       /* Magic 'xFSL'              */
  unsigned int  revision;   /* Interface revision        */
  unsigned long product;    /* Font-selector identifier  */
  unsigned int  version;    /* Font-selector version     */
  xFSL_INPUT    xfsl_input; /* Simplified call           */
  xFSL_INIT     xfsl_init;  /* Init call                 */
  xFSL_EVENT    xfsl_event; /* Event call                */
  xFSL_EXIT     xfsl_exit;  /* Exit call                 */
  xFSL_INFO     xfsl_info;  /* Info call                 */
} xFSL;

Die Komponenten der Struktur im einzelnen:

xfsl Here we have for safety's sake once more the ASCII character string 'xFSL' (= 0x7846534C in hexadecimal).
 
revision This is the revision number of the xFSL interface; at present it contains the value 4. If the interface should be extended in the future, one will find correspondingly higher values there.
 
product Here one finds the identifier for the actually installed font-selector. This entry is intended, however, only as additional information, and should not be evaluated by application programs that want to call the font-selector!
 
Identifiers used to date:
 

Identifier Font-selector
CLVN Calvino
FSEL FontSel
HUGO HuGo!

The identifier (like the following version number too) was only introduced for programs that want to output information about the installed font-selector (e.g. the program 'SysInfo').
 
version The version number of the installed font-selector as BCD number (e.g. hexadecimal 0x100 for Version 1.00). The same notes apply here as for the product field above.
 
xfsl_input This is the entry point for a simplified call of the font-selector. The font-selector then appears always as a modal dialog and most of the additional features of the xFSL interface can not be accessed.
 
xfsl_init, xfsl_event, xfsl_exit  These three functions together form the extended font-selector call. All of the new features can be accessed via them. The procedure corresponds to the display of a GEM dialog:
 
  1. Display font-selector (xfsl_init)
     

  2. Event handling in a loop until 'OK' or 'Cancel' has been selected (xfsl_event)
     

  3. Remove font-selector from the screen (xfsl_exit)
     

xfsl_info With this call one can inquire about some of the features of the installed font-selector, e.g. Drag&Drop support.
 

15.14.1.2 The simplified call (xfsl_input)

xfsl_input is the entry point for a simplified call. With it one can only call the font-selector as a modal dialog. In addition one can specify a heading, and restrict the type of fonts that the selector is to present for selection.

int xfsl_input (int           vdihandle,
                unsigned int  fontflags,
                const char   *headline,
                int          *id,
                int          *size
               );

The parameters in detail:

vdihandle Here you pass the handle of a virtual VDI workstation already opened by your program (if you want to set a font in your program, you have to open such a VDI workstation anyway). The font-selector then adopts the font just set on this workstation as the current font (provided it is actually offered for selection by fontflags).
 
Instead of a valid handle you can however just pass a NULL, in which case the font-selector will display the font that you pass in the parameters id and size.
 
If you pass a VDI workstation handle, then the selected font will also be simultaneously set on this workstation.
 
fontflags With the font-flags you can determine which fonts will actually be offered for selection.
 
headline Here you can specify a header that will then appear in the font-selector. If the header is missing (pass 0L), then a default text ('Font-selector', 'Fontauswahl' or similar) will be shown.
 
id In this variable the ID of the selected font will be returned (naturally only if a font was really selected). This font can now be set directly with the VDI function vst_font.
 
If you pass a NULL in vdihandle, then the font-selector will display the font specified in id.
 
size In this variable the size of the selected font in points will be returned (also only if a new font was really selected). If this is a bitmap font, then its size may be set with the VDI function vst_point. For vector fonts one should call the function vst_arbpt.
 
If you pass a NULL in vdihandle, then the font-selector will display the font specified in id in the size given in size.
 

Return values

xfsl_input returns a negative number if an error has arisen. A 0 is returned if 'Cancel' was selected. If a 1 is returned, then a new font was selected.

The return values are the same for all xFSL functions, and upwardly compatible to the return values of the UFSL.

15.14.1.3 The extended xFSL call

The extended xFSL call consists of three individual function calls:

xfsl_init Displays the font-selector on the screen. In addition the parameters are passed here.
 
xfsl_event This function is called repeatedly until a font has been selected in the font-selector, or 'Cancel' selected.
 
xfsl_exit Removes the font-selector from the screen again.
 

In C it can look like this, for instance:

xhandle = xfsl->xfsl_init (vdihandle, &xpar);
if (xhandle >= 0)
{
  do
  {
    ret = xfsl->xfsl_event (xhandle, 0L);
    if (ret == xFS_HELP)
      ...;  /* Call Help function  */
    else if (ret == xFS_POPUP)
      ...;  /* Handle popup       */
    else if (ret == xFS_EVENT)
      ...;  /* Handle AES event   */
  } while ((ret != xFS_OK) && (ret != xFS_STOP));
  xfsl->xfsl_exit (xhandle);
}

This splitting up into three has the advantage, amongst others, that the handling of the events (HELP button, popup, AES events) does not have to pass pointers to functions (which presents difficulties in some programming languages). Also the interface can be extended easily by furher events if these should ever become necessary.

15.14.1.3.1 xfsl_init

This call not only brings up the font-selector on the screen, it also determines which fonts are to be displayed, whether a user-popup is being used and several other things.

int xsfl_init (int       vdihandle,
               xFSL_PAR *xpar
              );

The two parameters mean:

vdihandle As for the simplified call, here you pass the handle of a virtual VDI workstation already opened by your program, or simply a NULL.
 
If you pass a valid workstation handle, then the font- selector will adopt the font current on this workstation and display it - provided fontflags (in the xFSL_PAR structure) actually makes it available for selection. If this is not the case, then the font-selector will choose a font from those available and display it.
 
If you pass a NULL as workstation handle, then the font from the PFONTINFO structure (to which a pointer in the xFSL_PAR structure points) will be adopted and displayed.
 
If you pass a VDI workstation handle, then the font selected on this workstation will also be set.
 
xpar This is a pointer (i.e. the address) of an xFSL_PAR structure that contains all further specifications for the font-selector.
 
Due to the large number of options, this structure has been given its own page.
 

The following applies again for the return codes of the function: A negative return value indicates an error. Positive values here have a slightly different meaning: A 0 means that the font-selector was opened (successfully) as a modal dialog. Any other positive values correspond to the window handle of the opened font-selector. This way you can register the font-selector window with an AV-server, for instance.

On success (return value larger or equal to 0) you should store the handle in a variable, as it will still be needed for the following calls (xfsl_event and xfsl_exit).

Note: If the font-selector is to be displayed as a window, but xfsl_init returns the error xFS_NO_WINDOW (no more windows available), then one should attempt to display the font-selector at least as a dialog (clear control-flag CC_WINDOW and call xfsl_init again).

Remember: The user wants a font-selector, not an error-message!

15.14.1.3.2 xfsl_event

When the font-selector has been initialized and brought to the screen, xfsl_event takes over the main work.

int xfsl_event (int    xhandle,
                EVENT *event
               );

The two parameters mean:

xhandle The handle of the font-selector, as returned by xfsl_init.
 
event Pointer to an EVENT structure, as used by Pure-C. In this structure the font-selector returns AES events that it could not process itself. In addition, you can also use the input parameters to tell the font-selector about which events are to be reported.
 
However, the pointer can also just be a NULL if you do not want to evaluate any (further) events. If the font-selector is to be operated as a window-dialog and the caller (i.e. your program) has some other windows open, then you have to evaluate the redraw messages at least!
 
Example: If you set the MU_MESAG flag in ev_mflags of evnt_multi, then the font-selector will return all the arriving AES messages that it cannot handle itself to the caller.
 
Note: It is also possible, or course, to receive timer events; but these should only be used sparingly and not be too short, as in that case the font-selector has to leave its own event loop each time. 250 ms might serve as the - non-binding - lower limit.
 

The possible return values of xfsl_event:

xFS_STOP The 'Cancel' button or (if present) the Closer of the window-dialog was selected in the font-selector.
 
If the CC_CLOSER control-flag is set and the Closer is clicked on, the PFONTINFO structure to which the pointer in the xFSL_PAR structure points nevertheless contains data about which font was last selected in the font- selector. Otherwise this information would not be preserved.
 
xFS_OK A font was chosen and 'OK' selected. The font that was selected is described in the PFONTINFO structure to which the pointer in the xFSL_PAR structure points. If a valid VDI handle was passed at xfsl_init, then this font will also be set immediately on this VDI workstation.
 
xFS_HELP The HELP button was selected (this can only occur if one has been provided, of course). It is up to the caller how it reacts to this. Normally help will be provided by the display of a Help page (or triggering such a display).
 
xFS_EVENT An AES event has occurred that the font-selector could not process (e.g. a Redraw message for another window). Exactly what this event was can be gathered from the ev_mwich field of the EVENT structure.
 
Desk accessories should not forget calling xfsl_exit on receipt of an AC_CLOSE message! The same applies for the AP_TERM message.
 
xFS_POPUP A change was made in the user-popup (if present). For the changed popup entry the FF_CHANGED bit is set in the fontflags element. The popup entry which was then selected, and on return to the font-selector will be the current one in the popup (at the next xfsl_event call), will lie in the sel_entry element of xFSL_PAR.
 
You now still have the option of making changes to the popup entries, for instance to alter the font-flags, or adopt the changed font in all other popup entries (in this way it is possible to use the popup for some other kind of information which may have nothing to do with the selected font). But the texts and the number of popup entries may not be changed!
 
other values: Other positive values should be ignored. It is possible that the interface will be extended by further return values (events).
 
Negative values indicate an error, the font-selector should then be aborted. But it is imperative that one still calls xfsl_exit beforehand!
 
15.14.1.3.3 xfsl_exit

With the xfsl_exit call the font-selector is removed from the screen again:

void xfsl_exit (int xhandle);

Here xhandle is again the handle of the font-selector, as returned by xfsl_init.

xfsl_exit must be called always when the use of the font-selector is to be ended, be it that a font was chosen or 'Cancel' was selected, or that xfsl_event reported an error. If already the xfsl_init call failed, then xfsl_exit may not be called (logical, since one has no valid handle).

The call of xfsl_exit should also not be forgotten on arrival of the AC_CLOSE and AP_TERM messages!

15.14.1.3.4 The info call (xfsl_info)

With this call one can inquire about some of the features of the installed font-selector:

long xfsl_info (void);

If the return value is positive, then the following flags represent the features that are present (negative return values are, as usual, error-messages):

Name Value Meaning
XF_SIZE 0x0001 Size changes possible
XF_COLOR 0x0002 Colour changes possible
XF_ATTR 0x0004 Attribute changes possible
XF_WIDTH 0x0008 Width changes possible
XF_KERN 0x0010 Kerning changes possible
XF_SKEW 0x0020 Slope/skew changes possible
XF_ALIGN 0x0040 Alignment changes possible
XF_ROTATION 0x0080 Text rotation possible
XF_FIX31 0x0100 fix31 support
XF_POPUP 0x0200 Popup support
XF_DRAGDROP 0x0400 Drag&Drop support
XF_MAPPING 0x0800 Understands mapping

Further features of the font-selector can be inquired indirectly via the control element of the xFSL_PAR structure: On a successful xfsl_init call, those control-flags that the font-selector does not know are cleared.

15.14.1.3.5 The VDI workstation in the xFSL interface

With the xfsl_input and xfsl_init calls one can pass the handle of a virtual VDI workstation already opened by the user in each case.

The further behaviour of the font-selector depends on whether one actually passes a workstation handle or just a NULL:

If one passes a valid handle, then the font-selector will try to ascertain the current font on the corresponding workstation and then - provided it matches the passed font-flags - to also set it and offer it for selection. If the current font does not match the fontflags setting (say if only vector fonts are to be offered but the current font is a bitmap font), then the font-selector will select a font from those on offer and present it as the current font.

If the user now selects a font and closes the font-selector with 'OK' then this font will also be set immediately on the passed workstation, so that the calling program no longer has to do this.

For this one should note that the font-selector also opens its own VDI workstation and uses this internally and for the selection of the fonts. Amongst other things it will also call vst_load_fonts for this workstation (provided a GDOS is installed). This can lead to some unexpected results if no vst_load_fonts has been called yet on the passed workstation and the user selects a font in the font-selector that only becomes available after a vst_load_fonts call!


Instead of a workstation handle however one can also simply pass a NULL. The font-selector will then ascertain the current font from the passed parameters (for a xfsl_input call) or from the xFSL_PAR structure (for a xfsl_init call).

The selected font will then (logically) only be returned in the parameters or the xFSL_PAR structure and the caller then has to set it him/herself.

15.14.1.3.6 The xFSL_PAR structure

With this structure you have extensive influence on the behaviour of the font-selector and the type of fonts displayed. Therefore the description of the options is somewhat on the long side ...

typedef struct
{
 int            par_size;    /* Size of xFSL_PAR structure     */
 int            pfi_size;    /* Size of PFONTINFO structure    */
 unsigned long  control;     /* Control-flags                  */
 const char    *headline;    /* Header, or 0L                  */
 const char    *example;     /* Sample text, or 0L             */
 const char    *helptext;    /* Text of the HELP button, or 0L */
 PFONTINFO     *font;        /* Pointer to Fontinfo structure  */
 unsigned int   fontflags;   /* Permitted font types           */
 const char    *poptext;     /* Text before the popup, or 0L   */
 int            num_entries; /* Number of entries (0..n)       */
 int            sel_entry;   /* Selected entry (0..n-1)        */
 xFSL_PENTRY   *popup;       /* Pointer to a popup, or 0L      */
 char          *helpinfo;    /* Pointer to Help-file/-page     */
} xFSL_PAR;

Despite the multitude of entries everything is really quite simple, the more so that the fields that you do not need, or whose meaning is not yet clear to you, can simply be filled with zeros, whereupon the font-selector will then assume sensible default values.

The fields in detail:

par_size This field may not be set to zero; here the size of the xFSL_PAR structure in bytes is entered, so that in C one can simply write:
 
xpar.par_size=sizeof(xFSL_PAR);

The size of the structure currently comprises 42 bytes. Should the structure be extended at some time, then the font-selector can recognize from the size specification whether it is dealing with the old or the new structure.
 
pfi_size This field too may not be zero; here one has to enter the size of the PFONTINFO structure, so in C:
 
xpar.pfi_size=sizeof(PFONTINFO);

The current size of the PFONTINFO structure comprises 38 bytes and might also be extended in the future.
 
control These are the so-called control-flags, with which the behaviour of the font-selector can be influenced (e.g. whether it is to appear as a window or a dialog).
 
These flags are described in greater detail in their dedicated section below.
 
headline This, as already familiar from the simplified call, is a pointer to a header line for the font-selector. If this is missing (headline contains 0L), then a default text header will inserted.
 
The length of the header should be within the limit set by UFSL (34 characters), though the font-selector will truncate longer headers if necessary.
 
example A pointer to a sample text. The font-selector displays an example of glyphs in the currently selected font making up a text that may be specified here. If this text is missing (i.e. example contains zero) then the font- selector will display a default text (e.g. the name of the current font in each case).
 
helptext This is the text for a button that can be displayed at bottom left of the font-selector. Normally one will want to display a button labelled 'HELP' (or 'HILFE'), which explains to the user the function of the font-selector, and what the selected font is to be used for.
 
If this text is missing (i.e. helptext contains zero), then no HELP button will be displayed and also xfsl_event will not return a value for xFS_HELP.
 
One should choose a short text (around 8 characters), though the font-selector will truncate longer texts if necessary.
 
font This is a pointer to a structure (PFONTINFO) which describes a font. The structure is used both for passing values to the font-selector as well as returning the selected font.
 
This structure too is described in greater detail in its dedicated section below.
 
fontflags These are once more the font-flags, familiar from the simplified call, with which you can influence the fonts available for selection.
 
poptext, num_entries, sel_entry, popup: With these four parameters an additional popup can be made to appear in the font- selector. Due to the manifold options there is again a dedicated section below for this.
 
If you do not want a popup, then simply set these four values to zero.
 
helpinfo This is a pure output parameter: If the HELP button was selected (provided it is present, see `helptext'), then one will find here a pointer to a filename of a Help-file and the name of a page to be displayed. The filename is specified without a path or extension, with the page name following directly after it, separated by a comma.
 
The string may only be read, but not altered!
 

If you do not want to display Help yourself with xFS_HELP then you can use the information to call up a help-system (e.g. ST-Guide).
 
Example: xfsl_event returns xFS_HELP, in helpinfo there is a pointer to the string:
 
fine,The finest font-selector of all time

From this one can create the following call for ST-Guide:
 
*:\fine.hyp The finest font-selector of all time

So one appends the extension for the relevant help-system to the filename and passes the post-comma portion as a page-name.
 

To stress once more: Fields that you do not require or do not yet understand can simply be set to zero at first. Exceptions are only:

15.14.1.3.7 The control-flags

With the control-flags one can influence the benaviour of the font- selector.

Name Value Meaning
CC_WINDOW 0x0001 Font-selector as a window
CC_APPMODAL 0x0002 Font-selector is application-modal
CC_FIX31 0x0004 All size specifications in 1/65536 point
CC_FAKESTYLE 0x0008 Simulate styles (only bitmap fonts)
CC_CLOSER 0x0010 Window with Closer, no OK button
CC_NOSIZE 0x0100 Do not alter size
CC_NOCOLOR 0x0200 Do not alter colour
CC_NOATTR 0x0400 Do not alter attributes
CC_NOWIDTH 0x0800 Do not alter width
CC_NOKERN 0x1000 Do not alter kerning
CC_NOSKEW 0x2000 Do not alter skewing
CC_NOALIGN 0x4000 Do not alter alignment
CC_NOROTATION 0x8000 Do not alter text rotation
CC_DFLTSIZE 0x10000 'Default' font size
CC_INVSTYLE 0x20000 'Inverse' attribute

The function of the individual flags should be clear already from the names and short descriptions. Here still a few notes:

Please note: Not all font-selectors support all of the control-flags! If a font-selector does not support a flag, then it will simply ignore it. On a successful(!) xfsl_init call, the font-selector will clear those flags in the control element of the xFSL_PAR structure that it does not understand.

15.14.1.3.8 The PFONTINFO structure

This structure describes a font. After calling the font-selector it contains the selected font. In addition these specifications are evaluated by the font-selector already at the call (and the described font displayed), if a zero is passed as the VDI handle.

typedef struct
{
 int          fontid;     /* ID of the font               */
 int          fonttype;   /* Type of font                 */
 char        *fontname;   /* Name of the font             */
 union fsize  fontsize;   /* Font size in pt or fix31     */
 union fsize  fontwidth;  /* Width in pt or fix31         */
 char         trackkern;  /* Track kerning                */
 char         pairkern;   /* Pair kerning                 */
 int          fontattr;   /* Attributes                   */
 int          fontskew;   /* Skew                         */
 int          fontcol;    /* Colour                       */
 int          backcol;    /* Text background colour       */
 int          halign;     /* Horizontal text alignment    */
 int          valign;     /* Vertical text alignment      */
 int          rotation;   /* Text rotation in 1/10 degree */
 int          validtype;  /* Type (V_CHAR_...) or mapping */
 int         *validchars; /* Valid characters, or  0L     */
} PFONTINFO;

The elements in detail:

fontid The ID of the font, as also returned by the VDI function vqt_name. The font ID is a non-zero number (so can also be negative).
 
fonttype The type of font, as used as of Speedo 5 or NVDI 3:
 
Name Value Font type
BITMAP_FONT 0x0001 Pixel
SPEEDO_FONT 0x0002 Speedo
TT_FONT 0x0004 TrueType
PFB_FONT 0x0008 Type-1 (Postscript)

These specification are currenly for information only, having no meaning for the font-selector. However, in the future it will be possible to set a font not just by its ID but also by its name, in which case the font type will be required as well.
 
The font type is also of interest when one wants to alter the size of the font: With bitmap fonts this is done with the VDI function vst_point, for all other types (vector fonts) with the function vst_arbpt.
 
fontname The name of the font, as returned by vqt_name (possibly one or more space characters were removed).
 
The caller itself must make enough space available for the font name, thus for 32 characters and a NULL-byte! If you do not require the font name, then you can also simply set the pointer to zero.
 
fontsize The size of the font in points (pt) or 1/65536 point (type 'fix31'):
 
union fsize
{
 int   size;    /* Font size in points        */
 fix31 size31;  /* Font size in 1/65536 point */
};

Which of these two statements is valid is controlled globally with the control-flag CC_FIX31.
 
fontwidth Width of the font in points (pt) or 1/65536 point (type (type 'fix31'):
 
union fsize
{
 int   size;    /* Font size in points        */
 fix31 size31;  /* Font size in 1/65536 point */
};

Which of these two statements is valid is controlled globally with the control-flag CC_FIX31.
 
The width can be set with the VDI functions vst_width in points and with vst_setsize in fix31.
 
trackkern This parameter specifies the type of track kerning for vst_kern. Valid values are:
 

Value Kerning
0 No kerning
1 Normal kerning
2 Tight kerning
3 Very tight kerning
pairkern With this parameter pair kerning can be switched on (0) or off (1), see vst_kern.
 
fontattr These are the font attributes (text effects), as also used by the VDI function vst_effects.
 
Calvino only uses this field if the CC_FAKESTYLE control-flag is set.
 
fontskew The slope or skew of the font in 1/10 degree, see vst_skew.
 
fontcol The colour of the font. The VDI colours are used, i.e. 0 = White, 1 = Black, etc. See vst_color.
 
backcol The background colour to the text. The VDI colours are used, i.e. 0 = White, 1 = Black etc. The setting of a text background colour is not supported directly by the VDI, so it is up to the caller whether and how this parameter is used.
 
halign With this one can specify the horizontal alignment of the text: The text is to be output ranged left, ranged right or centred.
 

Name Value Alignment
THA_LEFT 0 Ranged left
THA_CENTER 1 Centred
THA_RIGHT 2 Ranged right

These values correspond to the parameter for horizontal alignment for the VDI call vst_alignment.
 
valign With this one can specify the vertical aligment of the text: The text is to be output aligned to the top line or the bottom line, or (vertically) centred.
 

Name Value Alignment
TVA_BOTTOM 0 At the text bottom line
TVA_CENTER 1 Vertically centred
TVA_TOP 2 At the text top line

These values deliberately do not correspond to the parameter for vertical alignment with vst_alignment! Values used there ('Base line', 'Character cell bottom line') are hardly intuitive for the normal user and hence should not form part of the user interface (which they would be however for selections in the font-selector). The alignment therefore must be converted by the calling program to the 'correct' values.
 
rotation Text rotation in 1/10 degrees, as also used in the VDI function vst_rotation.
 

Still missing are the two parameters validtype and validchars:

Sometimes it is important to ensure that the font contains certain characters. There are two possibilities for this:

If validchars is zero, one can select with validtype one of the following four groups of characters:

Name Value Range Comment
V_CHAR_IND -1 - 'Doesn't matter'
V_CHAR_ASC -2 32-126 All printable ASCII characters
V_CHAR_PRT -3 32-255 All printable characters
V_CHAR_ALL -4 0-255 Really all characters

These four groups ought to cover the most common applications.

If both validtype and validchars are zero, then the font-selector will treat this as V_CHAR_IND; the same for othr invalid values in validtype.


Should the four groups not suffice at times, then one can instead also specify more precisely with validtype and validchars which characters are required:

validtype then contains a value for the character mapping to be used by GDOS (see vst_charmap and What's mapping?).
 
A free choice of mapping is only available with an appropriate GDOS (SpeedoGDOS or NVDI from Version 3 onwards). At present the following mappings are defined:
 

Name Value Meaning
MAP_DIRECT 0 Direct mapping
MAP_ASCII 1 ASCII mapping (default)

If the GDOS does not support mapping, then the font-selector will only accept MAP_ASCII; in that case all other mappings will be ignored and a test for the presence of given characters will not be performed.
 
validchars is a pointer to an array of integers (WORDs), with which one can specify which characters the font has to contain.
 
The array consists of a series of from-to pairs:
 
  • Two values following each other specify a range (from-to)
     

  • Individual characters are specified by doubling up
     

  • The end of the list is specified by a from-to pair in which the 'to' is smaller than the 'from'
     


Example: Only those fonts should be offered for selection that contain all printable ASCII characters as well as the German Umlauts:
 
xFSL_PAR xpar;
int chars[] = { ' ', ' ', /* ASCII 32..126 */
'ä','ä', 'ö','ö', 'ü','ü',
'Ä','Ä', 'Ö','Ö', 'Ü','Ü', 'ß','ß',
1,0 /* Ende der Liste */
};

xpar.font->validtype=MAP_ASCII;
xpar.font->validchars=chars;
 

Future GDOSes will probably support further mappings (BICS, Unicode, ...). Thanks to the coding used, the font-selector will also handle these correctly: The mapping is simply passed in validtype and then the presence of a character tested with validchars.

Note: The various possibilities available with the validtype and validchars parameters should be used sparingly and with some thought, as the required testing of the characters may - depending on the GDOS - take quite a lot of time.

15.14.1.3.9 The user-popup

For the user-defined popup (user-popup in short) the following fields exist in the xFSL_PAR structure:

poptext Pointer to a text that is to appear before the popup, or 0L. The font-selector is free to ignore this text.
 
num_entries Number of entries (i.e. lines) in popup. If there is a zero here than no popup will be displayed. One should not use more than 16 entries, even though some font- selectors may support more in some circumstances.
 
sel_entry The selected entry in the popup (count starts from 0). The font-selector stores the number of the selected popup entry here and reads out the value anew at each xfsl_event call. In this way you can also force the font-selector to activate the entry with number 5 instead of the selected number 3, for instance, (at xFS_POPUP the font-selector only reports which entry was selected, though this is only activated on jumping back into the font-selector).
 
popup This is a pointer to an array of xFSL_PENTRY elements as shown below. At the specified address there have to be exactly as many elements as were specified in num_entries.
 

An entry in the popup is built up as follows:

typedef struct
{
 char         *entry;      /* Text of the popup entry        */
 PFONTINFO    *fontinfo;   /* Pointer to Fontinfo structure  */
 unsigned int  fontflags;  /* Permitted font types           */
 long          funcflags;  /* Function-flags, only for HuGo! */
} xFSL_PENTRY;

The meaning of the elements of this structure should be clear from the preceding explanations. The function-flags correspond to the control- flags, apart from the flags that influence the global behaviour of the font-selector (CC_WINDOW etc.). These are ignored here.

Important: The pointer to the PFONTINFO structure may not be NULL!

If the text of an entry starts with a `-', then the relevant entry is disabled (displayed in light type and not selectable). This is mainly intended for separation lines between entries.


Application

In principle one can see three fields of use for the user-popup:

  1. Each popup entry sets the font for a given part of a program. So for example one could allow only non-proportional fonts in a given program window, no vector fonts in another one, and all fonts in a third.
     

  2. Each entry makes a given group of fonts available. For instance, if one frequently requires vector fonts, one could construct a popup with the entries 'Vector fonts only' and 'All fonts'.
     

  3. The popup however can be used also for something completely different. One could accommodate information here that though it has nothing to do with fonts, affects the window for which one wants to set a font. For instance, one could offer a choice of the way that inverse characters are to be displayed in a console window in the form of a popup having entries 'Inverse', 'Bold', 'Underlined' available for selection.
     
    If one wants to alienate the purpose of the popup in this way, then with the xFS_POPUP message one has to transfer the changed font (which can be recognized by the set FF_CHANGED flag) to all other popup entries, as otherwise the font that is displayed in the font-selector would change!
     

15.14.1.4 The font-flags

With the font-flags one can restrict the fonts offered for selection:

Name Value Meaning
FF_SYSTEM 0x0001 Show system font (additionally)
FF_MONOSPACED 0x0002 Show monospaced fonts
FF_PROPORTIONAL 0x0004 Show proportional fonts
FF_BITMAP 0x0008 Show bitmap fonts
FF_SPD 0x0010 Show Speedo fonts
FF_TTF 0x0020 Show TrueType fonts
FF_PFB 0x0040 Show Type-1 fonts
FF_CFN 0x0080 Show Calamus fonts (not implemented yet)
FF_VECTOR 0x00F0 Show all vector fonts
FF_ALL 0x00FE Show all fonts
FF_CHANGED 0x8000 Change made (only in the popup)

The values have been chosen in such a way that the individual flags may be OR'd with each other. So, for instance if one uses for the font-flags FF_MONOSPACED|FF_VECTOR, then only non-proportional vector fonts will be offered for selection.

In addition the following applies:

15.14.1.5 xFSL return codes

All xFSL calls return consistent return codes (return values). A negative number represents an error, a positive number (or zero) means success or an event.

Name Value Meaning
xFS_PARERROR -9 Parameter error, e.g. call after Rev. 3
xFS_LOADERROR -8 Error when loading an xFSL module
xFS_RES_ERROR -7 Resolution too low (minimum 640x400 pixels)
xFS_NO_HANDLE -6 No VDI handle free
xFS_NO_WINDOW -5 No window(handle) free
xFS_NO_FONTS -4 No fonts loaded
xFS_NO_FONTSIZE -3 Font size not identifiable
xFS_ACTIVE -2 Font-selector is active already
xFS_ERROR -1 General error (memory shortage or similar)
xFS_STOP 0 [Cancel] button selected
xFS_OK 1 [OK] button selected
xFS_HELP 2 [Help] button selected
xFS_EVENT 3 AES event occurred
xFS_POPUP 4 Changes to user-popup

These values were chosen to be upwardly compatible to the UFSL font- selector (this knows the return codes -4, -3, -2, -1, 0 and 1).

In addition, GEMDOS error messages (values smaller or equal to -32) can occur; in particular, xfsl_init can also return the value EINVFN (-32) if the font-selector does not support the extended call.

With the xfsl_init call, positive return values correspond to the font-selector's window handle (0 means that the font-selector was opened as a modal dialog).

It is possible that the list of return codes will be extended in the future for further errors (values smaller than -9) or events (values greater that 4). This should be respected during the design of the program: Unknown errors should lead to an abort, unknown events should be ignored.

15.14.1.6 The Pure-C event structure

The GEM library of Pure-C uses a special structure in which the parameters of the AES function evnt_multi are coalesced. This structure is also used by xfsl_event.

typedef struct /* Special type for EventMulti */
{
 /* Input parameters */
 int ev_mflags,
     ev_mbclicks, ev_bmask, ev_mbstate,
     ev_mm1flags, ev_mm1x, ev_mm1y, ev_mm1width, ev_mm1height,
     ev_mm2flags, ev_mm2x, ev_mm2y, ev_mm2width, ev_mm2height,
     ev_mtlocount, ev_mthicount;

 /* Output parameters */
 int ev_mwich,
     ev_mmox, ev_mmoy, ev_mmobutton, ev_mmokstate,
     ev_mkreturn, ev_mbreturn;

 /* Message-Buffer */
 int ev_mmgpbuf[8];
} EVENT;

The elements of the structure correspond to those of the evnt_multi call. The order of the parameters too - apart from a few exceptions - is identical. The field ev_mwich contains the occurred events in the same coding as ev_mflags in evnt_multi.

15.14.2 xFSL tips and notes

In the following sections an attempt is made to give some tips and notes for the xFSL interface.

15.14.2.1 A simple xFSL call

In view of the multitude of parameters and setting options, the following note seems appropriate:

Don't panic!

An xFSL call is simpler than it appears at first. In particular one can adopt here the strategy of 'step-by-step refinement', since one can set (almost) all parameters to zero at first.

A possible simple xFSL call can look like this, for instance:

#include <stdio.h>
#include <aes.h>
#include <vdi.h>
#include <xfsl.h>

void call_xfsl (void)
{
  int xhandle, xret;
  xFSL_PAR xpar;
  PFONTINFO pfont;
  xFSL *xfsl;

  memset (&xpar, 0, sizeof (xFSL_PAR));
  memset (&pfont, 0, sizeof (PFONTINFO));

  xpar.par_size = sizeof (xFSL_PAR);
  xpar.pfi_size = sizeof (PFONTINFO);
  xpar.font = &pfont;
  xpar.font->fontcol = BLACK;

  if (get_cookie ('xFSL', &xfsl))
  {
    xhandle = xfsl->xfsl_init (0, &xpar);
    if (xhandle >= 0)
    {
     do
       xret = xfsl->xfsl_event (xhandle, 0L);
     while (xret > xFS_OK);
     xfsl->xfsl_exit (xhandle);
     if (xret == xFS_STOP)
       printf ("Cancel\n");
     else if (xret == xFS_OK)
       printf ("Font with ID %d selected\n", xpar.font->fontid);
     else if (xret < 0)
       printf ("Error %d\n", xret);
   }
   else
     printf ("Error %d\n", xhandle);
  }
  else
    printf ("Cookie not found!\n");
}

With the two memset calls all elements of the structures xFSL_PAR and PFONTINFO are set to zero. Subsequently some absolutely necessary values are entered:

MNo further preparation is required, and now the actual call follows. First the xFSL cookie is searched for and on success the font-selector will be initialized by passing the xFSL_PAR structure. If this call was successful (xhandle is greater or equal to zero), then the font-selector is already on the screen. In the main loop one now waits until the font-selector is terminated either with xFS_STOP or xFS_OK by the user, or until an error occurs (other positive return values are simply ignored here). With the call of xfsl_exit the font-selector is removed from the screen once more and subsequently the return value is evaluated.

That wasn't too complicated, was it? From here on you can now continue experimenting with various parameters and flags.

15.14.2.2 xFSL Questions and Answers

How can I find out which features the font-selector offers?

Directly, this can be done for some features by using the function xfsl_info. Indirectly, further features can be inquired for with the control field in the xFSL_PAR structure: After a successful xfsl_init call the font-selector will clear those control-flags that it does not understand.

How should my program behave when it realizes that the font-selector does not support the desired feature?

If some kind of font-selector is installed, then it also ought to be used in any case. Depending on how important the missing feature is, your program could look for alternatives (e.g. via the Font protocol) or attempt to compensate for the missing feature.

Once again: The user wanted a font-selector, not an error-message! If the missing feature can be compensated for only with difficulty, then you should inform the user once(!) with a corresponding note, but call up the font-selector nevertheless. Even if the selection can then not be made with the desired convenience, it is still far less frustrating for the user than not being able to select a font at all.

Some examples: If the popup is to be used to set the font for a given program window, then if the popup is missing the font should be set for the topped window of the program. If the font-selector does not support the locking of size-changes, then the returned size should simply be ignored and - if it differs from the desired size - the user informed about this by a note.

Incidentally, one should not rely on the font-selector supporting the same features the next time it is called! The font-selectors that work with an overlay (XFSL.OVL) can be substituted at any time without a Reset by re-copying the overlay.

What's all this 'mapping' about?

Vector fonts generally contain more than the familiar 256 characters, and furthermore they are not normally in the accustomed ASCII coding (for example the space character may lie at position 0 instead of 32). Therefore the pertinent characters of the font are 'mapped' to the 'normal' 256 characters, so that the space character lies as usual in position 32, no matter what position it has within the font. This is designated as 'ASCII mapping'.

The ASCII mapping is active by default, but due to this one cannot access the characters that lie outside the ASCII character set. Hence a second mapping, 'Direct mapping', is available. Here one has access to all characters of a font. However, for this one also has to know what type of font one is dealing with and how many characters the font contains: Speedo fonts usually have 564 characters, TrueType fonts can (theoretically) contain up to 65536 characters. One can get this information after switching to Direct mapping with the VDI function vqt_fontinfo:

int minADE, maxADE;

vst_charmap(handle,0); vqt_fontinfo(handle,&minADE,&maxADE,dumarray,&dummy,dumarray);

In minADE one gets the smallest, in maxADE the largest valid character index.

Direct mapping only has limited use for normal applications. Unlike ASCII mapping which provides consistent mapping for all types of fonts, one needs to know here exactly what kind of font one is dealing with. Thus, for instance, the Speedo symbol fonts have a different coding to the 'normal' Speedo fonts. This means that at position 64 of such a symbol font, say, one will not find the same character as for a 'normal' Speedo font.

Other mappings than ASCII are therefore of no interest to the majority of programs at present. But future GDOSes or equivalents may possibly also offer other consistent mappings (e.g. Unicode or BICS), where one can once more rely on the same character appearing always at a given position (similar to ASCII mapping but also including positions higher than 255).

Note: NVDI from NVDI 4 onwards is able to use Unicode mapping.

15.14.2.3 xFSL technical programming notes

The description of the xFSL interface in this text is effected in Pure-C. In the following sections the data-types and specifics of Pure-C are described in greater detail, so that xFSL calls succeed in other programming languages and C-dialects as well.

15.14.2.3.1 Data-types

The following data-types are used in this (part of the) text:

Name Size
int 16-bit signed
unsigned int 16-bit unsigned
long 32-bit signed
unsigned long 32-bit unsigned

The data-type 'char' is an (ASCII) character and is used here only as a pointer type, i.e. as a pointer to a C-string (series of characters terminated with a NULL-byte).


Union

A union corresponds to a variable record in Pascal. It is a structure whose individual elements lie 'on top of each other', i.e. occupy the same block of memory. Which element is valid at a given time depends on the context, or is left to the programmer.

Example: In the structure PFONTINFO a union `fsize' is used for the size specification:

union fsize
{
 int   size;    /* Font size in points        */
 fix31 size31;  /* Font size in 1/65536 point */
};

The memory requirement of this union comprises four bytes, as the type fix31 is four bytes long. One could now assign to the element size31 a size-specification in 1/65536 point and then read out the value in whole points from the element size - but this is not to be recommended, as in the conversion of fix31 to points one should always round off (see below).


fix31

The data-type fix31 is a fixed-point number, in which the upper 16 bits represent the signed pre-decimal point (whole number) portion, and the lower 16 bits the unsigned decimal portion. It is used only for the size specification and positioning of fonts, so that one can obtain a precision of 1/65536 point with it.

In the conversion of fix31 to points one must not forget rounding. To quote from the NVDI guide:

One may never, never, ever just cut off the decimal part!

15.14.2.3.2 xFSL parameter passing

The passing of parameters for all xFSL calls is done via the stack according to C-convention. This means that at the call the parameter lying furthest right is placed first on the stack, and the left-most parameter at the end, i.e. when jumping to the font-selector, lies at the top.

15.14.2.3.3 Pure-C and 'cdecl'

Pure-C normally passes the parameters to functions in registers. For passing via the stack one must either use the keyword 'cdecl' (as in the include file XFSL.H) or the compiler switch '-H' must be set.

The keyword 'cdecl' is a Pure-C-specific extension and so will issue a warning with compiler switch '-A' (ANSI-conform) set.

15.14.3 xFSL revisions history

Revision 4


Revision 3


Older revisions

15.14.4 UFSL/xFSL program overview

There follows an overview of all available font-selectors at this time that dispose of a UFSL or an xFSL interface (or both).

This is followed by a list of programs that use a font-selector with one or both of these interfaces.

15.14.4.1 Font-selector overview

A short overview of the currently existig font-selectors:

UFSL

by Michael Thänitz
This is the prototype of all external font-selectors. The last published version is 0.97, after which Michael unfortunately ceased its development. Thankfully however he has published the source texts.
 

FontSel

by Holger Weets and Christoph Zwerschke
A small but also rather spartan font-selector from Holger Weets, which from Version 1.02 has been developed further by Christoph Zwerschke. As of the Version 1.02 the xFSL interface is supported as well.
 

xUFSL

by Stefan Rogel
The xUFSL offers many additional features to the font-selectors named above. As these could not be accessed via the existing UFSL interface, Stefan has extended the interface. The design of the first version was, to put it carefully, 'controversial'. The last published Version: 1.05. The successor of the xUFSL is ...
 

HuGo

by Stefan Rogel
HuGo! is the successor of the xUFSL adapted to the xFSL interface (the UFSL interface is also still supported, but not the special extensions of the xUFSL to the UFSL interface). The name change was made to avoid confusion.
 

Calvino

by Dirk Haun
Together with HuGo! the first font-selector with a xFSL interface. Calvino too still supports the simple UFSL interface.
 

FONT_SEL und FONT_PAL

by Christian Grunenberg
These two programs work on a Drag&Drop basis, so they support neither the UFSL nor the xFSL interface, but instead support the Font protocol. FONT_SEL is a font-selector, FONT_PAL a font palette (with integrated font-selector).
 

15.14.4.2 Programs that support a font-selector

The following programs support an external font-selector (position at 16.08.1998, all specifications without guarantee):

Program Category Author UFSL xFSL
800XL-Deejay Drive emulator Kolja Koischwitz +
APP_List System utility Ralf Zimmermann +
Bellini Graphics program Ingo Dehne +
BibelST Bible software Reinhard Bartel +
Cat2Maus MausTausch Harald Sommerfeldt +
Chatwin Shell Dirk Haun +W +W
CyPress Text processor Rene Bartholomay +W
DB-Point Newsreader Michael Heng +
Disk Cake Disk utility Christoph Zwerschke + +
Egale File utility David Reitter + +
Everest Editor Oliver Schmidt +
Face Value App.builder/Lib Vegard Hofsoy - +
Floh FFile list utility Heiko Schaefer +
GEMAR Backup Steffen Engel +
GEM-Fontviewer Font displayer Reinhard Bartel + +
GEM-Plan Spreadsheet Reiner Rosin +W
Hitchcock System utility Thorsten Pohlmann +
IdeaList ASCII print program Christoph Bartholme +
Imagin Function plotter Reinhard Maier +
Jedi GAL-Assembler Ralf Zimmermann +
Kandinsky Drawing program Ulrich Rossgoderer +
MagiC!Conf MagiC utility Christian Ratsch +
MasterBrowse File viewer Michel Forget +
MenuInfo System utility Dirk Hagedorn +W
Okami Newsreader Wolfram Rösler +
Photo Line Image processor Gerhard Huber +
QED Editor Christian Felsch +
RoadRunner Car journey planner Andreas Schrell +W
SaugUtility Ditto Frank Rüger +
Schecks Business software Christian Lehmann +
ST-Guide Hypertext Holger Weets +
STJ-Oberon Programming language Stephan Junker + +
Texel Spreadsheet Thomas Much + +
UpToCASE CASE tool Michael Nolte +
VESAL Learning program Peter Klasen +
Zeig's mir File viewer Reiner Rosin + +W

(+: supported, W: as window-dialog)


15.14.5 The UFSL interface

For the sake of completeness, an English translation of the original description by Michael Thänitz of the original UFSL interface follows here :

Programming interface:

UFSL is a font-selector box for the AUTO folder. If offers a simple programming interface to the programmer via a cookie.

The cookie is called: 'UFSL'.
The cookie returns a pointer to the following structure:

 typedef struct
 {
  unsigned long  id;      /* UFSL ID (UFSL)       */
  unsigned int   version; /* Version (BCD format) */
  int dialtyp;            /* 0=Dialog, 1=Window   */
  int cdecl (*font_selinit)(void);
  int cdecl (*font_selinput)(
              int vdihandle,
              int dummy,
              char *text,    /* Custom text, max. 34 characters  */
              int ftype,     /* 1=Only monospaced fonts, 0=All   */
              int *fretid,   /* Set Font ID                      */
              int *fretsize  /* Set font size                    */
              );
  OBJECT *helpbutton;           /* Type: BOXTEXT                 */
  void cdecl (*helpfunc)(void); /* User-defined Help function    */

  /**** As of Version 0.91 ********************************************/
  char *examplestr;            /* Sample text for font display     */

  /**** As of Version 0.96 ********************************************/
  void cdecl (*msgfunc)(int event, int msgbuf[]);/* Redraw function */

  /**** As of Version 0.97 ********************************************/
  int cdecl (*fontsel_exinput)(
              int vdihandle,
              int ftype,     /* 1=Only monospaced fonts, 0=All     */
              char *text,    /* Custom text, masx. 34 characters   */
              int *fretid,   /* Set font ID                        */
              int *fretsize  /* Set font size                      */
              );
 } UFSL;

Call:

UFSL *ufsl;
ufsl=(UFSL *)get_cookie('UFSL');
ufsl->helpfunc= my_helpfunc;   /* Help function, or NULL */
ufsl->msgfunc = my_msghandler; /* Redraw function, or NULL,
                                  respect dialtyp       */
ufsl->fontsel_input(vdihandle,"Please select a font",0,&id,&size);
or
ufsl->fontsel_input(vdihandle,NULL,0,&id,&size);

Return codes:

 1 : All OK, values are valid
 0 : Cancel selected
-1 : Out of memory
-2 : Impermissible mutliple call
-3 : Font size could not be identified
-4 : Number of fonts must be greater than zero

Special functions:

void cdecl (*helpfunc)(void); /* User-defined Help function      */

UFSL can call a user-defined Help function via the equally optional HELP button. helpfunc requires no parameters and also has no return value.

void cdecl (*msgfunc)(int event, int msgbuf[]); /* Redraw function */

When using the UFSL as a window-dialog it is necessary to make a Redraw function available. It sends any received events back to the calling program, so that after moving the dialog one can restore the background windows. msgfunc returns the result of evnt_multi as the first parameter and the MsgPipe as the second parameter. A return code is not required. The calling program must make available all the required routines for window handling. wind_update(..._UPDATE) is not set by UFSL, so this is the duty of the calling user program. On principle (?) the memory protection of MultiTOS should be switched off.

Basically one should give some thought whether all events should be replied to appropriately. A WM_TOPPED, which tops other windows of the program, should not be answered, since UFSL naturally can only be applications modal as UFSL gyrates in its own form_do / evnt_multi.

15.14.6 Notes for authors of other font-selectors

Authors of other font-selectors are invited to have their program join the xFSL interface. In principle, every font-selector that uses a TSR concept can be furnished with the xFSL interface.

To prevent misunderstandings: The overlay technique and the reentrancy as offered by Calvino and HuGo! are not part of the actual interface and hence need not be supported by other font-selectors. Indeed the interface between the resident part ('shell') and the post-loaded part ('overlay') is also standardized and therefore can be used by other font-selectors as well. A description of this internal interface is available on request, see 'Contact addresses'.

Since a number of programs already support the old UFSL interface, it seems advisable to make this interface available in new font-selectors as well. However a quick look at these programs shows that they call the font-selector almost exclusively as a modal dialog. Thus the recommendation is to build in minimal UFSL support (as a modal dialog only) and instead implement the xFSL interface as widely as possible, since one can now expect that just those - now finally standardized - extensions will be used by programs rather than the UFSL interface.

A font-selector should offer the following additional features if possible:

The following conventions were agreed for an xFSL font-selector:


Home ProtocolsProtocols XAccXAcc XSSI protocolXSSI protocol