using the encoding for the current locale. To support a number of locales, the application needs to store string data in
separate files from the application code. The application must provide a separate file for each of the locales supported,
so that the program can read the appropriate file during localization.
However, since most Motif widgets use compound strings for representing textual data, a Motif application has to use
compound strings to display text. As we describe compound strings in this chapter, we'll discuss how to use them so
as not to interfere with the lower−level X internationalization features.
20.2 Creating Compound Strings
Almost all of the Motif widgets use compound strings to specify textual data. Labels, PushButtons, and Lists, among
others, all require their text to be given in compound string format, whether or not you require the additional
flexibility compound strings provide. The only widgets that don't use compound strings are the Text and TextField
widgets. As a result, you cannot use the compound string techniques for displaying text using multiple fonts.
However, in Motif 1.2, these widgets do support internationalized text output, so they can display text using multiple
character sets. For information on the internationalization capabilities of the Text and TextField widgets, see Section
#stexti18n.
A compound string (XmString) is made of three components: a tag, a direction, and text. The tag is an arbitrary
name that the programmer can use to associate a compound string with a particular font or font set. In Motif 1.1, the
tag was referred to as a character set. Since the tag doesn't necessarily specify a character set, Motif 1.2 now refers to
the entity as a font list tag; this change is strictly semantic. The tag−to−font mapping is done on a per−widget basis, so
the same name can map to different fonts for different widgets.
An application can create a compound string that uses multiple fonts by concatenating separate compound strings with
different tags to produce a single compound string. Concatenating compound strings with different fonts is a powerful
way to create graphically interesting labels and captions. More importantly, because fonts are loosely bound to
compound strings via resources, you can dynamically associate new fonts with a widget while an application is
running and effectively change text styles on the fly.
20.2.1 The Simple Case
Many applications only need to use compound strings to specify various textual resources. In this case, all that is
needed is a routine that converts a standard C−style NULL−terminated text string into a compound string. The most
basic form of conversion can be done using the XmStringCreateLocalized() function, as demonstrated in
examples throughout this book. This routine takes the following form:
XmString
XmStringCreateLocalized(text)
char *text;
The text parameter is a common C char string. The value returned is of type XmString, which is an opaque type
to the programmer.
XmStringCreateLocalized() is a new routine in Motif 1.2; it creates a compound string in the current locale,
which is specified by the tag XmFONTLIST_DEFAULT_TAG. This routine interprets the text string in the current
locale when creating the compound string. If you are writing an internationalized application that needs to support
multiple locales, you should use XmStringCreateLocalized() to create compound strings. The routine allows
you to take advantage of the lower−level internationalization features of X.
20 Compound Strings 20.2 Creating Compound Strings
564
Most applications specify compound string resources in resource files. This technique is appropriate for an
internationalized application, as there can be a separate resource file for each language environment that is supported.
Motif automatically converts all strings that are specified in resource files into compound strings using
XmStringCreateLocalized(), so the strings are handled correctly for the current locale. If an application
needs to create a compound string programmatically, it should use XmStringCreateLocalized() to ensure that
the string is interpreted in the current locale. All of the examples in this book use
XmStringCreateLocalized() to demonstrate the appropriate technique, even though the examples are only
designed to work in the C locale.
With Motif 1.1, you should use the XmStringCreateSimple() routine to create a compound string that uses the
default character set and direction. This function is obsolete in Motif 1.2; it remains for backwards−compatibility
purposes only. With both XmStringCreateLocalized() and XmStringCreateSimple(), you cannot
explicitly specify the tag or the string direction that is used for the compound string, and the string cannot have
multiple lines.
Both XmStringCreateLocalized() and XmStringCreateSimple() allocate memory to store the
compound string that is returned. Widgets that have compound string resources always allocate their own space and
store copies of the compound string values you give them. When you are done using a compound string to set widget
resources, you must free it using XmStringFree(). The following code fragment demonstrates this usage:
XmString str = XmStringCreateLocalized ("Push Me");
XtVaCreateManagedWidget ("widget_name",
xmPushButtonGadgetClass, parent,
XmNlabelString, str,
NULL);
XmStringFree (str);
The process of creating a compound string, setting a widget resource, and then freeing the string is the most common
use of compound strings. However, this process involves quite a bit of overhead, as memory operations are expensive.
Memory is allocated by the string creation function and again by the internals of the widget for its own storage, and
then your copy of the string must be deallocated.
The programmatic interface to the string creation process can be simplified by using the XtVaTypedArg feature in
Xt. This special resource can be used in variable argument list specifications for functions such as
XtVaCreateManagedWidget() and XtVaSetValues(). It allows you to specify a resource using a
convenient type and have Xt do the conversion for you. In the case of compound strings, we can use this method to
convert a C string to a compound string. The following code fragment has the same effect as the previous example:
XtVaCreateManagedWidget ("widget_name",
xmPushButtonWidgetClass, parent,
XtVaTypedArg, XmNlabelString, XmRString,
"Push Me", 8, /* or strlen ("Push Me") + 1 */
NULL);
XtVaTypedArg takes four additional parameters: the name of the resource, the type of the value specified for the
resource, the value itself, and the size of the value. We set the XmN-labelString resource. We want to avoid
converting the character string to a compound string, so we specify a char * value and XmRString as its type. This
terminology may be confusing to a new Motif programmer. Xt uses the typedef String for char *. The
representation type used by Xt resource converters for this type is XtRString (XmRString in Motif). A compound
string, on the other hand, is of type XmString; its representation type is XmRXmString. You just have to read the
symbols carefully. Resource converters are described in detail in Volume Four, X Toolkit Intrinsics Programming
20 Compound Strings 20.2 Creating Compound Strings
565

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.