Back to Contents


Front End Protocol

This page describes the Front End Protocol: the communication between the Runtime System and the Front End.


Definition of Front End Protocol

The purpose of the Front End Protocol is to synchronize the Abstract User Interface (AUI) Tree maintained by the Runtime System and the corresponding copy held by the Front End. For more details about these concepts, see the Dynamic User Interface.

The AUI Tree is used by the Front End to create graphical objects. The Front End and the Runtime System have the same version of the AUI Tree. This way, communications correspond to AUI Tree synchronization operations: on one hand the Front End sends modification requests to the Runtime System (also called Front End Events); on the other hand, the Runtime System analyses and validates Front End requests, performs some codes if required, and sends back modification orders.

The following schema describes typical communication between the Runtime System and the Front End:

  1. Initialization phase: The Runtime System sends the initial AUI Tree.
  2. The Front End builds the Graphical User Interface according to the AUI Tree.
  3. The Front End waits for a user interaction (mouse click, keyboard typing).
  4. When the user performs some interaction, the Front End sends Front End Events corresponding to the modifications made by the user.
  5. Front End Events are analyzed and validated by the runtime system.
  6. The Runtime System sends back the result of the Front End requests, by the way of AUI Tree Modifications Commands.
  7. When receiving these commands, the Front End modifies its version of the AUI Tree and updates the Graphical User Interface. It then waits for new user interactions (step 3).

String Literals

In the Front End Protocol, the type of all attributes is string. The value of the attributes follows the same rules as 4gl string literals:

Example:

01   { GroupBox 25 {  { text "this is a \"GroupBox\""} } {}}

Runtime System Commands

The Runtime System sends commands to the Front End in order to modify the User Interface. As discussed earlier, these commands are modifications of the AUI Tree. Modifications can be:

Syntax:

om command-id 
{ 
  [ { { appendNodeCommand | updateNodeCommand | removeNodeCommand } } ] [...]
}

Notes:

Warning: There is no verification made about this order. The communication wire is supposed to be reliable and the Runner and the Front End do not perform verification about lost commands.


Append Node Command

The an command adds one or several children and their attributes to a specified node. Several children (and sub-children) and can be added in the same an command. This command is sent by the Runtime System when there are new graphical objects to display, and to initialize communication.

Syntax:

  an parent-id new-node

Where new-node is :

  tagName new-id { [ attribute-list ] } { [ child-list ] } }

Where attribute-list is :

  { attribute-name "attribute-value" } [...]
Where children-list is :
  { new-node } [...]

Notes:

  1. parent-id identifies the existing node.
  2. tag-name identifies the type of the added child. The list of possible children for each node is defined in the AUI Tree.
  3. new-id is a unique id for the new node created.
  4. attribute-name is the name of the attribute of the node.
  5. attribute-value is the value of the attribute.

Example:

This example shows an an command that creates a Menu (a Menu node is added) :

01 an 0 Menu 356 { { active "1"} { text "MAIN"} { posY "0"} { selection "357"} }
02 {
03   { MenuAction 357 { { name "Option1"} { text "Option1"} { comment ""} } {}} 
04   { MenuAction 358 { { name "Flow"} { text "Flow"} { comment ""} } {}} 
05   { MenuAction 359 { { name "Window"} { text "Window"} { comment "OPEN WINDOW"} } {}} 
06   { MenuAction 360 { { name "Form"} { text "Form"} { comment "form: scroll, erase..."} } {}} 
07   { MenuAction 361 { { name "Dialog"} { text "Dialog"} { comment ""} } {}} 
08   { MenuAction 362 { { name "Display"} { text "Display"} { comment ""} } {}} 
09   { MenuAction 363 { { name "Options"} { text "Options"} { comment "OPTIONS"} } {}} 
10   { MenuAction 364 { { name "Exit"} { text "Exit"} { comment ""} } {}} 
11 }

Remove Node Command

The rn command removes a specific node. This command is used when graphical objects are no longer required and need to be removed from the User Interface.

Syntax:

  rn node-id

Notes:

  1. node-id identifies the existing node to be deleted

Example:

This example shows a rn command that removes a node from the AUI Tree; in this example, the node removed would be a MenuAction node created by the an command in the previous example.

01 rn 357

Update Node Command

The un command modifies some attributes of a specific node. This command is used to modify the aspect of a widget, for example to validate the value entered by a user in a form field. This command is also used to confirm a focus change, modifying the focus attribute of the UserInterface node.

Syntax:

  un node-id { [ attribute-list ] }

Where attribute-list is :

  { attribute-name "attribute-value" } [...]

Notes:

  1. node-id identifies the modified node.
  2. attribute-name is the name of the attribute of the node.
  3. attribute-value is the value of the attribute.

Example:

This example shows an un command confirming a focus change: the focus now goes to the Menu option identified by id "358", created by the an command described in the example below. The UserInterface node has always an id equal to 0 (zero).

01 un 0 { focus "358" }

Front End Events

The Front End sends "modification requests" represented as "Front End Events" to the Runtime system. A group of modification requests can be sent in the same event _om command.

These events can be:

A very basic Front End needs only to handle KeyEvent events, and can send all keys pressed by the user to the Runtime System. For performance and more enhancements, most of the key pressed events are handled locally by the Front End. Only the keys mentioned above are sent. 

Syntax:

event _om command-id {} 
{ 
  { { ConfigureEvent 0 { { idRef "object-id" } attribute-list  } }
  | { KeyEvent 0 { { keyName "key-value" } } }
  | { ActionEvent 0 { { idRef  "object-id" } } }
  | { FunctionCallEvent 0 { { result "result-value" } } }
  | { DestroyEvent 0 { { status "status-value" } { message "message-value" } } }
  } [...]
}
Where attribute-list is :
{ attribute-name "attribute-value" } [...]

Notes:

  1. command-id is the number of the event. This number is increased automatically for each event _om command sent by the Front End to Runtime System. 
  2. object-id is the id of the node which is concerned by the event. Typically, this is the id of the object which has been changed by the user, such as a form field.
  3. attribute-name is the name of the attribute of the node.
  4. attribute-value is the value of the attribute.
  5. key-value is the value of the key pressed.
  6. result-value is the value returned by the local function, after it completes execution.
  7. status-value is the error identifier that causes the DestroyEvent.
  8. message-value is the error message explaining the reason of the DestroyEvent.

Example:

This example shows an event _om command corresponding to the following interaction:

01 event _om 3 {} 
02  { 
03    { ConfigureEvent 0 { { idRef "35" } { value "someText" } { cursor "4" } } }
04    { ConfigureEvent 0 { { idRef "32" } { cursor "6" } } } 
05  }           

Communication Initialization

Communication is initiated by the Runtime System, which sends some meta information to the Front End. The meta information sent is "encoding". The Front End replies with some information, to include the version of the Front End. With communication initialized, the Runtime System sends the first version of the AUI Tree, generated according to the interactive elements used in the program (see Menus, Windows and Forms).

The root node of the Tree is the UserInterface node. This node is sent once to the Front End. The append node command (an) is used to create the root node with an id of zero ('0'). The append node command is then used to add all the children needed by the Front End to build the initial Graphical User Interface.

DVM meta message syntax:

DVM :   meta Connection {
              { encoding "character-set" }
              { protocolVersion "protocol-version" }
              { interfaceVersion "interface-version" }
              { runtimeVersion "runtime-version" }
              { compression "zlib|none" }
              { encapsulation "0|1" }
        }

Notes:

  1. character-set defines the encoding character code set used in the protocol.
  2. The compression attribute defines the type of compression used. The compression method can be "zlib" or "none". When "zlib" is used the encapsulation must be enabled. If this attribute is not set the default value is "none". When the DVM send this attribute it is a request. The compression is only used once the front-end validates this request.
  3. protocol-version defines the version of the protocol (commands).
  4. interface-version defines the version of the user interface (nodes and attributes).
  5. runtime-version defines the version of runtime system (VM).

Front-end meta message syntax:

FE :    meta Client {
              { name "client-type" }
              { version "client-version" }
              { host "hostname" }
              { port "tcpport" }
              { connections "count" }
              { frontEndID2 "frontend-ID2" }
              { compression "zlib|none" }
              { encapsulation "0|1" }
              { filetransfer "0|1" }
        }

Notes:

  1. client-type is the type of the front end. Can be GDC, GJC, and so on.
  2. client-version is the version of the Front End.
  3. hostname is the network address (alphanumeric value) of the computer hosting the Front End.
  4. tcpport is the network port number used by the connection.
  5. count is the number of connections established with the front-end.
  6. frontend-ID2 identifies the front-end for authentication rules.

Protocol compression and encapsulation

Encapsulation is always active in the GUI protocol, to send packets by blocks over the network and allow secondary protocols over the channel, such as file transfer between the front-end and the application server.

When possible, the runtime system and the client try to compress the data exchanges in the GUI communication. The compression algorithm is provided by the standard ZLIB library of the system. The ZLIB library might not be installed on the system, especially on Windows platforms. If the runtime system is not able to find the standard ZLIB library of the system, it loads the fallback library provided in FGLDIR. This secondary library is located in $FGLDIR/lib/libzfgl.so on UNIX and %FGLDIR%\bin\LIBZFGL.DLL on Windows.

Notes:

  1. By default if encapsulation / compression is enabled, the GUI communication is not pretty printed. To properly see the GUI communication in a front-end log window, set the environment variable FGLGUIDEBUG to 1.