An internationalized application can be tailored to operate in many areas of the world, each with its own requirements for the language and customs to be used. This section explains some methods for localizing an application.
The following section describes how the user and the application developer (and perhaps the system administrator) establish the language environment of an application. It then discusses two general approaches to localizing applications. Succeeding sections focus on four aspects of localizing information in Motif programs:
Many aspects of localization depend on the particular operating system, Motif implementation, and user environment in which the application runs. The following must all cooperate for correct localization to occur:
Although there are different methods for localizing an application, there are some common considerations:
The term language environment refers to the set of localized data that the application needs in order to run correctly in the user-specified locale. A language environment supplies the rules associated with a specific language. In addition, the language environment consists of any externally stored data, such as localized strings or text used by the application. For example, the menu items displayed by an application might be stored in separate files for each language supported by the application. This type of data can be stored in resource files, UID files, or, on XPG3-compliant systems, message catalogs.
A single language environment is established when an application executes. The actual language environment in which an application operates is specified by the application user, often either by setting an environment variable ( LANG on POSIX-based systems) or by setting the xnlLanguage resource. The application then sets the language environment based on the user's specification. The application can do this either by using setlocale in a language procedure established by XtSetLanguageProc, or by using a method that does not call setlocale. In either case, Xt caches a per-display language string that is used by XtResolvePathname to find resource, bitmap, and UIL files.
An application that supplies a language procedure may either provide its own or use an Xt default procedure. In either case, the application establishes the language procedure by calling XtSetLanguageProc before calling XtAppInitialize. When a language procedure is installed, Xt calls it in the process of constructing the initial resource database. Xt uses the value returned by the language procedure as its per-display language string.
The default language procedure performs the following tasks:
where language is the value of xnlLanguage or the empty string ("") if xnlLanguage is not set. When xnlLanguage is not set, the locale is generally derived from an environment variable ( LANG on POSIX-based systems).
The application can use the default language procedure by making the call to XtSetLanguageProc in this manner:
XtSetLanguageProc(NULL, NULL, NULL); toplevel = XtAppinitialize(...);
By default, Xt does not install any language procedure. If the application does not call XtSetLanguageProc, Xt uses as its per-display language string the value of the xnlLanguage resource if it is set. If xnlLanguage is not set, Xt derives the language string from the environment. On POSIX-based systems, this is the value of the LANG environment variable.
It is important to note that the per-display language string that results from this process is implementation dependent and that Xt provides no public means of examining the language string once it is established. The following vary by operating system and by Motif implementation:
Furthermore, by supplying its own language procedure, an application may use any procedure it wants for setting the language string.
The locale provides local information to an application based on the user's language, territory, and code set. Both language and territory are needed because some languages are spoken in more than one country and more than one language may be spoken in some countries. (French is an example of the first, and Belgium, Canada, and Switzerland are examples of the second.)
Information in resource, UID, and image files can be localized and stored in separate directories by language. The Xt function XtResolvePathname uses the run-time locale to determine the proper directory to use.
On XPG3-compliant systems, an application can use message catalogs to localize text and messages. A message catalog file exists for each language, and each is usually stored in a separate directory by language.
The locale method of localizing compound strings and font lists consists of the following steps:
The run-time locale determines which fonts are used to display text. This is accomplished in the following manner:
In this method, the application usually does not specify charset tags other than XmFONTLIST_DEFAULT_TAG. It is possible to supply explicit rendition tags with locale-dependent text. For example, text might be displayed using large and small fonts or bold and italic fonts. The application can do this with special tags in both the compound string and the render table associated with it. In the render table, match the tag with a font set specification that supplies the desired attribute (point size, for example). When the application creates the font set, the charset comes from the locale. For example, a resource file might specify a render table in the following manner to obtain fonts with a different point size:
*fontList: -*-*-*-R-Normal--*-120-100-100-*-*:,\ -*-*-*-R-Normal--*-180-100-100-*-*:BIG,\ -*-*-*-R-Normal--*-80-100-100-*-*:SMALL
See Chapter 9 for more information about fonts and controlling font selection.
In this method, the locale is not set in the program, and a language procedure is not needed. Instead, the user specifies the language environment by using either xnlLanguage or an environment variable such as LANG. Resource, UID, and image files are localized and stored in separate directories by language, as they are when the application uses locales. XtResolvePathname uses the display's language string in the same way to determine the proper locations of these files.
Message catalogs are not used in this method. Also, in this case Text and TextField cannot accommodate 16-bit data.
The nonlocale method of localizing compound strings and render tables consists of these steps:
The resources used in an application that are subject to internationalization ought to be stored in files external to the application. These resources include
The information in the external resource files is used when Xt builds the initial resource database. The XtDisplayInitialize function loads the resource database by merging in resources from the following sources, in order of precedence (that is, each component takes precedence over the following components):
Localization applies to two components of the initial resource database--the application-specific user and class resources. Localized resources that are controlled by the programmer are in the application class resource file, and localized resources that are controlled by the user are in the user resource file. Note that the user resources take precedence over the application class resources.
XtDisplayInitialize calls XtResolvePathname to load both the user and the class resources.
To load the user's application resource file, XtDisplayInitialize uses the value of the XUSERFILESEARCHPATH environment variable as the search path. If that variable is not set or if the search path fails to find the file, and if the environment variable XAPPLRESDIR is defined, XtDisplayInitialize next tries an implementation-dependent search path with a number of entries that include XAPPLRESDIR and the user's home directory. If XAPPLRESDIR is not set or if that search path fails, XtDisplayInitialize tries another implementation-dependent search path with a number of entries that include the user's home directory.
To load the application-specific class resource file, XtDisplayInitialize uses the value of the XFILESEARCHPATH environment variable as the search path. If that variable is not set or if the search path fails to find the file, XtDisplayInitialize tries an implementation-dependent search path.
The search paths for both resource files may contain any substitutions recognized by XtResolvePathname. That routine substitutes the display's language string for %L. In an implementation-dependent manner, it substitutes the language, territory, and code set components of the language string for %l, %t, and %c, respectively. This mechanism allows Xt to load different resource files for different languages, as specified by the display's language string.
The display's language string is determined by the application's language procedure, if present, or else by the value of the xnlLanguage resource or by the environment. The language string associated with any particular language and the search paths used to find the resource files depend on the system vendor, the Motif vendor, the application, and the user's system administrator. Determining the actual directories in which localized resource files reside requires coordination among all these sources.
In general, an application developer prepares a set of localized application class resource files, one for each language the application supports. The developer may also need to supply a language procedure appropriate for one or more of the systems on which the application will run. The application vendor must arrange for the resource files to be installed in the correct directories, depending on the operating system and the Motif implementation on which the application will run.
Following is an example of an application class defaults file for a simple program that creates a MainWindow with a Text widget. Because the render table specification includes a single rendition with a default tag, this resource file would be appropriate for an application that uses locales.
*renderTable.fontName: -*-*-*-R-Normal--*-180-100-100-*-* *renderTable.fontType: XmFONT_IS_FONTSET *Text1.value:\ Hier ist etwas Text fur das Text Widget.\n\ Gemischter 8-und 16-bit Text. *version_box.messageString: Dies ist i18n Demo Version *version_box.okLabelString: Schliessen *version_box.dialogTitle: I18n Demo Version *pgm_ver_btn.labelString: I18n Demo Version *events_btn.labelString: Aktionen *help_btn_menu.labelString: Hilfe *help_btn_cascade.labelString: Hilfe *help_box.messageString: Leider ist keine Hilfe hier. *help_box.okLabelString: Schliessen *help_box.dialogTitle: i18n Demo Hilfe *stop_btn.labelString: Enden
The general models for localizing applications that use UIL are the same as those for applications that do not use UIL. An application developer creates separate UIL files, each containing string and resource values for a particular language. UIL files can also be used in conjuction with localized resource and pixmap files. As with localization of resource files, there are two basic approaches to localizing UIL files: one that uses locales and one that does not.
When using locales with UIL, an application developer should follow these rules:
When localizing UIL files without using locales, an application developer should follow these rules:
The UIL compiler processes a single source file for each invocation of the uil command or the Uil function. However, UIL has an include file directive that is similar to the C preprocessor's #include directive. If the file argument for this directive is not an absolute pathname, the compiler searches for the file in a series of directories. These include the directory of the main UIL source file and any directories specified via the -I option to the uil command or the include_dir member of the Uil_command_type structure for the Uil function.
One strategy for maintaining localized UIL source files is to place only language-independent information in the main UIL source file and to put all language-dependent information in included files that are in separate directories for each language. Then a developer can compile the UIL files for different languages without editing any UIL files. When using locales, a developer first sets up the environment for the intended locale. Whether using locales or not, the developer then invokes the UIL compiler with the proper include directory for the intended language.
In general, a developer can mix localized UIL files with localized resource files. For example, the developer might specify compound strings in UIL files and render tables in resource files. Note one exception: it is not practical to use resource files to localize compound strings without using locales. This is because no resource file syntax exists for supplying an explicit charset/locale tag for a compound string.
For resource values that the user may override, the developer must use resource files or fallback resources, or must in some way ensure that the user's resource settings can override the developer's settings from the UIL file.
Once the developer has generated localized UID files, the vendor and the user's system administrator must arrange for these files to be installed in the appropriate directories for the system where the program is to run. As with resource files, these directories depend on configurations established by the operating system vendor, the Motif vendor, and the system administrator.
MrmOpenHierarchyPerDisplay takes as an argument a list of names of UID files. It calls XtResolvePathname to find each file the list. If a filename is an absolute pathname, that pathname is the search path for XtResolvePathname. Otherwise, MrmOpenHierarchyPerDisplay constructs a search path in the following way:
These paths may include the substitution field %U. In each call to XtResolvePathname, MrmOpenHierarchyPerDisplay substitutes the current filename from the list of UID files for %U. The paths may also include other substitution fields accepted by XtResolvePathname. In particular, XtResolvePathname substitutes the display's language string for %L, and it substitutes the components of the display's language string (in a vendor-dependent way) for %l, %t, and %c. If necessary MrmOpenHierarchyPerDisplay searches the path twice, first with %S mapped to .uid and then with %S mapped to NULL. The substitution field %T is always mapped to uid.
The usual mechanism for employing localized UID files is to use a search path that contains one of the substitutions derived from the display's language string. As with resource files, the vendor and system administrator must ensure that the directories where the localized UID files reside match the display's language string (or the appropriate component of the language string).
On an XPG3-compliant system, an application can use message catalogs to localize text. The format of message catalogs is implementation dependent, and the application must take steps to coordinate the locations of the message catalogs with the locations of resource, UID, and image files. Use of message catalogs requires the following steps:
The catopen function takes as an argument the name of the message catalog file. If this is an absolute pathname, catopen opens that file. Otherwise, catopen uses the value of the NLSPATH environment variable as a search path. This path can contain a number of substitution fields. The filename passed to catopen is substituted for %N. The value of the LANG environment variable is substituted for %L, and its language, territory, and code set components are substituted for %l, %t, and %c, respectively.
Note that these values may not be the same as the display's language string or its components. An application and software vendor that use message catalogs must coordinate the locations of message catalogs with those of localized resource, UID, and image files, which usually depend on the display's language string. One possible strategy is to call catopen with an absolute pathname constructed by calling XtResolvePathname with the value of NLSPATH as the search path argument. XtResolvePathname substitutes the display's language string and its components for %L, %l, %t, and %c in $NLSPATH. In this way, the application can use a single mechanism, the display's language string, to distinguish file locations by language. The software vendor must still arrange for the user's system administrator to install the message catalogs in the correct locations and to ensure that NLSPATH is appropriately set in the user's environment.
A pixmap is a screen image that is stored in memory so that it can be recalled and displayed when needed. Motif has a number of pixmap resources that allow the application to supply pixmaps for backgrounds, borders, shadows, label and button faces, drag icons, and other uses. As with text, some pixmaps may be specific to particular language environments; these pixmaps need to be localized.
Motif maintains caches of pixmaps and images. The function XmGetPixmapByDepth searches these caches for a requested pixmap. If the requested pixmap is not in the pixmap cache and a corresponding image is not in the image cache, XmGetPixmapByDepth searches for an X bitmap file whose name matches the requested image name. XmGetPixmapByDepth calls XtResolvePathname to search for the file. If the requested image name is an absolute pathname, that pathname is the search path for XtResolvePathname. Otherwise, XmGetPixmapByDepth constructs a search path in the following way:
These paths may include the substitution field %B. In each call to XtResolvePathname, XmGetPixmapByDepth substitutes the requested image name for %B. The paths may also include other substitution fields accepted by XtResolvePathname. In particular, XtResolvePathname substitutes the display's language string for %L, and it substitutes the components of the display's language string (in a vendor-dependent way) for %l, %t, and %c. The substitution field %T is always mapped to bitmaps, and %S is always mapped to NULL.
As with resource and UID files, the usual mechanism for employing localized X bitmap files is to use a search path that contains one of the substitutions derived from the display's language string. As with resource and UID files, the vendor and system administrator must ensure that the directories where the localized X bitmap files reside match the display's language string (or the appropriate component of the language string).
See Chapter 12 for more information on images and pixmaps.
The locale approach allows an application to use existing internationalization routines. On the other hand, the application is limited in portability to systems that support the same internationalization standards (XPG3, POSIX, or ANSI). This approach is also only applicable to applications using a single language.
The nonlocale approach only addresses the aspect of isolating information from the application and ensuring that it uses the proper localized version of this information. The disadvantage is that there is more work for the programmer and there may be nonstandard functionality. The advantages are that there is guaranteed portability across all platforms that support Motif, and that it allows handling of multiple character sets for specialized applications that require this functionality.