useful when you want to display a compound string that contains text in several different styles, as we'll show you in
an example later in this section.
Although automatic string conversion can handle the creation of most compound strings, there are still a few
situations when you need to define compound strings explicitly. If you want to declare an exported compound string
variable or override one of the properties of a compound string, you need to use the compound string literal syntax.
An explicit compound string definition takes the following form:
compound_string (string_expression,
[, right_to_left = boolean_expression ]
[, separate = boolean_expression ] )
A compound_string literal begins with the compound_string keyword and is followed by a single or
double−quoted string and the optional properties. You can set the writing direction of the compound string with the
right_to_left property; the default value of this property is taken from the writing direction string's character
set. The separate property specifies whether or not a separator component is added to the end of the compound
string. The default value is false, which means that a separator is not added.
Unlike with NULL−terminated strings, placing a newline character in a compound string does not produce a
multi−line string. A line break in a compound string is indicated by a separator component, which you add by setting
the separate property to true in an explicit compound string definition. You can create a multi−line compound
string by concatenating compound strings with the & operator, as shown in the source code
module multiline
value
file : compound_string ("/vmunix", separate=true);
owner : compound_string ("root", separate=true);
desc : compound_string ("The UNIX kernel.");
all : "File: " & file & "Owner: " & owner & "Desc: " & desc;
object root : XmLabel {
arguments {
XmNlabelString = all;
};
};
end module;
Both file and owner are defined as compound string values that contain a compound string separator. The
concatenation of the strings in this example produces a three−line compound string, which is shown in the figure.
User interface of multiline.uil
25 Creating a User Interface With UIL 25.3.4 Text−related Values
681
As the source code shows, you can mix NULL−terminated strings and compound strings with the & concatenation
operator. When you concatenate two strings, the result is a compound string if either one of the strings is a compound
string, or if the character sets of the two strings are different. The wide_character string type was added in Motif
1.2 to support the definition of user interfaces that contain Asian language text. Unfortunately, the UIL compiler flags
a wide−character definition as an error in early releases of Motif 1.2. The form of a wide−character definition is:
wide_character (string_expression)
The string_expression contains a multibyte string. Asian language text must be represented with multibyte or
wide−character strings because the number of different characters in these languages cannot be encoded in single
bytes. In a multibyte character string, the length in bytes of each individual character varies, but in a wide−character
string, the length of each character is the same. Most programs, including the Motif widgets, work with
wide−character strings internally because the fixed character size makes them easier to use than multibyte characters.
The wide_character type converts a multibyte character string into an equivalent wide−character string. The
conversion is based on the locale that is set when you run the UIL compiler. When compiling a module that contains
wide−character strings, you must use the −s compiler option or multibyte string conversions may be incorrect. See
Section #suilcomps for more information about this option.
The only wide−character resource in the Motif widget set is the XmNvalueWcs resource of the Text and TextField
widgets. In addition to setting this resource, you can also fetch exported wide−character strings from an application
program and use them as callback arguments. In addition to single, NULL−terminated strings and compound strings,
UIL supports arrays of both types. The XmNitems and XmNselectedItems resources of the List widget are both
XmStringTable values, or compound string arrays. Even though there are no NULL−terminated string array
resources in the Motif widget set, you can still pass these arrays as callback arguments and fetch exported arrays with
MrmFetchLiteral(), just as you can with compound string arrays. The form of each type of array is similar, as
shown in the following fragment:
value
seasons : asciz_string_table ('winter', 'spring', 'summer', 'autumn');
fruits : compound_string_table ("apple", "banana", "grape", "cherry");
You can also use the keywords asciz_table and string_table when defining NULL−terminated and
compound string tables, respectively. The UIL compiler terminates both types of arrays with a NULL pointer. Quoted
strings in the compound_string_table are converted automatically to compound strings by the UIL compiler.
However, unlike with individual string values, the UIL compiler does not convert an asciz_string_table to a
compound_string_table. Remember that when you set a Motif XmStringTable resource, the UIL compiler
sets the associated count resource automatically. Fonts are the last piece of the textual information picture that we
need to examine. As we explained earlier, you cannot display a compound string without an associated font; a
character set links a string to a particular font. You specify the fonts used by Motif widgets with font list resources.
The simplest case involves setting the XmNfontList resource of a widget to a single font. A font list can also
specify a list of fonts or font sets and their associated character sets. For more information on Motif font lists, see
Chapter 19, Compound Strings.
UIL provides support for font, font set, and font list values. These types correspond to the XFontStruct,
XFontSet, and XmFontList types in C. The UIL font set type was added in Motif 1.2 to support the XFontSet
type that was added in X11R5. A font list can contain both fonts and font sets, so we'll look at these two types first.
The following code fragment shows a value of each type:
value
menu_font : font
('−adobe−times−bold−r−normal−−12−120−75−75−p−67−iso8859−1');
25 Creating a User Interface With UIL 25.3.4 Text−related Values
682
label_font : fontset ('−*−fixed−medium−r−normal−*−*−130−*');
As these definitions illustrate, fonts and font sets are defined using X Logical Font Description (XLFD) names and
patterns. Xlib may load one or more fonts in a font set, which is why you must always specify a pattern instead of a
single font name. Xlib determines the exact fonts that are needed based on the locale setting. For example, drawing
Japanese text typically requires a Kanji font, a Kana font, and a Latin font. For additional information about fonts and
font sets, see Volume One, Xlib Programming Manual, and Volume Two, Xlib Reference Manual.
Fonts and font sets are loaded at run−time because they are resources maintained by the X server. UIL simply stores
the font names or patterns that you specify in the UID output file without checking to see if the fonts exist. The font
and fontset types are typically used to set a Motif font list resource. Mrm also creates a XFontStruct or
XFontSet value for you when you pass a font or fontset value as a callback argument or when you fetch one of
the values from an application program.
Each Motif widget that displays text has a XmFontList resource associated with it. UIL provides the font_table
type so you can define font lists directly in UIL. A font list is simply an array of font and/or font set values, each of
which has an associated character set. The following fragment illustrates the definition of a font list:
value
latin1 : font ('*−iso8859−1', character_set = iso_latin1);
hebrew : font ('*−iso8859−8')
fonts : font_table (latin1, iso_hebrew = font ('*−iso8859−8'));
You define a font list using the font_table keyword followed by a list of fonts. This example demonstrates the
two ways of associating a character set with a font or font set. You can specify the character set in the font or font set
definition by adding a character_set property setting, or you can specify the character set directly in the
font_table definition. The character set specified in a font table definition takes precedence over a character set
specified in a font or font set definition.
If you do not specify a character set for a font or a font set, it defaults to the codeset portion of the LANG environment
variable if it is set, or to XmFALLBACK_CHARSET otherwise. Unlike with string definitions, the default character set
of the module has no effect on the character set used for font and font set definitions. If a font list contains only a
single font or font set, you can set the XmNfontList resource to the font or font set directly, and the UIL compiler
creates a font list that contains the entry automatically. Motif obtains the font or font set needed to render a compound
string by matching the character set of the string with a font or font set in a font list that has the same character set.
Now we can take a look at an example that uses strings, character sets, fonts, and font lists. The module in the source
code shows how these values work together. In early releases of Motif 1.2, the user−defined character set in this
module may cause a compilation error or it may crash the UIL compiler.
/* joel.uil − Example of strings, character sets, and fonts, and font sets. */
module joel
value
artist : #iso_latin1 "Billy Joel";
title : #iso_cyrillic "186\222\221\230\213\224\226
album : #character_set('latin1−bold') "Album";
value
normal : font ('*fixed−medium−r−normal−*−*−140−*−iso8859−1');
bold : font ('*fixed−medium−r−bold−*−*−140−*−iso8859−1');
russian : font ('*fixed−medium−r−normal−*−*−140−*−iso8859−5');
value
25 Creating a User Interface With UIL 25.3.4 Text−related Values
683
Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.