Previous Page TOC Next Page

Character User Interface (FMLI and ETI)

Programming Tips and Known Problems

Programming Tips

Automatic Function Key Downloading


The FMLI interface relies heavily on the use of a terminal's keyboard function keys F1 through F8 but these keys are not available on some terminals or are not designed in a way that the System V terminfo(4) database can work with cleanly. To help in these situations, FMLI provides equivalent 2-character sequences to achieve the same effect: CTRL-f 1 though CTRL-f 8. Sometimes, however, new users of an FMLI application do not know about these equivalent character sequences, and are unable to use the screen-labeled function keys of the interface, a rather frustrating situation for such new users.

FMLI 4.0 provides a partial fix to this problem of new users, at a possible slight inconvenience to some experienced users, on some terminals. If a terminal, as defined in its terminfo entry, does not have default escape sequences for its function keys but can download strings into its function keys (this is the case, for example, on the AT&T 5620 and 630 terminals), then FMLI attempts to download the equivalent 2-character sequences into the function keys. This occurs, by default, when fmli if first invoked and each time that the user returns from any full-screen activity, such as those initiated with the run or unix-system commands. For terminals not fitting this description, no downloading is done.

NOTE: Referencing a terminfo entry for the AT&T 5620 Terminal from an old (pre-Release 4.0) terminfo database, will cause the FMLI default escape sequences for the function keys to be incorrectly downloaded. Not all escape sequences will be downloaded, and garbage may be output to the screen. This can occur if a user maintains a private variant of the terminfo entry. A user can set LOADPFK=NO in the environment to avoid this problem.

For new users this default behavior is helpful, but for an experienced user who has already placed other strings into the function keys, this is inconvenient, as the FMLI character sequences replace the user's own, and FMLI cannot restore the user's automatically.

Using the LOADPFK Environment Variable to Disable Downloading


The environment variable LOADPFK can be used to specify that this downloading not be done. Setting LOADPFK=NO in the environment before invoking fmli prevents this downloading from occurring, at any time.

Using a Shell Script to Restore Your Function Key Settings


Users who have entered strings in their function keys on this type of terminal may find a shell script to restore their stings useful; this script uses the tput utility to download function key strings:

Downloading FMLI Sequences More Efficiently


Even when the user wants the FMLI sequences downloaded, it is more efficient to do it only once if no program run from the FMLI application changes the function key settings (most programs do not); any possible delays required to download the sequences occur just once this way, instead of at the beginning of the application and every time a full-screen activity is run. This can be done using tput as above, but with the FMLI 2-character sequences; however, it is more easily done by the command sequence:


The first invocation of FMLI downloads the equivalent 2-character sequences. You then exit from that invocation and call it again, with LOADPFK=NO, to have your application run a little more efficiently.

Validation of Form Fields

Inter-dependent Field Validation


FMLI validates all fields that have not been navigated to when a form is saved (the SAVE SLK is pressed, causing the done descriptor to be evaluated). This is not always sufficient for inter-field validations. For example, assume two inter-related fields on a form. The first field that appears will not have the interfield validation specified since the validation cannot be done until the second field is set. This works fine for the case in which the first field and then the second field is set or if the second field is not set (it will be checked on saving). Putting a minimal validation on the first field handles the case where neither field is set before leaving. The problem occurs if the user enters the first around to the first field and re-sets it: the inter-field validation is not re-done so the fields may not be valid. The application developer must allow for this and code the done descriptor accordingly.

Using Global Variables Across Frames


Developers should be aware that information stored in FMLI variables via the set utility or the argument passing mechanism ($ARGn) may not be valid at the time it is used even if it was validated at the time it was set. This can occur when variables set from data in one frame are used in the processing activity of another frame. If the use of a variable containing invalid data could seriously corrupt or compromise the system it must be re-validated at the time it is used.

Developer-set variables are known to all frames in an FMLI session--there is no "frame scoping" of variables, no way to make a variable known only to the frame it is set in. This results in the classic programming issues around global variables.

Here are two scenarios that can result in the value of a variable no longer being valid.

Scenario 1

The done descriptor of Form.1 sets a variable set -1 FOO=$F1, the value of field one, and opens Form.1a. The user enters data in Form1 and presses the SAVE SLK; Form.1a opens and becomes the current frame. The user now changes her/his mind, navigates back to Form.1 and enters a new value in field one. If instead of pressing the SAVE SLK for Form.1 again, the user navigates to Form.1a, when the user saves Form.1a it will not know the value in Form.1 has changed and any action in Form.1a based on the value of FOO will be different from what the user expects. The user's error of not pressing SAVE after changing Form.1 will not be detected.

Scenario 2

The done descriptor of Form.1 opens Form.1a passing the value of $F1 as the first argument (as in open Form.1a $F1). Assume this value is a user ID that Form.1 validated. Now the user navigates to another menu and deletes the user, then navigates back to Form.1a. Now the value of ARG1 is not a valid user ID even thought Form.1 validated it.

Commands

Co-processing Functions

Forms


If a second, or subsequent page of a form is defined to be larger than can be displayed on the terminal being used, it is not displayed at all (e.g., if rows=25 is defined, and the terminal being used only has 24 rows available for display).

Menus


The table entries for the two cases when columns is specified and description is not imply that menu items are truncated to fit in the column size determined fro sC. Thus, the columns descriptor should not be specified for menus that are dynamically generated, when there is no way to guarantee that such a menu will not have truncated items.

Descriptors set?

Step 1

Step 2

Step 3

D

r

c

pC

pR

uC

uR

yes

no

no

not needed

not needed

1

min(10,nR)

yes

no

yes

"

"

1*

"

yes

yes

no

"

"

1

min(aR,nR,sR

yes

yes

yes

"

"

1*

"

no

no

no

_**

_**

_**

_**

no

no

yes

if sC > mC, 1; otherwise, sC***

((tI-1) mod pC)+1

if pR > aR, 1: otherwise, pC

if pR > aR, min (aR,10); otherwise, pR

no

yes

no

((tI-1) mod pR)+1t

min(aR,nR,sR)t

if pC>fC, 1; otherwise, pC

pR

no

yes

yes

if sC > mC, 1; otherwise, sC***

((tI-1) mod pC)+1

if pR> aR, 1; otherwise, pC

if pR>aR, min (aR,sR); otherwise, pRtt

Footnotes

*

columns descriptor is ignored

*

columns descriptor is ignored

**

the algorithm attempts to open a menu with a 3:1 aspect ratio of width to height

***

menu items are truncated if they are too long to fit; equal-width columns are kept after truncation.

+

step 1 and step 2 are reversed for this case (pR must be computed first)

++

rows descriptor is ignored

Legend

d

description descriptor

r

rows descriptor

c

columns descriptor

sR

(specified rows) the value coded with the rows descriptor

aR

(available rows) the number of rows that frames can occupy on the terminal screen

nR

(needed rows) the number of rows needed to open the menu--for single column menus this equals tI

pR

(probable rows) the number of rows needed to open the menu, as determined from the first (preliminary) calculations

uR

(used rows) the number of rows used to open the menu, after all steps are done

tI

(total items) the total number of menu items for the menu (the number of menu descriptors)

sC

(specified columns) the value coded with the columns descriptor

fC

(fittable columns) the number of columns that can fit on the screen, given the screen width and the length of the longest menu item; equals (screen Width-2) mod (maxItem Width+1); this is a "maximum" value--the maximum fittable columns

mC

(max columns) the maximum number of columns that could fit on the screen if each column were only 1 character wise; equals (screen Width-3) mod 2

pC

(probable columns) the number of columns needed to open the menu, as determined from the first (preliminary) calculations

uC

(used columns) the number of columns used to open the menu, after all steps are done

Text

Backquoted Expressions

Color

Message Line

Syntax

Miscellaneous

Known Problems

Initialization

Screen Appearance

Message Line

Command Line

Screen Labels for Function Keys

Forms

Multi-page forms

Form Field Validation

Horizontally Scrollable Form Fields

Other Form Problems

Text Frames

Commands


this disables it throughout the interface. There is no way to remove it from the Commands Menu and still leave it available for use in the application code itself.

Built-in Utilities

regex

readfile

Co-processing Utilities

if then else

Other Built-in Utility Problems

Descriptors

Interrupt Facility

Miscellaneous

Previous Page Page Top TOC Next Page