Technical Capabilities
Having trouble finding what you need?
Get in touch with us, so we can answer your specific questions directly.
Get In Touch

VX/FMS – OpenVMS Forms Management

Overview

VX/FMS is a native reimplementation of DEC's OpenVMS Forms Management System (FMS) for Linux. It delivers the FDV$ Form Driver API, the FMS form language compiler, and the supporting form utilities as a linked C runtime, so migrated OpenVMS applications keep their existing FDV$ calls, .flg form sources, and character-cell terminal behaviour without source changes.

The runtime library links directly into the migrated program: its FDV$ calls resolve to Sector7's implementations with the same calling sequence and VMS status conventions as OpenVMS. Forms compile from .flg source to .fbn binary through the VX/FMS compiler, User Action Routines bind by name at link time, and screens render through direct VT and ANSI terminal control with no dependency on curses, termcap, or terminfo.

Architecture and components

VX/FMS is a linked runtime library plus a small set of command-line utilities, not a long-running server. The runtime is a C library that the migrated application links against directly, so the program's existing FDV$ calls resolve to Sector7's implementations with no server process to administer. The table maps each OpenVMS FMS component to its VX/FMS counterpart.

OpenVMS FMS componentVX/FMS artifactRoleStatus
FMS Form Driver (FDV$ shareable image)libfms.a / libfms.soRuntime the migrated application links; exposes the full FDV$ call surface.live
Form Language Translator (FMS$FLTR)fms_formCompiles .flg ASCII form source into .fbn binary form files.live
Screen-oriented form editor (FMS$FORM)fmseditInteractive .flg editor for VT and ANSI terminals.live
UAR binding (VMS image activator)fms_uarGenerates the User Action Routine name-to-function binding table to link into the application.live
Diagnostics and regression toolingfms_display / fms_dump / fms_compareHeadless render of a compiled form, escape-sequence dump, and render comparison against a captured reference.live
No runtime daemon. There is no forms server and no IPC substrate to configure. The compiled .fbn form library is opened on disk by the linked runtime at FDV$LOPEN time, and forms are pulled into memory individually with FDV$LOAD.

Call dispatch chain

Each public API name is a thin dispatcher. A call to FDV$DISP resolves through a link-time alias to an internal dispatcher, which wraps the call in the VX runtime trace/return convention and hands off to the routine implementation:

01 – AliasesPortable caller symbolsFDV$DISP, fdv$disp, and fdv$disp_ expose C upper-case, C lower-case, and Fortran trailing-underscore names for unchanged C, COBOL, and Fortran callers.
02 – Public dispatcherFDV_D_DISPAll three link-time aliases resolve to this single portable symbol.
03 – Runtime wrapperBegin, call, endThe wrappers apply tracing and the VMS return convention around the implementation call.
04 – ImplementationFCC_DISP()The display implementation performs the routine's actual work.

On an OpenVMS host, the dispatcher reads the caller's argument count and nulls out omitted optional parameters, preserving FMS's "optional trailing argument" semantics. On Linux the fixed prototype is used. The real work lives in the per-routine implementation files, which are complete implementations rather than stubs.

The FDV$ Form Driver API

VX/FMS implements the full FMS Form Driver call surface: 66 public FDV$ routines, each exported under the VMS dollar-sign name plus C lower-case and Fortran trailing-underscore aliases so existing object references resolve at link time. A migrated application links against libfms and its FDV$ calls run unchanged.

VMS calling convention

Every routine returns a VMS condition value by value: odd means success, even means failure. Arguments are passed by reference as VMS descriptors (32-bit, or 64-bit descriptors under an LP64 build), matching the original VMS calling convention. This is what lets unmodified VMS source relink against VX/FMS. The canonical success status is FDV$_SUC; callers test the low bit of the return value exactly as they did on OpenVMS.

Routine reference

The table below groups the most frequently called routines by role. It is a representative selection of the 66-routine FDV$ API; every routine listed is implemented in the runtime.

GroupRoutinesPurposeStatus
Terminal sessionFDV$ATERM, FDV$DTERM, FDV$STERM, FDV$FIX_SCREENAttach and detach the Form Driver session, set terminal characteristics, and re-sync the physical screen.live
WorkspaceFDV$AWKSP, FDV$SWKSP, FDV$DWKSPAllocate, select, and free a Form Driver workspace.live
Form libraryFDV$LOPEN, FDV$LOAD, FDV$LCLOSOpen a compiled form library, load a named form into memory, and close the library.live
DisplayFDV$DISP, FDV$DISPW, FDV$CDISP, FDV$CLEAR, FDV$RFRSHDisplay a form on the terminal, display at a workspace offset, clear, and refresh.live
Field input / outputFDV$GET, FDV$GETAL, FDV$PUT, FDV$PUTAL, FDV$PUTL, FDV$RET, FDV$RETALRead a single field or the whole form, write values into fields, and return field values with their terminators.live
Scrolled areasFDV$GETSC, FDV$PUTSCRead from and write to a scrolled (scrolling) region within a form.live
Named dataFDV$RETDN, FDV$RETDI, FDV$NDISPRetrieve named-data items by name or index, attached to a compiled form.live
Status and operatorFDV$STAT, FDV$SIGOP, FDV$BELL, FDV$RETLE, FDV$RETFNReturn Form Driver status and field metadata, signal the operator, and sound the terminal bell.live
KeyboardFDV$DFKBD, FDV$LEDON, FDV$LEDOFConfigure the keyboard and toggle keyboard LEDs.live

Real call path

A migrated program links this session sequence unchanged against libfms. The example uses a banking demo library and tests each status with the VMS success convention:

/* 1. Attach the terminal (open the Form Driver session) */
rc = fdv$aterm(&_tca, &val0, &val1, 0, 0, 0);
if (rc != FDV$_SUC) { /* report status text and exit */ }

/* 2. Allocate and select a workspace */
val0 = 2000;
rc = fdv$awksp(&_wksp1, &val0);
rc = fdv$swksp(&_wksp1);

/* 3. Open the compiled form library and load a form */
rc = fdv$lopen(_DESCR1("BANKING_FORMS"), &val0);
rc = fdv$load (_DESCR1("ACCOUNT_INQUIRY"));

/* 4. Display the form and read all fields (trm receives the terminator) */
rc = fdv$dispw(0);
rc = fdv$getal(&_val, &trm, 0, 0);

/* 5. Tear down */
fdv$dwksp(&_wksp1);
fdv$dterm(&_tca);

The equivalent portable C entry point is declared as extern "C" int fdv$get(...); and returns the condition value by value. The same routines are the ones the callable FMS$ Forms Management System API page documents in full detail.

The FMS form language

.flg is the ASCII form-description source the compiler reads. The VX/FMS compiler emits a binary form file with the .fbn extension, byte-compatible with the compiled forms FMS produced on OpenVMS. A library of compiled forms is opened at runtime with FDV$LOPEN, and individual forms are pulled with FDV$LOAD.

Statement keywords

The form language has ten top-level statement types:

StatementPurpose
FORMOpens a form definition (takes NAME=).
END_OF_FORMCloses a form definition (takes NAME=).
FIELDDefines an input or output field at a row and column.
TEXTPlaces literal text at a (row,col) position.
ATTRIBUTE_DEFAULTSSets default field and attribute values for the form.
NAMED_DATAAttaches named constant data to the form.
ORDERDefines the field navigation order.
SCROLLDeclares a scrolled region by line range.
DRAWLine-draw or ruling directive.
VIDEOVideo and display-attribute directive.

Statement items and attribute flags

Statement items take a =value; attribute flags are bare keywords, most with a NO... negation. The compiler recognises the full FMS keyword set:

NAME=
PICTURE=
DEFAULT=
HELP=
HELP_FORM=
WIDTH=
INDEX=
CHARACTER_SET=
CLEAR_CHARACTER=
BACKGROUND=
HIGHLIGHT=
DATA=
AREA_TO_CLEAR=
BEGIN_WITH= / END_WITH=
DATE_FIELD= / TIME_FIELD=
ACTION_ROUTINE=
FUNCTION_KEY_ACTION_ROUTINE=
PRE_HELP_ACTION_ROUTINE=
POST_HELP_ACTION_ROUTINE=
AUTOTAB / NOAUTOTAB
BOLD / NOBOLD
BLINKING / NOBLINKING
REVERSE / NOREVERSE
UNDERLINE / NOUNDERLINE
DISPLAY_ONLY / ECHO / NOECHO
MUST_FILL / RESPONSE_REQUIRED
LEFT_JUSTIFIED / RIGHT_JUSTIFIED
UPPERCASE / BLANK_FILL / ZERO_FILL
SUPERVISOR_ONLY / SUPPRESS

Date fields support MDY, DDMMMYY, MMDDYY, and DDMMYY pictures; time fields support HHMMSS and HHMMAMPM. PICTURE accepts either a literal mask (PICTURE='XXXXX-XXXX') or a count-prefixed form (PICTURE=40'X').

Example form source

A field with attribute defaults, a bound User Action Routine, a navigation order, and a help string. Comments begin with !; a statement ends with ;:

FORM NAME='ACCOUNT_INQUIRY'
    AREA_TO_CLEAR=1:23
    WIDTH=80
    BACKGROUND=CURRENT
    HIGHLIGHT=BOLD:UNDERLINE
    FUNCTION_KEY_ACTION_ROUTINE='FILTER_UAR'
    ;

TEXT (2,30) 'ACCOUNT INQUIRY' ;

ATTRIBUTE_DEFAULTS FIELD
    CLEAR_CHARACTER=' '
    NOAUTOTAB BLANK_FILL NOBOLD NOREVERSE ECHO
    LEFT_JUSTIFIED NOSUPERVISOR_ONLY NOUPPERCASE
    ;

FIELD NAME='POST_IT'  (22,64)
    PICTURE='X'
    HELP='Enter "Y" to post this transaction, "N" to abort'
    UPPERCASE
    ACTION_ROUTINE='POST_IT_UAR'
    RESPONSE_REQUIRED
    ;

ORDER BEGIN_WITH = 1
    NAME='ACCOUNT_NUMBER'
    NAME='POST_IT'
;

END_OF_FORM NAME='ACCOUNT_INQUIRY' ;

Scrolled regions are declared by line range, and a help form is linked with HELP_FORM='HELPTOPIC'. The RULE character set selects the VT line-drawing glyphs used for box borders:

SCROLL BEGIN_WITH=9  END_WITH=13 ;
SCROLL BEGIN_WITH=18 END_WITH=20 ;

User Action Routines

A User Action Routine (UAR) is a user-supplied C or C++ function bound to a form or field by name in the .flg source. VX/FMS supports all UAR scenarios that OpenVMS FMS does:

  • Field completion events, when the operator finishes entering a field.
  • Help requests raised by the terminal operator.
  • Function-key interactions, bound with FUNCTION_KEY_ACTION_ROUTINE=.
  • Pre-help and post-help hooks, bound with PRE_HELP_ACTION_ROUTINE= and POST_HELP_ACTION_ROUTINE=.
  • Screen refresh operations.

Binding and dispatch

A form binds a UAR by string name, for example ACTION_ROUTINE='POST_IT_UAR' or FUNCTION_KEY_ACTION_ROUTINE='FILTER_UAR'. At run time the Form Driver dispatches by name through a generated lookup table that pairs each UAR name with its function pointer:

/* generated binding table, linked into the application */
extern char *FMS_name_field[];        /* UAR names */
extern int (*FMS_ptr_field[])(void);  /* parallel function pointers */

int FMS_find_call_uar(char *name) {
    /* locate name in FMS_name_field[], then call the paired pointer */
    for (i = 0; strcmp(name, FMS_name_field[i]) && ... ; i++) ;
    return (*FMS_ptr_field[i])();     /* invoke the UAR */
}

The name-to-pointer table is produced by the fms_uar generator, which scans the application's UAR source and emits the binding table to link in. On OpenVMS the image activator resolved UARs by name at run time; on Linux there is no image activator, so the generator materialises the equivalent table at link time. This is also how VX/FMS extends the original FMS capability by allowing dynamic linking of external C++ functions as UARs, giving migrated forms more flexibility than the OpenVMS original.

No source rewrite for UAR logic. Existing UAR functions keep their names and signatures. The only new build step is running fms_uar to generate the binding table, which replaces the OpenVMS run-time name resolution.

Terminal handling

VX/FMS drives the terminal directly and emits raw VT and ANSI escape sequences. It does not depend on curses, termcap, or terminfo. This is a deliberate design choice: rendering the screen the same way OpenVMS FMS did preserves exact character-cell behaviour, cursor addressing, and video attributes, rather than approximating them through a Unix TUI layer.

Supported terminals

  • VT100, VT220, and all compatible VT-series terminals.
  • DECterm under DECwindows.
  • ANSI-compatible terminal emulators on Linux.

Display features preserved

FeatureBehaviour
132-character modeWide-screen (132-column) display, switched at runtime through the screen-width routine.
Double-size and double-widthThe DBLSIZ and DBLWID form attributes render as on VT terminals.
Line drawingThe RULE character set drives VT line-drawing glyphs for box borders and rules.
Video attributesBOLD, REVERSE, UNDERLINE, and BLINKING map to their SGR equivalents.
Scrolled regionsScrolling areas declared by line range in the form scroll and refresh correctly.

Because the runtime owns terminal I/O end to end, the diagnostic tools can capture and replay the exact escape stream: fms_dump writes a form render to an escape-sequence file, and fms_compare parses those escapes back to compare a Linux render against a captured reference render for regression testing.

Build and compile pipeline

The build produces the runtime library and the form utilities. Applications then compile their forms and generate the UAR binding table before linking against the library.

StepCommandInputOutput
Build the runtime librarymakeruntime C sourceslibfms.a / libfms.so
Build the utilitiesmake (utilities target)utility C sourcesfms_form, fms_uar, fms_display, fms_compare
Standalone variantmake standalonesame sourcesself-contained library and tools, independent of the wider VX/RT runtime
Compile a formfms_form <name>name.flgname.fbn
Edit a formfmsedit name.flg.flg.flg
Generate the UAR tablefms_uarapplication UAR sourcesname-to-pointer binding table to link in
Standalone or integrated. VX/FMS builds either as a self-contained library and toolset, or against the wider Sector7 runtime so it interoperates with VX/RT and other Sector7 migration components in the same estate.

The form compiler is a hand-written recursive-descent parser: it reads the .flg statement stream, keys on the statement keywords against the token table, and serialises the compiled form to the .fbn binary. Because the output format matches the OpenVMS compiled form, existing tooling that consumes .fbn libraries continues to work.

Feature and platform compatibility

VX/FMS retains the core capabilities of OpenVMS FMS so migrated applications keep their form behaviour, layout, and interactions. The matrix below lists each capability and its status in the runtime.

CapabilityStatus
FDV$ Form Driver API (66 routines)live
.flg to .fbn form compilerlive
User Action Routine name-to-pointer dispatch and generatorlive
Scrolled areas, named data, and overlapping formslive
132-column, double-size, and double-width displaylive
HELP forms with pre-help and post-help action routineslive
Direct VT and ANSI terminal I/O (no curses, termcap, or terminfo)live
fmsedit interactive form editorlive
Diagnostic and regression tooling (dump, display, compare)live

Platforms

The VX/FMS runtime is native on Linux, and the same sources build for other Unix platforms (macOS, HP-UX, and SCO) through build-time configuration. The library links directly into the migrated application, so the target platform is whatever the recompiled application targets.

100 percent FDV$ API compatibility. Every FDV$ routine an existing forms application calls is implemented with the same arguments and status conventions, so migration is a relink rather than a rewrite. This makes VX/FMS a drop-in path for OpenVMS FMS forms applications moving to Linux.

Quick reference

Session skeleton

The canonical Form Driver session lifecycle:

01Attach terminalFDV$ATERM
02Attach or select workspaceFDV$AWKSP or FDV$SWKSP
03Open libraryFDV$LOPEN
04Load formFDV$LOAD
05DisplayFDV$DISP or FDV$DISPW
06Read fieldsFDV$GET or FDV$GETAL
07Detach workspaceFDV$DWKSP
08Detach terminalFDV$DTERM

At a glance

ItemValue
Runtime librarylibfms.a / libfms.so, linked into the migrated application.
Public API66 FDV$ routines, dispatched to per-routine implementations.
Form languageSource .flg compiled to .fbn by fms_form.
Return conventionVMS condition value by value; odd is success, FDV$_SUC is success.
UARsBound by name in the .flg; dispatched through a table generated by fms_uar.
TerminalsVT100, VT220, DECterm, and ANSI emulators, driven by direct VT and ANSI escapes.
Utilitiesfms_form, fmsedit, fms_uar, fms_display, fms_dump, fms_compare.

Status codes

Form Driver routines return VMS-format 32-bit condition values, where odd values indicate success. Field-level input conditions (for example full field, no previous field, numeric required, or help available) are reported through the same status interface, and a workspace-item form of the status is available through FDV$STAT for programs that inspect completion detail.

Frequently Asked Questions

Curious about how Sector7 can facilitate your application migration? Explore our FAQs for expert insights.

How does VX/FMS support existing FMS applications?
VX/FMS translates FMS mask description language into binary runtime files, allowing applications to retain their original behavior, formatting, and user interactions on modern Linux platforms.
What are the key features of VX/FMS?
Key features of VX/FMS include:
  • 100% compatible FDV$ API implementation
  • Support for VT terminals and DECterm
  • User Action Routines (UARs) for interactive events
  • Full form compilation to binary runtime
How does VX/FMS integrate with other Sector7 tools?
VX/FMS works seamlessly with VX/RT APIs and other Sector7 migration tools to provide comprehensive OpenVMS compatibility on Linux platforms.
What terminal types does VX/FMS support?
VX/FMS supports VT100, VT220, DECterm, and ANSI-compatible terminal emulators for Linux, ensuring identical user interaction across platforms without relying on curses or termcap.
How does VX/FMS handle User Action Routines?
VX/FMS fully supports all UAR scenarios including field completion events, help requests, function key interactions, and screen refresh operations, maintaining original VMS FMS behavior.
What migration benefits does VX/FMS provide?
VX/FMS enables organizations to modernize their form-based applications while preserving existing user interfaces and workflows. This approach eliminates the need for costly UI rewrites and maintains user productivity during migration.
How can I get started with VX/FMS migration?
To learn more about VX/FMS and how it can streamline your OpenVMS forms migration to Linux, contact us for a detailed assessment and migration roadmap.
Which platforms does VX/FMS run on?

VX/FMS is a native reimplementation of DEC's OpenVMS Forms Management System for Linux. It reproduces the original FMS behaviour, formatting, and user interactions so migrated applications run without functional changes, and the same sources also build for other Unix platforms through build-time configuration.

Does my application code have to change to use VX/FMS?

No. VX/FMS implements the FDV$ APIs with the same arguments and status conventions as OpenVMS FMS, so existing applications that call the FDV$ interface keep their calling sequence unchanged. Migration is a relink rather than a rewrite.

What does the VX/FMS compiler do?

It translates the FMS mask description language (.flg source) into binary runtime form files (.fbn), the same compiled form output FMS produced on OpenVMS, so form logic, attributes, and layout are preserved and execute identically after migration.

Which terminals and emulators does VX/FMS support?

VX/FMS supports VT100, VT220, and all compatible VT-series terminals, DECterm under DECwindows, and ANSI-compatible terminal emulators on Linux, giving identical character-cell user interaction across platforms.

Does VX/FMS depend on curses, termcap, or terminfo?

No. The Form Driver renders FMS screens directly with VT and ANSI escape sequences and does not rely on curses, termcap, or terminfo. That is how it keeps exact compatibility with original VMS FMS display behaviour rather than approximating it through a Unix TUI layer.

What FMS features are preserved during migration?

Scrolled areas, named data, overlapping forms, 132-character wide-screen mode, VMS HELP forms, and User Action Routines are all supported, so the migrated environment retains the core capabilities of OpenVMS FMS.

What are User Action Routines (UARs) and how are they supported?

UARs are user-defined callback procedures triggered by form events. A form binds a UAR by name in the .flg source, and the Form Driver dispatches it at run time. VX/FMS supports all UAR scenarios, including field completion, operator help requests, function-key interactions, and screen refresh, and it also allows dynamic linking of external C++ functions for extra flexibility.

How does VX/FMS fit with the rest of the Sector7 toolset?

VX/FMS can run as a standalone product or integrate with VX/RT, Sector7's OpenVMS runtime environment on Linux, and it works alongside VX/RMS and other Sector7 migration tools so an entire OpenVMS forms application can move together.

Transform Your Legacy Software Today!

Get In Touch
Unlock the potential of your legacy software with our expert migration services.