UIL(5X) OSF/Motif UIL(5X)NAMEUIL - The user interface language file format
SYNOPSIS
MODULE module_name
[ NAMES = CASE_INSENSITIVE | CASE_SENSITIVE ]
[ CHARACTER_SET = character_set ]
[ OBJECTS = { widget_name = GADGET | WIDGET; [...] } ]
{ [
[ value_section ] |
[ procedure_section ] |
[ list_section ] |
[ object_section ] |
[ identifier_section ]
[ ... ]
] } END MODULE;
DESCRIPTION
The UIL language is used for describing the initial state of a user
interface for a widget based application. UIL describes the widgets
used in the interface, the resources of those widgets, and the call‐
backs of those widgets. The UIL file is compiled into a UID file using
the command uil or by the callable compiler Uil(). The contents of the
compiled UID file can then by accessed by the various Motif Resource
Management (MRM) functions from within an application program.
FILE FORMATUIL is a free-form language. This means that high-level constructs
such as object and value declarations do not need to begin in any par‐
ticular column and can span any number of lines. Low-level constructs
such as keywords and punctuation characters can also begin in any col‐
umn; however, except for string literals and comments, they cannot span
lines.
The UIL compiler accepts input lines up to 132 characters in length.
The name by which the UIL module is known in the UID file. This name
is stored in the UID file for later use in the retrieval of resources
by the MRM. This name is always stored in uppercase in the UID file.
Indicates whether names should be treated as case sensitive or case
insensitive. The default is case sensitive. The case-sensitivity
clause should be the first clause in the module header, and in any case
must precede any statement that contains a name. If names are case
sensitive in a UIL module, UIL keywords in that module must be in low‐
ercase. Each name is stored in the UIL file in the same case as it
appears in the UIL module. If names are case insensitive, then key‐
words can be in uppercase, lowercase, or mixed case, and the uppercase
equivalent of each name is stored in the UID file. Specifies the
default character set for string literals in the module that do not
explicitly set their character set. The default character set, in the
absence of this clause is the codeset component of the LANG environment
variable, or the value of XmFALLBACK_CHARSET if LANG is not set or has
no codeset component. The value of XmFALLBACK_CHARSET is defined by
UIL supplier, but is usually ISO8859-1 (equivalent to ISO_LATIN1). Use
of this clause turns off all localized string literal processing turned
on by the compiler flag -s or the Uil_command_type data structure ele‐
ment use_setlocale_flag. Indicates whether the widget or gadget form
of the control specified by widget_name is used by default. By default
the widget form is used, so the gadget keyword is usually the only one
used. The specified control should be one that has both a widget and
gadget version: XmCascadeButton, XmLabel, XmPushButton, XmSeparator,
and XmToggleButton. The form of more than one control can be specified
by delimiting them with semicolons. The gadget or widget form of an
instance of a control can be specified with the GADGET and WIDGET key‐
words in a particular object declaration. Provides a way to name a
value expression or literal. The value name can then be referred to by
declarations that occur elsewhere in the UIL module in any context
where a value can be used. Values can be forward referenced. Value
sections are described in more detail later in the reference page.
Defines the callback routines used by a widget and the creation rou‐
tines for user-defined widgets. These definitions are used for error
checking. Procedure sections are described in more detail later in the
reference page. Provides a way to group together a set of arguments,
controls (children), callbacks, or procedures for later use in the UIL
module. Lists can contain other lists, so that you can set up a hier‐
archy to clearly show which arguments, controls, callbacks, and proce‐
dures are common to which widgets. List sections are described in more
detail later in the reference page. Defines the objects that make up
the user interface of the application. You can reference the object
names in declarations that occur elsewhere in the UIL module in any
context where an object name can be used (for example, in a controls
list, as a symbolic reference to a widget ID, or as the tag_value argu‐
ment for a callback procedure). Objects can be forward referenced.
Object sections are described in more detail later in the reference
page. Defines a run-time binding of data to names that appear in the
UIL module. Identifier sections are described in more detail later in
the reference page.
The UIL file can also contain comments and include directives, which
are described along with the main elements of the UIL file format in
the following sections.
Comments
Comments can take one of two forms, as follows: The comment is intro‐
duced with the sequence /* followed by the text of the comment and ter‐
minated with the sequence */. This form of comment can span multiple
source lines. The comment is introduced with an ! (exclamation point),
followed by the text of the comment and terminated by the end of the
source line.
Neither form of comment can be nested.
Value sections
A value section consists of the keyword VALUE followed by a sequence of
value declarations. It has the following syntax:
VALUE value_name :
[ EXPORTED | PRIVATE ] value_expression |
IMPORTED value_type ;
Where value_expression is assigned to value_name or a value_type is
assigned to an imported value name. A value declaration provides a way
to name a value expression or literal. The value name can be referred
to by declarations that occur later in the UIL module in any context
where a value can be used. Values can be forward referenced. A value
that you define as exported is stored in the UID file as a named
resource, and therefore can be referenced by name in other UID files.
When you define a value as exported, MRM looks outside the module in
which the exported value is declared to get its value at run time. A
private value is a value that is not imported or exported. A value
that you define as private is not stored as a distinct resource in the
UID file. You can reference a private value only in the UIL module
containing the value declaration. The value or object is directly
incorporated into anything in the UIL module that references the decla‐
ration. A value that you define as imported is one that is defined as
a named resource in a UID file. MRM resolves this declaration with the
corresponding exported declaration at application run time.
By default, values and objects are private. The following is a list of
the supported value types in UIL. ANY ARGUMENT BOOLEAN COLOR COLOR_TA‐
BLE COMPOUND_STRING FLOAT FONT FONT_TABLE FONTSET ICON INTEGER INTE‐
GER_TABLE KEYSYM REASON SINGLE_FLOAT STRING STRING_TABLE TRANSLA‐
TION_TABLE WIDE_CHARACTER WIDGET
Procedure sections
A procedure section consists of the keyword PROCEDURE followed by a
sequence of procedure declarations. It has the following syntax:
PROCEDURE
procedure_name [ ( [ value_type ] ) ] ;
Use a procedure declaration to declare: A routine that can be used as a
callback routine for a widget The creation function for a user-defined
widget
You can reference a procedure name in declarations that occur later in
the UIL module in any context where a procedure can be used. Proce‐
dures can be forward referenced. You cannot use a name you used in
another context as a procedure name.
In a procedure declaration, you have the option of specifying that a
parameter will be passed to the corresponding callback routine at run
time. This parameter is called the callback tag. You can specify the
data type of the callback tag by putting the data type in parentheses
following the procedure name. When you compile the module, the UIL
compiler checks that the argument you specify in references to the pro‐
cedure is of this type. Note that the data type of the callback tag
must be one of the valid UIL data types. You can use a widget as a
callback tag, as long as the widget is defined in the same widget hier‐
archy as the callback, that is they have a common ancestor that is in
the same UIL hierarchy.
The following list summarizes how the UIL compiler checks argument type
and argument count, depending on the procedure declaration: No argument
type or argument count checking occurs. You can supply either 0 or 1
aguments in the procedure reference. Checks that the argument count is
0. Checks that the argument count is 1. Does not check the argument
type. Use the ANY type to prevent type checking on procedure tags.
Checks for one argument of the specified type. Checks for one widget
argument of the specified widget class.
While it is possible to use any UIL data type to specify the type of a
tag in a procedure declaration, you must be able to represent that data
type in the programming language you are using. Some data types (such
as integer, Boolean, and string) are common data types recognized by
most programming languages. Other UIL data types (such as string
tables) are more complicated and may require you to set up an appropri‐
ate corresponding data structure in the application in order to pass a
tag of that type to a callback routine.
You can also use a procedure declaration to specify the creation func‐
tion for a user-defined widget. In this case, you specify no formal
parameters. The procedure is invoked with the standard three arguments
passed to all widget creation functions. (See the Motif Toolkit docu‐
mentation for more information about widget creation functions.)
List sections
A list section consists of the keyword LIST followed by a sequence of
list declarations. It has the following syntax:
LIST
list_name : { list_item; [...] }
[...]
You can also use list sections to group together a set of arguments,
controls (children), callbacks, or procedures for later use in the UIL
module. Lists can contain other lists, so that you can set up a hier‐
archy to clearly show which arguments, controls, callbacks, and proce‐
dures are common to which widgets. You cannot mix the different types
of lists; a list of a particular type cannot contain entries of a dif‐
ferent list type or reference the name of a different list type. A
list name is always private to the UIL module in which you declare the
list and cannot be stored as a named resource in a UID file.
The additional list types are described in the following sections.
Arguments List Structure
An arguments list defines which arguments are to be specified in the
arguments-list parameter when the creation routine for a particular
object is called at run time. An arguments list also specifies the
values for those arguments. Argument lists have the following syntax:
LIST
list_name : ARGUMENTS {
argument_name = value_expression;
[...] }
[...]
The argument name must be either a built-in argument name or a user-
defined argument name that is specified with the ARGUMENT function.
If you use a built-in argument name as an arguments list entry in an
object definition, the UIL compiler checks the argument name to be sure
that it is supported by the type of object that you are defining. If
the same argument name appears more than once in a given arguments
list, the last entry that uses that argument name supersedes all previ‐
ous entries with that name, and the compiler issues a message.
Some arguments, such as XmNitems and XmNitemCount, are coupled by the
UIL compiler. When you specify one of the arguments, the compiler also
sets the other. The coupled argument is not available to you.
The Motif Toolkit and the X Toolkit (intrinsics) support constraint
arguments. A constraint argument is one that is passed to children of
an object, beyond those arguments normally available. For example, the
Form widget grants a set of constraint arguments to its children.
These arguments control the position of the children within the Form.
Unlike the arguments used to define the attributes of a particular wid‐
get, constraint arguments are used exclusively to define additional
attributes of the children of a particular widget. These attributes
affect the behavior of the children within their parent. To supply
constraint arguments to the children, you include the arguments in the
arguments list for the child.
See Appendix B in the OSF/Motif Programmer's Reference for information
about which arguments are supported by which widgets. See Appendix C,
also in the OSF/Motif Programmer's Reference for information about what
the valid value type is for each built-in argument.
Callbacks List Structure
Use a callbacks list to define which callback reasons are to be pro‐
cessed by a particular widget at run time. Callback lists have the
following syntax:
LIST
list_name : CALLBACKS {
reason_name = PROCEDURE procedure_name
[ ( [ value_expression ] ) ]; |
reason_name = procedure_list ;
[...] }
[...]
For Motif Toolkit widgets, the reason name must be a built-in reason
name. For a user-defined widget, you can use a reason name that you
previously specified using the REASON function. If you use a built-in
reason in an object definition, the UIL compiler ensures that reason is
supported by the type of object you are defining. Appendix B shows
which reasons each object supports.
If the same reason appears more than once in a callbacks list, the last
entry referring to that name supersedes all previous entries using the
same reason, and the UIL compiler issues a diagnostic message.
If you specify a named value for the procedure argument (callback tag),
the data type of the value must match the type specified for the call‐
back tag in the corresponding procedure declaration. When specifying a
widget name as a procedure value expression you must also specify the
type of the widget and a space before the name of the widget.
Because the UIL compiler produces a UID file rather than an object mod‐
ule (.o), the binding of the UIL name to the address of the entry point
to the procedure is not done by the loader, but is established at run
time with the MRM function MrmRegisterNames. You call this function
before fetching any objects, giving it both the UIL names and the pro‐
cedure addresses of each callback. The name you register with MRM in
the application program must match the name you specified for the pro‐
cedure in the UIL module.
Each callback procedure receives three arguments. The first two argu‐
ments have the same form for each callback. The form of the third
argument varies from object to object.
The first argument is the address of the data structure maintained by
the Motif Toolkit for this object instance. This address is called the
widget ID for this object.
The second argument is the address of the value you specified in the
callbacks list for this procedure. If you do not specify an argument,
the address is NULL.
The third argument is the reason name you specified in the callbacks
list.
Controls List Structure
A controls list defines which objects are children of, or controlled
by, a particular object. Each entry in a controls list has the follow‐
ing syntax:
LIST
list_name : CONTROLS {
[child_name] [MANAGED | UNMANAGED] object_definition;
[...] }
[...]
If you specify the keyword MANAGED at run time, the object is created
and managed; if you specify UNMANAGED at run time, the object is only
created. Objects are managed by default.
You can use child_name to specify resources for the automatically cre‐
ated children of a particular control. Names for automatically created
children are formed by appending Xm_ to the name of the child widget.
This name is specified in the documentation for the parent widget.
Unlike the arguments list and the callbacks list, a controls list entry
that is identical to a previous entry does not supersede the previous
entry. At run time, each controls list entry causes a child to be cre‐
ated when the parent is created. If the same object definition is used
for multiple children, multiple instances of the child are created at
run time. See Appendix B in the Programmer's Reference for a list of
which widget types can be controlled by which other widget types.
Procedures List Structure
You can specify multiple procedures for a callback reason in UIL by
defining a procedures list. Just as with other list types, procedures
lists can be defined in-line or in a list section and referenced by
name.
If you define a reason more than once (for example, when the reason is
defined both in a referenced procedures list and in the callbacks list
for the object), previous definitions are overridden by the latest def‐
inition. The syntax for a procedures list is as follows:
LIST
list_name : PROCEDURES {
procedure_name [ ( [ value_expression ] ) ];
[...] }
[...]
When specifying a widget name as a procedure value expression you must
also specify the type of the widget and a space before the name of the
widget.
Object Sections
An object section consists of the keyword OBJECT followed by a sequence
of object declarations. It has the following syntax:
OBJECT object_name :
[ EXPORTED | PRIVATE | IMPORTED ] object_type
[ PROCEDURE creation_function ]
[ object_name [ WIDGET | GADGET ] |
{list_definitions } ]
Use an object declaration to define the objects that are to be stored
in the UID file. You can reference the object name in declarations
that occur elsewhere in the UIL module in any context where an object
name can be used (for example, in a controls list, as a symbolic refer‐
ence to a widget ID, or as the tag_value argument for a callback proce‐
dure). Objects can be forward referenced; that is, you can declare an
object name after you reference it. All references to an object name
must be consistent with the type of the object, as specified in the
object declaration. You can specify an object as exported, imported,
or private.
The object definition can contain a sequence of lists that define the
arguments, hierarchy, and callbacks for the widget. You can specify
only one list of each type for an object. When you declare a user-
defined widget, you must include a reference to the widget creation
function for the user-defined widget.
Use the GADGET or WIDGET keyword to specify the object type or to over‐
ride the default variant for this object type. You can use the Motif
Toolkit name of an object type that has a gadget variant (for example,
XmLabelGadget) as an attribute of an object declaration. The
object_type can be any object type, including gadgets. You need to
specify the GADGET or WIDGET keyword only in the declaration of an
object, not when you reference the object. You cannot specify the GAD‐
GET or WIDGET keyword for a user-defined object; user-defined objects
are always widgets.
Identifier sections
The identifier section allows you to define an identifier, a mechanism
that achieves run-time binding of data to names that appear in a UIL
module. The identifier section consists of the reserved keyword IDEN‐
TIFIER, followed by a list of names, each name followed by a semicolon.
IDENTIFIER identifier_name; [...;]
You can later use these names in the UIL module as either the value of
an argument to a widget or the tag value to a callback procedure. At
run time, you use the MRM functions MrmRegisterNames and MrmRegister‐
NamesInHierarchy to bind the identifier name with the data (or, in the
case of callbacks, with the address of the data) associated with the
identifier.
Each UIL module has a single name space; therefore, you cannot use a
name you used for a value, object, or procedure as an identifier name
in the same module.
The UIL compiler does not do any type checking on the use of identi‐
fiers in a UIL module. Unlike a UIL value, an identifier does not have
a UIL type associated with it. Regardless of what particular type a
widget argument or callback procedure tag is defined to be, you can use
an identifier in that context instead of a value of the corresponding
type.
To reference these identifier names in a UIL module, you use the name
of the identifier wherever you want its value to be used.
Include directives
The include directive incorporates the contents of a specified file
into a UIL module. This mechanism allows several UIL modules to share
common definitions. The syntax for the include directive is as fol‐
lows:
INCLUDE FILE file_name ;
The UIL compiler replaces the include directive with the contents of
the include file and processes it as if these contents had appeared in
the current UIL source file.
You can nest include files; that is, an include file can contain
include directives. The UIL compiler can process up to 100 references
(including the file containing the UIL module). Therefore, you can
include up to 99 files in a single UIL module, including nested files.
Each time a file is opened counts as a reference, so including the same
file twice counts as two references.
The character expression is a file specification that identifies the
file to be included. The rules for finding the specified file are sim‐
ilar to the rules for finding header, or .h files using the include
directive, #include, with a quoted string in C. The uil uses the -I
option for specifying a search directory for include files. If you do
not supply a directory, the UIL compiler searches for the include file
in the directory of the main source file. If the compiler does not
find the include file there, the compiler looks in the same directory
as the source file. If you supply a directory, the UIL compiler
searches only that directory for the file.
LANGUAGE SYNTAX
Names and Strings
Names can consist of any of the characters A to Z, a to z, 0 to 9, $
(dollar sign), and _ (underscore). Names cannot begin with a digit (0
to 9). The maximum length of a name is 31 characters.
UIL gives you a choice of either case-sensitive or case-insensitive
names through a clause in the MODULE header. For example, if names are
case sensitive, the names "sample" and "Sample" are distinct from each
other. If names are case insensitive, these names are treated as the
same name and can be used interchangeably. By default, UIL assumes
names are case sensitive.
In CASE-INSENSITIVE mode, the compiler outputs all names in the UID
file in uppercase form. In CASE-SENSITIVE mode, names appear in the
UIL file exactly as they appear in the source.
The following table list the reserved keywords, which are not available
for defining programmer defined names.
───────────────────────────────────────────────
Reserved Keywords
───────────────────────────────────────────────
ARGUMENTS CALLBACKS CONTROLS END
EXPORTED FALSE GADGET IDENTIFIER
INCLUDE LIST MODULE OFF
ON OBJECT PRIVATE PROCEDURE
PROCEDURES TRUE VALUE WIDGET
───────────────────────────────────────────────
The following table list the UIL unreserved keywords. These keywords
can be used as programmer defined names, however, if you use any key‐
word as a name, you cannot use the UIL-supplied usage of that keyword.
Built-in argument names (for example: XmNx, XmNheight) Built-in reason
names (for example: XmNactivateCallback, XmNhelpCallback) Character set
names (for example: ISO_LATIN1, ISO_HEBREW_LR) Constant value names
(for example: XmMENU_OPTION, XmBROWSE_SELECT) Object types (for exam‐
ple: XmPushButton, XmBulletinBoard)
────────────────────────────────────────────────────────────
Unreserved Keywords
────────────────────────────────────────────────────────────
ANY ARGUMENT ASCIZ_STRING_TABLE
ASCIZ_TABLE BACKGROUND BOOLEAN
CASE_INSENSITIVE CASE_SENSITIVE CHARACTER_SET
COLOR COLOR_TABLE COMPOUND_STRING
COMPOUND_STRING_TABLE FILE FLOAT
FONT FONT_TABLE FONTSET
FOREGROUND ICON IMPORTED
INTEGER INTEGER_TABLE KEYSYM
MANAGED NAMES OBJECTS
REASON RGB RIGHT_TO_LEFT
SINGLE_FLOAT STRING STRING_TABLE
TRANSLATION_TABLE UNMANAGED USER_DEFINED
VERSION WIDE_CHARACTER WIDGET
XBITMAPFILE
────────────────────────────────────────────────────────────
String literals can be composed of the upper- and lower-case letters,
digits, and punctuation characters. Spaces, tabs, and comments are
special elements in the language. They are a means of delimiting other
elements, such as two names. One or more of these elements can appear
before or after any other element in the language. However, spaces,
tabs, and comments that appear in string literals are treated as char‐
acter sequences rather than delimiters.
Data Types
UIL provides literals for several of the value types it supports. Some
of the value types are not supported as literals (for example, pixmaps
and string tables). You can specify values for these types by using
functions described in the Functions section. UIL directly supports
the following literal types: String literal Integer literal Boolean
literal Floating-point literal
UIL also includes the data type ANY, which is used to turn off compile
time checking of data types.
String Literals
A string literal is a sequence of zero or more 8-bit or 16-bit charac‐
ters or a combination delimited by ' (single quotation marks) or "
(double quotation marks). String literals can also contain multibyte
characters delimited with double quotation marks. String literals can
be no more than 2000 characters long.
A single-quoted string literal can span multiple source lines. To con‐
tinue a single-quoted string literal, terminate the continued line with
a \ (backslash). The literal continues with the first character on the
next line.
Double-quoted string literals cannot span multiple source lines.
(Because double-quoted strings can contain escape sequences and other
special characters, you cannot use the backslash character to designate
continuation of the string.) To build a string value that must span
multiple source lines, use the concatenation operator described later
in this section.
The syntax of a string literal is one of the following:
'[character_string]' [#char_set]"[character_string]"
Both string forms associate a character set with a string value. UIL
uses the following rules to determine the character set and storage
format for string literals: A string declared as 'string' is equivalent
to #cur_charset"string", where cur_charset will be the codeset portion
of the value of the LANG environment variable if it is set or the value
of XmFALLBACK_CHARSET if LANG is not set or has no codeset component.
By default XmFALLBACK_CHARSET is ISO8859-1 (equivalent to ISO_LATIN1),
but vendors may define a different default. A string declared as
"string" is equivalent to #char_set"string" if you specified char_set
as the default character set for the module. If no default character
set has been specified for the module, then if the -s option is pro‐
vided to the uil command or the use_setlocale_flag is set for the
callable compiler, Uil(), the string will be interpreted to be a string
in the current locale. This means that the string is parsed in the
locale of the user by calling setlocale and its charset is
XmFONTLIST_DEFAULT_TAG, and that if the string is converted to a com‐
pound string, it is stored as a locale encoded text segment. Other‐
wise, "string" is equivalent to #cur_charset"string", where cur_charset
is interpreted as described for single quoted strings. A string of the
form "string" or #char_set"string" is stored as a null-terminated
string.
The following table lists the character sets supported by the UIL com‐
piler for string literals. Note that several UIL names map to the same
character set. In some cases, the UIL name influences how string lit‐
erals are read. For example, strings identified by a UIL character set
name ending in _LR are read left-to-right. Names that end in a differ‐
ent number reflect different fonts (for example, ISO_LATIN1 or
ISO_LATIN6). All character sets in this table are represented by 8
bits.
───────────────────────────────────────────────────────
Supported Character Sets
───────────────────────────────────────────────────────
UIL Name Description
───────────────────────────────────────────────────────
ISO_LATIN1 GL: ASCII, GR: Latin-1 Supplement
ISO_LATIN2 GL: ASCII, GR: Latin-2 Supplement
ISO_ARABIC GL: ASCII, GR: Latin-Arabic Supplement
ISO_LATIN6 GL: ASCII, GR: Latin-Arabic Supplement
ISO_GREEK GL: ASCII, GR: Latin-Greek Supplement
ISO_LATIN7 GL: ASCII, GR: Latin-Greek Supplement
ISO_HEBREW GL: ASCII, GR: Latin-Hebrew Supplement
ISO_LATIN8 GL: ASCII, GR: Latin-Hebrew Supplement
ISO_HEBREW_LR GL: ASCII, GR: Latin-Hebrew Supplement
ISO_LATIN8_LR GL: ASCII, GR: Latin-Hebrew Supplement
JIS_KATAKANA GL: JIS Roman, GR: JIS Katakana
───────────────────────────────────────────────────────
Following are the parsing rules for each of the character sets: Charac‐
ter codes in the range 00...1F, 7F, and 80...9F are control characters
including both bytes of 16-bit characters. The compiler flags these as
illegal characters. These sets are parsed from left to right. The
escape sequences for null-terminated strings are also supported by
these character sets. These sets are parsed from right to left; for
example, the string #ISO_HEBREW"012345" generates a primitive string
"543210" with character set ISO_HEBREW. A DDIS descriptor for such a
string has this segment marked as being right_to_left. The escape
sequences for null-terminated strings are also supported by these char‐
acter sets, and the characters that compose the escape sequences are in
left-to-right order. For example, you type \n, not n\. These sets are
parsed from left to right; for example, the string
#ISO_HEBREW_LR"012345" generates a primitive string "012345" with char‐
acter set ISO_HEBREW. A DDIS descriptor for such a string marks this
segment as being left_to_right. The escape sequences for null-termi‐
nated strings are also supported by these character sets. This set is
parsed from left to right. The escape sequences for null-terminated
strings are also supported by this character set. Note that the \
(backslash) may be displayed as a yen symbol.
In addition to designating parsing rules for strings, character set
information remains an attribute of a compound string. If the string
is included in a string consisting of several concatenated segments,
the character set information is included with that string segment.
This gives the Motif Toolkit the information it needs to decipher the
compound string and choose a font to display the string.
For an application interface displayed only in English, UIL lets you
ignore the distinctions between the two uses of strings. The compiler
recognizes by context when a string must be passed as a null-terminated
string or as a compound string.
The UIL compiler recognizes enough about the various character sets to
correctly parse string literals. The compiler also issues errors if
you use a compound string in a context that supports only null-termi‐
nated strings.
Since the character set names are keywords, you must put them in lower‐
case if case-sensitive names are in force. If names are case insensi‐
tive, character set names can be uppercase, lowercase, or mixed case.
In addition to the built-in character sets recognized by UIL, you can
define your own character sets with the CHARACTER_SET function. You
can use the CHARACTER_SET function anywhere a character set can be
specified.
String literals can contain characters with the eighth (high-order) bit
set. You cannot type control characters (00..1F, 7F, and 80..9F)
directly in a single-quoted string literal. However, you can represent
these characters with escape sequences. The following list shows the
escape sequences for special characters: Backspace Form-feed Newline
Carriage return Horizontal tab Vertical tab Single quotation mark Dou‐
ble quotation mark Backslash Character whose internal representation is
given by integer (in the range 0 to 255 decimal)
Note that escape sequences are processed literally in strings that are
parsed in the current locale (localized strings).
The UIL compiler does not process newline characters in compound
strings. The effect of a newline character in a compound string
depends only on the character set of the string, and the result is not
guaranteed to be a multiline string.
Compound String Literals
A compound string consists of a string of 8-bit, 16-bit, or multibyte
characters, a named character set, and a writing direction. Its UIL
data type is compound_string.
The writing direction of a compound string is implied by the character
set specified for the string. You can explicitly set the writing
direction for a compound string by using the COMPOUND_STRING function.
A compound string can consist of a sequence of concatenated compound
strings, null-terminated strings, or a combination of both, each of
which can have a different character set property and writing direc‐
tion. Use the concatenation operator & (ampersand) to create a
sequence of compound strings.
Each string in the sequence is stored, including the character set and
writing direction information.
Generally, a string literal is stored in the UID file as a compound
string when the literal consists of concatenated strings having differ‐
ent character sets or writing directions, or when you use the string to
specify a value for an argument that requires a compound string value.
If you want to guarantee that a string literal is stored as a compound
string, you must use the COMPOUND_STRING function.
Data Storage Consumption for String Literals
The way a string literal is stored in the UID file depends on how you
declare and use the string. The UIL compiler automatically converts a
null-terminated string to a compound string if you use the string to
specify the value of an argument that requires a compound string. How‐
ever, this conversion is costly in terms of storage consumption.
PRIVATE, EXPORTED, and IMPORTED string literals require storage for a
single allocation when the literal is declared; thereafter, storage is
required for each reference to the literal. Literals declared in-line
require storage for both an allocation and a reference.
The following table summarizes data storage consumption for string lit‐
erals. The storage requirement for an allocation consists of a fixed
portion and a variable portion. The fixed portion of an allocation is
roughly the same as the storage requirement for a reference (a few
bytes). The storage consumed by the variable portion depends on the
size of the literal value (that is, the length of the string). To con‐
serve storage space, avoid making string literal declarations that
result in an allocation per use.
───────────────────────────────────────────────────────────────────────
Data Storage Consumption for String Literals
───────────────────────────────────────────────────────────────────────
Declaration Data Type Used As Storage Requirements
Per Use
───────────────────────────────────────────────────────────────────────
In-line Null-terminated Null-terminated An allocation and a
reference (within
the module)
Private Null-terminated Null-terminated A reference (within
the module)
Exported Null-terminated Null-terminated A reference (within
the UID hierarchy)
Imported Null-terminated Null-terminated A reference (within
the UID hierarchy)
In-line Null-terminated Compound An allocation and a
reference (within
the module)
Private Null-terminated Compound An allocation and a
reference (within
the module)
Exported Null-terminated Compound A reference (within
the UID hierarchy)
Imported Null-terminated Compound A reference (within
the UID hierarchy)
In-line Compound Compound An allocation and a
reference (within
the module)
Private Compound Compound A reference (within
the module)
Exported Compound Compound A reference (within
the UID hierarchy)
Imported Compound Compound A reference (within
the UID hierarchy)
───────────────────────────────────────────────────────────────────────
Integer Literals
An integer literal represents the value of a whole number. Integer
literals have the form of an optional sign followed by one or more dec‐
imal digits. An integer literal must not contain embedded spaces or
commas.
Integer literals are stored in the UID file as long integers. Exported
and imported integer literals require a single allocation when the lit‐
eral is declared; thereafter, a few bytes of storage are required for
each reference to the literal. Private integer literals and those
declared in-line require allocation and reference storage per use. To
conserve storage space, avoid making integer literal declarations that
result in an allocation per use.
The following table shows data storage consumption for integer liter‐
als.
────────────────────────────────────────────────────────────────
Data Storage Consumption for Integer Literals
────────────────────────────────────────────────────────────────
Declaration Storage Requirements Per Use
────────────────────────────────────────────────────────────────
In-line An allocation and a reference (within the module)
Private An allocation and a reference (within the module)
Exported A reference (within the UID hierarchy)
Imported A reference (within the UID hierarchy)
────────────────────────────────────────────────────────────────
Boolean Literal
A Boolean literal represents the value True (reserved keyword TRUE or
On) or False (reserved keyword FALSE or Off). These keywords are sub‐
ject to case-sensitivity rules.
In a UID file, TRUE is represented by the integer value 1 and FALSE is
represented by the integer value 0.
Data storage consumption for Boolean literals is the same as that for
integer literals.
Floating-Point Literal
A floating-point literal represents the value of a real (or float) num‐
ber. Floating-point literals have the following form:
[+|-][integer].integer[E|e[+|-]exponent]
For maximum portability a floating-point literal can represent values
in the range 1.0E-37 to 1.0E+37 with at least 6 significant digits. On
many machines this range will be wider, with more significant digits.
A floating-point literal must not contain embedded spaces or commas.
Floating-point literals are stored in the UID file as double-precision,
floating-point numbers. The following table gives examples of valid
and invalid floating-point notation for the UIL compiler.
─────────────────────────────────────────────────────────────────
Floating Point Literals
─────────────────────────────────────────────────────────────────
Valid Floating-Point Literals Invalid Floating-Point Literals
─────────────────────────────────────────────────────────────────
1.0 1e1 (no decimal point)
.1 E-1 (no decimal point or digits)
3.1415E-2 (equals .031415) 2.87 e6 (embedded blanks)
-6.29e7 (equals -62900000) 2.0e100 (out of range)
─────────────────────────────────────────────────────────────────
Data storage consumption for floating-point literals is the same as
that for integer literals.
The ANY Data Type
The purpose of the ANY data type is to shut off the data-type checking
feature of the UIL compiler. You can use the ANY data type for the
following: Specifying the type of a callback procedure tag Specifying
the type of a user-defined argument
You can use the ANY data type when you need to use a type not supported
by the UIL compiler or when you want the data-type restrictions imposed
by the compiler to be relaxed. For example, you might want to define a
widget having an argument that can accept different types of values,
depending on run-time circumstances.
If you specify that an argument takes an ANY value, the compiler does
not check the type of the value specified for that argument; therefore,
you need to take care when specifying a value for an argument of type
ANY. You could get unexpected results at run time if you pass a value
having a data type that the widget does not support for that argument.
Expressions
UIL includes compile-time value expressions. These expressions can
contain references to other UIL values, but cannot be forward refer‐
enced.
The following table lists the set of operators in UIL that allow you to
create integer, real, and Boolean values based on other values defined
with the UIL module. In the table, a precedence of 1 is the highest.
───────────────────────────────────────────────────────────
Valid Operators
───────────────────────────────────────────────────────────
Operator Operand Types Meaning Precedence
───────────────────────────────────────────────────────────
~ Boolean NOT 1
integer One's complement
- float Negate 1
integer Negate
+ float NOP 1
integer NOP
* float,float Multiply 2
integer,integer Multiply
/ float,float Divide 2
integer,integer Divide
+ float,float Add 3
integer,integer Add
- float,float Subtract 3
integer,integer Subtract
>> integer,integer Shift right 4
<< integer,integer Shift left 4
& Boolean,Boolean AND 5
integer,integer Bitwise AND
string,string Concatenate
| Boolean,Boolean OR 6
integer,integer Bitwise OR
^ Boolean,Boolean XOR 6
integer,integer Bitwise XOR
───────────────────────────────────────────────────────────
A string can be either a single compound string or a sequence of com‐
pound strings. If the two concatenated strings have different proper‐
ties (such as writing direction or character set), the result of the
concatenation is a multisegment compound string.
The string resulting from the concatenation is a null-terminated string
unless one or more of the following conditions exists: One of the oper‐
ands is a compound string The operands have different character set
properties The operands have different writing directions
Then the resulting string is a compound string. You cannot use
imported or exported values as operands of the concatenation operator.
The result of each operator has the same type as its operands. You
cannot mix types in an expression without using conversion routines.
You can use parentheses to override the normal precedence of operators.
In a sequence of unary operators, the operations are performed in
right-to-left order. For example, - + -A is equivalent to -(+(-A)).
In a sequence of binary operators of the same precedence, the opera‐
tions are performed in left-to-right order. For example, A*B/C*D is
equivalent to ((A*B)/C)*D.
A value declaration gives a value a name. You cannot redefine the
value of that name in a subsequent value declaration. You can use a
value containing operators and functions anywhere you can use a value
in a UIL module. You cannot use imported values as operands in expres‐
sions.
Several of the binary operators are defined for multiple data types.
For example, the operator for multiplication (*) is defined for both
floating-point and integer operands.
For the UIL compiler to perform these binary operations, both operands
must be of the same type. If you supply operands of different data
types, the UIL compiler automatically converts one of the operands to
the type of the other according to the following conversions rules. If
the operands are an integer and a boolean, the boolean is converted to
an integer. If the operands are an integer and a floating-point, the
integer is converted to an floating-point. If the operands are a
floating-point and a boolean, the boolean is converted to a floating-
point.
You can also explicitly convert the data type of a value by using one
of the conversion functions INTEGER, FLOAT or SINGLE_FLOAT.
Functions
UIL provides functions to generate the following types of values: Char‐
acter sets Keysyms Colors Pixmaps Single-precision, floating-point num‐
bers Double-precision, floating-point numbers Fonts Fontsets Font
tables Compound strings Compound string tables ASCIZ (null-terminated)
string tables Wide character strings Widget class names Integer tables
Arguments Reasons Translation tables
Remember that all examples in the following sections assume case-insen‐
sitive mode. Keywords are shown in uppercase letters to distinguish
them from user-specified names, which are shown in lowercase letters.
This use of uppercase letters is not required in case-insensitive mode.
In case-sensitive mode, keywords must be in lowercase letters. You can
define your own character sets with the CHARACTER_SET function. You
can use the CHARACTER_SET function anywhere a character set can be
specified.
The result of the CHARACTER_SET function is a character set with
the name string_expression and the properties you specify.
String_expression must be a null-terminated string. You can
optionally include one or both of the following clauses to spec‐
ify properties for the resulting character set: RIGHT_TO_LEFT =
boolean_expression SIXTEEN_BIT = boolean_expression
The RIGHT_TO_LEFT clause sets the default writing direction of
the string from right to left if boolean_expression is True, and
right to left otherwise.
The SIXTEEN_BIT clause allows the strings associated with this
character set to be interpreted as 16-bit characters if bool‐
ean_expression is True, and 8-bit characters otherwise. The
KEYSYM function is used to specify a keysym for a mnemonic
resource. The string_literal must contain exactly one charac‐
ter. The COLOR function supports the definition of colors.
Using the COLOR function, you can designate a value to specify a
color and then use that value for arguments requiring a color
value. The string expression names the color you want to
define; the optional keywords FOREGROUND and BACKGROUND identify
how the color is to be displayed on a monochrome device when the
color is used in the definition of a color table.
The UIL compiler does not have built-in color names. Colors are
a server-dependent attribute of an object. Colors are defined
on each server and may have different red-green-blue (RGB) val‐
ues on each server. The string you specify as the color argu‐
ment must be recognized by the server on which your application
runs.
In a UID file, UIL represents a color as a character string.
MRM calls X translation routines that convert a color string to
the device-specific pixel value. If you are running on a mono‐
chrome server, all colors translate to black or white. If you
are on a color server, the color names translate to their proper
colors if the following conditions are met: The color is
defined. The color map is not yet full.
If the color map is full, even valid colors translate to black
or white (foreground or background).
Interfaces do not, in general, specify colors for widgets, so
that the selection of colors can be controlled by the user
through the .Xdefaults file.
To write an application that runs on both monochrome and color
devices, you need to specify which colors in a color table
(defined with the COLOR_TABLE function) map to the background
and which colors map to the foreground. UIL lets you use the
COLOR function to designate this mapping in the definition of
the color. The following example shows how to use the COLOR
function to map the color red to the background color on a mono‐
chrome device: VALUE c: COLOR ( 'red',BACKGROUND );
The mapping comes into play only when the MRM is given a color
and the application is to be displayed on a monochrome device.
In this case, each color is considered to be in one of the fol‐
lowing three categories: The color is mapped to the background
color on the monochrome device. The color is mapped to the
foreground color on the monochrome device. Monochrome mapping
is undefined for this color.
If the color is mapped to the foreground or background color,
MRM substitutes the foreground or background color, respec‐
tively. If you do not specify the monochrome mapping for a
color, MRM passes the color string to the Motif Toolkit for map‐
ping to the foreground or background color. The three integers
define the values for the red, green, and blue components of the
color, in that order. The values of these components can range
from 0 to 65,535, inclusive.
In a UID file, UIL represents an RGB value as three integers.
MRM calls X translation routines that convert the integers to
the device-specific pixel value. If you are running on a mono‐
chrome server, all colors translate to black or white. If you
are on a color server, RGB values translate to their proper col‐
ors if the colormap is not yet full. If the colormap is full,
values translate to black or white (foreground or background).
The color expression is a previously defined color, a color
defined in line with the COLOR function, or the phrase BACK‐
GROUND COLOR or FOREGROUND COLOR. The character can be any
valid UIL character.
The COLOR_TABLE function provides a device-independent way to
specify a set of colors. The COLOR_TABLE function accepts
either previously defined UIL color names or in line color defi‐
nitions (using the COLOR function). A color table must be pri‐
vate because its contents must be known by the UIL compiler to
construct an icon. The colors within a color table, however,
can be imported, exported, or private.
The single letter associated with each color is the character
you use to represent that color when creating an icon. Each
letter used to represent a color must be unique within the color
table. The color table name must refer to a previously defined
color table and the row is a character expression giving one row
of the icon.
The ICON function describes a rectangular icon that is x pixels
wide and y pixels high. The strings surrounded by single quota‐
tion marks describe the icon. Each string represents a row in
the icon; each character in the string represents a pixel.
The first row in an icon definition determines the width of the
icon. All rows must have the same number of characters as the
first row. The height of the icon is dictated by the number of
rows.
The first argument of the ICON function (the color table speci‐
fication) is optional and identifies the colors that are avail‐
able in this icon. By using the single letter associated with
each color, you can specify the color of each pixel in the icon.
The icon must be constructed of characters defined in the speci‐
fied color table.
A default color table is used if you omit the argument specify‐
ing the color table. To make use of the default color table,
the rows of your icon must contain only spaces and asterisks.
The default color table is defined as follows: COLOR_TABLE(
BACKGROUND COLOR = ' ', FOREGROUND COLOR = '*' )
You can define other characters to represent the background
color and foreground color by replacing the space and asterisk
in the BACKGROUND COLOR and FOREGROUND COLOR clauses shown in
the previous statement. You can specify icons as private,
imported, or exported. Use the MRM function MrmFetchIconLiteral
to retrieve an exported icon at run time. The XBITMAPFILE func‐
tion is similar to the ICON function in that both describe a
rectangular icon that is x pixels wide and y pixels high. How‐
ever, XBITMAPFILE allows you to specify an external file con‐
taining the definition of an X bitmap, whereas all ICON function
definitions must be coded directly within UIL. X bitmap files
can be generated by many different X applications. UIL reads
these files through the XBITMAPFILE function, but does not sup‐
port creation of these files. The X bitmap file specified as
the argument to the XBITMAPFILE function is read at application
run time by MRM.
The XBITMAPFILE function returns a value of type pixmap and can
be used anywhere a pixmap data type is expected. The SIN‐
GLE_FLOAT function lets you store floating-point literals in UIL
files as single-precision, floating-point numbers. Single-pre‐
cision floating-point numbers can often be stored using less
memory than double-precision, floating-point numbers. The
real_number_literal can be either an integer literal or a float‐
ing-point literal. A value defined using this function cannot
be used in an arithmetic expression. The FLOAT function lets
you store floating-point literals in UIL files as double-preci‐
sion, floating-point numbers. The real_number_literal can be
either an integer literal or a floating-point literal. You
define fonts with the FONT function. Using the FONT function,
you designate a value to specify a font and then use that value
for arguments that require a font value. The UIL compiler has
no built-in fonts.
Each font makes sense only in the context of a character set.
The FONT function has an additional parameter to let you specify
the character set for the font. This parameter is optional; if
you omit it, the default character set depends on the value of
the LANG environment variable if it is set of the value of
XmFALLBACK_CHARSET if LANG is not set.
The string expression specifies the name of the font and the
clause CHARACTER_SET = char_set specifies the character set for
the font. The string expression used in the FONT function can‐
not be a compound string. You define fontsets with the FONTSET
function. Using the FONTSET function, you designate a set of
values to specify fonts and then use those values for arguments
that require a fontset. The UIL compiler has no built-in fonts.
Each font makes sense only in the context of a character set.
The FONTSET function has an additional parameter to let you
specify the character set for the font. This parameter is
optional; if you omit it, the default character set depends on
the value of the LANG environment variable if it is set of the
value of XmFALLBACK_CHARSET if LANG is not set.
The string expression specifies the name of the font and the
clause CHARACTER_SET = char_set specifies the character set for
the font. The string expression used in the FONTSET function
cannot be a compound string. A font table is a sequence of
pairs of fonts and character sets. At run time when an object
needs to display a string, the object scans the font table for
the character set that matches the character set of the string
to be displayed. UIL provides the FONT_TABLE function to let
you supply such an argument. The font expression is created
with the FONT and FONTSET functions.
If you specify a single font value to specify an argument that
requires a font table, the UIL compiler automatically converts a
font value to a font table. Use the COMPOUND_STRING function to
set properties of a null-terminated string and to convert it
into a compound string. The properties you can set are the
character set, writing direction, and separator.
The result of the COMPOUND_STRING function is a compound string
with the string expression as its value. You can optionally
include one or more of the following clauses to specify proper‐
ties for the resulting compound string: CHARACTER_SET = charac‐
ter_set RIGHT_TO_LEFT = boolean_expression SEPARATE = bool‐
ean_expression
The CHARACTER_SET clause specifies the character set for the
string. If you omit the CHARACTER_SET clause, the resulting
string has the same character set as string_expression.
The RIGHT_TO_LEFT clause sets the writing direction of the
string from right to left if boolean_expression is True, and
left to right otherwise. Specifying this argument does not
cause the value of the string expression to change. If you omit
the RIGHT_TO_LEFT argument, the resulting string has the same
writing direction as string_expression.
The SEPARATE clause appends a separator to the end of the com‐
pound string if boolean_expression is True. If you omit the
SEPARATE clause, the resulting string does not have a separator.
You cannot use imported or exported values as the operands of
the COMPOUND_STRING function. A compound string table is an
array of compound strings. Objects requiring a list of string
values, such as the XmNitems and XmNselectedItems arguments for
the list widget, use string table values. The COM‐
POUND_STRING_TABLE function builds the values for these two
arguments of the list widget. The COMPOUND_STRING_TABLE func‐
tion generates a value of type string_table. The name
STRING_TABLE is a synonym for COMPOUND_STRING_TABLE.
The strings inside the string table can be simple strings, which
the UIL compiler automatically converts to compound strings. An
ASCIZ string table is an array of ASCIZ (null-terminated) string
values separated by commas. This function allows you to pass
more than one ASCIZ string as a callback tag value. The
ASCIZ_STRING_TABLE function generates a value of type asciz_ta‐
ble. The name ASCIZ_TABLE is a synonym for ASCIZ_STRING_TABLE.
Use the WIDE_CHARACTER function to generate a wide character
string from null-terminated string in the current locale. Use
the CLASS_REC_NAME function to generate a widget class name.
For a widget class defined by the toolkit, the string argument
is the name of the class. For a user-defined widget, the string
argument is the name of the creation routine for the widget. An
integer table is an array of integer values separated by commas.
This function allows you to pass more than one integer per call‐
back tag value. The INTEGER_TABLE function generates a value of
type integer_table. The ARGUMENT function defines the arguments
to a user-defined widget. Each of the objects that can be
described by UIL permits a set of arguments, listed in Appendix
B. For example, XmNheight is an argument to most objects and
has integer data type. To specify height for a user-defined
widget, you can use the built-in argument name XmNheight, and
specify an integer value when you declare the user-defined wid‐
get. You do not use the ARGUMENT function to specify arguments
that are built into the UIL compiler.
The string_expression name is the name the UIL compiler uses for
the argument in the UID file. the argument_type is the type of
value that can be associated with the argument. If you omit the
second argument, the default type is ANY and no value type
checking occurs. Use one of the following keywords to specify
the argument type: ANY ASCIZ_TABLE BOOLEAN COLOR COLOR_TABLE
COMPOUND_STRING FLOAT FONT FONT_TABLE FONTSET ICON INTEGER INTE‐
GER_TABLE REASON SINGLE_FLOAT STRING STRING_TABLE TRANSLA‐
TION_TABLE WIDE_CHARACTER WIDGET
You can use the ARGUMENT function to allow the UIL compiler to
recognize extensions to the Motif Toolkit. For example, an
existing widget may accept a new argument. Using the ARGUMENT
function, you can make this new argument available to the UIL
compiler before the updated version of the compiler is released.
The REASON function is useful for defining new reasons for user-
defined widgets.
Each of the objects in the Motif Toolkit defines a set of condi‐
tions under which it calls a user-defined function. These con‐
ditions are known as callback reasons. The user-defined func‐
tions are termed callback procedures. In a UIL module, you use
a callbacks list to specify which user-defined functions are to
be called for which reasons.
Appendix B lists the callback reasons supported by the Motif
Toolkit objects.
When you declare a user-defined widget, you can define callback
reasons for that widget using the REASON function. The string
expression specifies the argument name stored in the UID file
for the reason. This reason name is supplied to the widget cre‐
ation routine at run time. Each of the Motif Toolkit widgets
has a translation table that maps X events (for example, mouse
button 1 being pressed) to a sequence of actions. Through widget
arguments, such as the common translations argument, you can
specify an alternate set of events or actions for a particular
widget. The TRANSLATION_TABLE function creates a translation
table that can be used as the value of a argument that is of the
data type translation_table.
You can use one of the following translation table directives
with the TRANSLATION_TABLE function: #override, #augment, or
#replace. The default is #replace. If you specify one of these
directives, it must be the first entry in the translation table.
The #override directive causes any duplicate translations to be
ignored. For example, if a translation for <Btn1Down> is
already defined in the current translations for a PushButton,
the translation defined by new_translations overrides the cur‐
rent definition. If the #augment directive is specified, the
current definition takes precedence. The #replace directive
replaces all current translations with those specified in the
XmNtranslations resource.
RELATED INFORMATIONuil(1X), Uil(3X)UIL(5X)