The following three examples retrieve the same strings, but have different effects on the text
domain. The ﬁrst example does not change the current text domain. The second and third
examples change the current text domain to library_error_strings, then retrieve the
foreign language string of wrongbutton.
message = dgettext("library_error_strings",
message = gettext("wrongbutton");
message = dgettext("", "wrongbutton"); \\* "" = current domain *\\
If XV_LOCALE_DIR is set in xv_init(), XView calls bindtextdomain() on the appli-
cation’s behalf to prepend the pathname speciﬁed by XV_LOCALE_DIR to the default domain
path list. All unbound text domains would be located in the directory with the general format:
<XV_LOCALE_DIR>/<Display Language Setting>/LC_MESSAGES/domain
"domain” is the name of the text domains. The default value of XV_LOCALE_DIR is
An example, using XV_LOCALE_DIR follows:
xv_init(XV_INIT_ARGS, argc, argv,
22.2.2 Creating a Text Domain
Once the program is written using gettext() and dgettext(), text domains are created
using the following procedures:
1. For example, you could run xgettext on the following source ﬁle fragment (see the
man page for xgettext for proper usage):
message1 = dgettext("library_error_string", "Save");
message2 = dgettext("library_error_string", "File");
message3 = dgettext("library_error_string", "Edit");
This ﬁlter extracts the strings from the source ﬁles, and places them in a portable message
ﬁle. The format of the portable message ﬁle produced is shown below:
The xgettext ﬁlter currently does not expand #define commands. If you have
#define strings which need to be extracted, then you need to run your application
through the C preprocessor as follows:
cc -P file.c
This runs the source ﬁle through the C preprocessor only, and outputs to a ﬁle with a suf-
ﬁx, .i. You should then run this .i ﬁle through xgettext to extract all strings:
xgettext xgettext options file.i
This will produce a ﬁle called library_error_string.po.
2. Add the foreign language equivalents for all the native language strings in the portable
message ﬁle between quotes next to msgstr. Use a plain text editor that supports the
character set/encoding for the language.
msgstr "<french for File>"
msgstr "<french for Save>"
msgstr "<french for Edit>"
If you wish to create multiple text domains, you may separate the related text strings into
separate ﬁles. Be sure that the ﬁrst line of every ﬁle consists of a domain line at the begin-
ning of each ﬁle. You may also have multiple text domains within the same ﬁle. To do
this, simply start each new domain with the line:
where domain_name is the name of the text domain. Note that the message identiﬁers and
strings of a particular domain must be in the same ﬁle under the same domain name.
3. Run the msgfmt program on each portable message ﬁle to produce the text domain ﬁle:
This produces the text domain ﬁle library_error_string.mo, which contains the messages
compiled in an internal format. The text domain ﬁle is in binary format, and is not inter-
changeable between CPU architectures. It cannot be edited using an editor, and must be
created using msgfmt.
4. Move each text domain to the directory under the path speciﬁed as follows:
548 XView Programming Manual
As mentioned previously, gettext() and dgettext() search the text domain for the
native language text or key value, then extract the corresponding foreign language text.
The key is a unique name that identiﬁes the string to be retrieved. The key does not have
to be the native language string, but the native language string is a good choice since it
tends to be self-documenting.
22.2.3 New and Enhanced XView Attributes for gettext()
NOTICE_MESSAGE_STRING speciﬁes text to print in a notice. NOTICE_MESSAGE_STRING is
necessary when using gettext() to get a notice message. The value of this attribute is a
single NULL-terminated string, which may contain “\n” as a line break. NOTICE_MES-
speciﬁes the text to print in a notice. The value is NULL-terminated list of
strings, which may contain “\n” as a line break. NOTICE_MESSAGE_STRINGS_ARRAY_PTR
speciﬁes the text to print in a notice. The value is a variable pointing to a NULL-terminated
array of strings, which may contain “\n” as a line break.
This example shows how notices are displayed in XView Version 2.
result = notice_prompt( panel , NULL,
NOTICE_BUTTON, "Update changes" , 101,
NOTICE_BUTTON, "Ignore changes" , 102,
NOTICE_BUTTON, "Destroy everything" ,103,
NOTICE_MESSAGE_STRINGS, "Press button,"
"then go home" ,
This example uses NOTICE_MESSAGE_STRING and makes the same notice window as the pre-
result = notice_prompt( panel , NULL,
NOTICE_BUTTON, "Update changes", 101,
NOTICE_BUTTON, "Ignore changes", 102,
NOTICE_BUTTON, "Destroy everything", 103,
NOTICE_MESSAGE_STRING, "Press button,\nthen go home" ,
This example shows how to embed gettext().
result = notice_prompt( panel , NULL,
NOTICE_BUTTON, gettext("Update changes" ), 101,
NOTICE_BUTTON, gettext("Ignore changes" ), 102,
NOTICE_BUTTON, gettext(" Destroy everything" ), 103,
NOTICE_MESSAGE_STRING, gettext(" Press button,\n then go home" ),
22.3 Object Layout and Customization
The layout of screen objects (buttons, panel items, etc.) needs to change when the dimensions
of the strings within those objects change. For example, a button string in French might be
much longer than the same button string in English, thus requiring other buttons to be reposi-
tioned. Another example of object layout changes are objects that have to be repositioned to
accommodate locale-speciﬁc representations such as date or time. A mechanism is required
to alter the layout during localization.
22.3.1 Implicit and Explicit
Object layout of an XView application may be implicit or explicit. Using explicit layout, the
application speciﬁes x and y coordinates for the objects in the application. Implicit layout
relies on certain defaults that are built into the toolkit. Thus, if a series of panel items is
created, and no layout information is explicitly speciﬁed, the panel package will position the
items based on default spacing rules. For example, one rule is to start a new row when a
panel item extends past the edge of a panel.
Implicit positioning may be all that is required to localize an application. When the locale is
switched, the new strings are picked up and the panel package automatically adjusts the lay-
out of the panel items based on the dimensions of the new strings.
Other scenarios may exist, however, where explicit layout is required. One situation where
implicit positioning does not provide a satisfactory layout is when switching locales. Another
scenario requiring explicit repositioning is when accommodating changes in format when
locales are switched. For example, the date representation in the United States is mm/dd/yy,
while in India the date is represented as dd/mm/yy. Reliance on such explicit formats requires
modiﬁcation during localization.
The attributes, XV_USE_DB and XV_INSTANCE_NAME, allow developers to specify customiz-
able attributes. These attributes can be used to specify explicit object layout.
22.3.2 Layout and Customization API
Each application may have one or more locale-speciﬁc application defaults ﬁles. These ﬁles
provide layout information and any other data stored under the X Resource Manager that is
speciﬁc to a given locale.
The directory structure for the locale-speciﬁc defaults ﬁles used by the layout scheme is:
<XV_LOCALE_DIR>/locale/app-defaults/<appname>.db (read first)
where locale is the current setting of Basic Locale.
550 XView Programming Manual
Typically an application would have its locale-speciﬁc application defaults ﬁle (one ﬁle) in:
If the application wants to group its application defaults into multiple ﬁles, they can be
placed in the directory:
XV_USE_DB can be used to specify a set of attributes that are to be searched in the X11
Resource Manager database. XV_USE_DB takes a NULL-terminated list of attribute value pairs
as its values. During program execution, each attribute in this NULL-terminated list is looked
up in the X11 Resource Manager database. If the attribute is not found in the database, then
the value speciﬁed in the attribute-value pair is used as the default value.
XV_INSTANCE_NAME is used to associate an instance name with an XView
object. The instance name is used to construct the key value (resource name) used by the
resource manager to perform the lookup. The key value is constructed by concatenating the
instance names of all objects in the current object’s lineage, starting with the name of the
application or whatever was passed in with the -name command-line option. The XView
attribute name remains in lowercase.
An example using
XV_INSTANCE_NAME is shown below. Assume that the application name is
“app.” The key value is constructed by concatenating “app,” “frame1,” and “panel1.” Thus,
resource ﬁles containing entries such as the following would be speciﬁed as in Example 22-1:
Example 22-1. Using
XV_INIT_ARGC_PTR_ARGV, &argc, argv,
frame = (Frame)xv_create(0, FRAME,
XV_INSTANCE_NAME, "frame1" ,
panel = (Panel)xv_create(frame, PANEL,
XV_INSTANCE_NAME, "panel1" ,