The following three examples retrieve the same strings, but have different effects on the text
domain. The first 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 *\\ XV_LOCALE_DIR
If XV_LOCALE_DIR is set in xv_init(), XView calls bindtextdomain() on the appli-
cation’s behalf to prepend the pathname specified 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,
XV_LOCALE_DIR, "/app_home/lib/locale",
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 file 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");
Internationalization 547
This filter extracts the strings from the source files, and places them in a portable message
file. The format of the portable message file produced is shown below:
domain "library_error_strings
msgid "File"
msgid "Save"
msgid "Edit"
The xgettext filter 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 file through the C preprocessor only, and outputs to a file with a suf-
fix, .i. You should then run this .i file through xgettext to extract all strings:
xgettext xgettext options file.i
This will produce a file called library_error_string.po.
2. Add the foreign language equivalents for all the native language strings in the portable
message file between quotes next to msgstr. Use a plain text editor that supports the
character set/encoding for the language.
domain "library_error_strings
msgid "File"
msgstr "<french for File>"
msgid "Save"
msgstr "<french for Save>"
msgid "Edit"
msgstr "<french for Edit>"
If you wish to create multiple text domains, you may separate the related text strings into
separate files. Be sure that the first line of every file consists of a domain line at the begin-
ning of each file. You may also have multiple text domains within the same file. To do
this, simply start each new domain with the line:
domain "domain_name"
where domain_name is the name of the text domain. Note that the message identifiers and
strings of a particular domain must be in the same file under the same domain name.
3. Run the msgfmt program on each portable message file to produce the text domain file:
msgfmt library_error_string.po
This produces the text domain file library_error_string.mo, which contains the messages
compiled in an internal format. The text domain file 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 specified 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 identifies 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 specifies 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-
specifies 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
specifies 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,
"then go home" ,
This example uses NOTICE_MESSAGE_STRING and makes the same notice window as the pre-
vious example.
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" ),
Internationalization 549
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-specific 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 specifies 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 specified, 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
modification 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 XV_LOCALE_DIR
Each application may have one or more locale-specific application defaults files. These files
provide layout information and any other data stored under the X Resource Manager that is
specific to a given locale.
The directory structure for the locale-specific defaults files 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-specific application defaults file (one file) in:
If the application wants to group its application defaults into multiple files, they can be
placed in the directory:
<XV_LOCALE_DIR>/locale/app-defaults/<appname>/*.db XV_USE_DB
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 specified in the attribute-value pair is used as the default value. XV_INSTANCE_NAME
The attribute
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 files containing entries such as the following would be specified as in Example 22-1:
app.frame1.panel1.xv_x: 20
app.frame1.panel1.xv_y: 20
Example 22-1. Using
(void)xv_init(XV_USE_LOCALE, TRUE,
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" ,
XV_X, 10,
XV_Y, 15,
Internationalization 551

Get Volume 7A: XView Programming Manual now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.