[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Programmer's Guide



Localizing Applications

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:

  1. Resource files

  2. UID files

  3. Message catalogs

  4. X bitmap files

    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:

    1. The operating system's locale mechanism, if any

    2. The Motif implementation

    3. The application itself

    4. The user's system administrator

    5. The user's language environment

    6. Techniques for Localization

      Although there are different methods for localizing an application, there are some common considerations:

      1. The application should not explicitly code any language-dependent information in the application. This includes strings, fonts, and language-dependent pixmaps.

      2. The application should isolate text, fonts, and pixmaps, and translate them into the languages needed. Usually this information is stored in separate directories by language.

      3. Establishing the Language Environment

        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:

        1. Sets the locale. On ANSI C-based systems, this is done by using the following code:
          setlocale(LC_ALL, 
          language);

          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).

        2. Calls XSupportsLocale to verify that the locale just set is supported. If not, a warning message is issued and the locale is set to "C."

        3. Calls XSetLocaleModifiers specifying the empty string.

        4. Returns the value of the current locale. On ANSI C-based systems, this is the result of calling the following:
          setlocale(LC_ALL, NULL);

          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:

          1. The mechanism, if any, used to set the locale

          2. On ANSI C-based systems, the value returned by setlocale

          3. The possible values of any environment variables used to establish the language environment

          4. Whether or not xnlLanguage is used and, if so, its possible values

            Furthermore, by supplying its own language procedure, an application may use any procedure it wants for setting the language string.

          5. Using Locales

            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:

            1. Establish a language procedure before calling XtAppInitialize. The language procedure calls setlocale.

            2. Localize the compound strings and render tables using resource files, message catalogs, or UID files. Normally, do not specify any charset tags other than XmFONTLIST_DEFAULT_TAG.

            3. Use font sets in resource or UID file font lists.

            4. Use XmStringGenerate to create compound strings in the program, but only use the rendition tag _MOTIF_DEFAULT_LOCALE.

              The run-time locale determines which fonts are used to display text. This is accomplished in the following manner:

              1. Motif calls XtResolvePathname to load resource or UID files that specify the names of fonts for font sets. XtResolvePathname uses a file search path that may vary depending on the display's language string.

              2. XCreateFontSet uses the locale to determine the fonts to be used from the base font name and the locale charset.

                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.

              3. Localization Without Locales

                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:

                1. Localize compound strings by using UIL files. Localized render tables and font lists can appear in resource files.

                2. Specify explicit rendition tags other than _MOTIF_DEFAULT_LOCALE in both compound strings and render tables.

                3. Use font names with explicit charset components in resource or UIL files. Do not use font sets.

                4. To create compound strings in the program, use XmStringGenerate with the rendition tag set to something other than _MOTIF_DEFAULT_LOCALE.

                5. Resources and Localization

                  The resources used in an application that are subject to internationalization ought to be stored in files external to the application. These resources include

                  1. All labels, particularly those that identify controls. Such labels are defined as type XmString, meaning they are compound strings.

                  2. Text strings; that is, strings of text that are not compound strings.

                  3. Render tables.

                  4. Font lists.

                  5. Initial Resource Database

                    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):

                    1. The application command line

                    2. A per-host user environment resource file on the local host

                    3. Screen-specific resources for the default screen of the display

                    4. A resource property on the server or user preference resource file on the local host

                    5. An application-specific user resource file on the local host

                    6. An application-specific class resource file on the local host

                      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.

                    7. Resource File Locations

                      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.

                      An Example

                      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

                      UIL and Localization

                      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.

                      Preparing Localized UID Files

                      When using locales with UIL, an application developer should follow these rules:

                      1. Do not use a character_set declaration for the module.

                      2. When creating compound strings in a UIL file, use double quotes and no character set specification for the text.

                      3. When creating render tables or font lists in a UIL file, use font sets, not fonts. Do not specify character sets for the font sets.

                      4. Before compiling a UIL file via the uil command, set up any environment variables (such as LANG) or other mechanisms the system vendor recommends to establish the locale that is appropriate for the UIL file to be compiled. Invoke the uil command with the -s option. This enables the UIL compiler to set the locale and parse double-quoted strings without explicit character sets in the locale's encoding. It also ensures that localized compound strings and font list entries are created with font list element tags of XmFONTLIST_DEFAULT_TAG.

                      5. Before using the Uil function to compile a UIL file, set the locale that is appropriate for the UIL file to be compiled. In the Uil_command_type structure that is the first argument to the Uil function, set the use_setlocale_flag member to 1. This has the same effect as invoking the uil command with the -s option.

                        When localizing UIL files without using locales, an application developer should follow these rules:

                        1. When using single quotes for the text of compound strings, supply a character_set declaration for the module.

                        2. When using double quotes for the text of compound strings, supply an explicit character set for each text component.

                        3. When creating font lists in a UIL file, use fonts, not font sets. Specify an explicit character set for each font.

                        4. When compiling a UIL file via the uil command, do not invoke the command with the -s option. The UIL compiler does not set the locale, and it parses each string by using rules derived from the explicitly specified character set for that string.

                        5. When compiling a UIL file via the Uil function, set the use_setlocale_flag member of the Uil_command_type structure to 0. This has the same effect as invoking the uil command without the -s option.

                          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.

                        6. MRM and Localized UID Files

                          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:

                          1. If the environment variable UIDPATH is set, the value of that variable is the search path.

                          2. If UIDPATH is not set, but XAPPLRESDIR is set, MrmOpenHierarchyPerDisplay uses a default search path with entries that include $XAPPLRESDIR, the user's home directory, and vendor-dependent system directories.

                          3. If neither UIDPATH nor XAPPLRESDIR is set, MrmOpenHierarchyPerDisplay uses a default search path with entries that include the user's home directory and vendor-dependent system directories.

                            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).

                          4. Message Catalogs and Localization

                            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:

                            1. Using an implementation-dependent method, prepare a separate message catalog containing text to be localized for each language.

                            2. Arrange to have the message catalogs installed in the appropriate directories on the systems on which the application will run.

                            3. Arrange for the user's environment to be set up correctly so that the application can read the message catalog appropriate to the language.

                            4. In the program, use the catopen function to open a message catalog and the catclose function to close it.

                            5. Use the catgets function to read text from an open message catalog.

                            6. If necessary, convert the text to the target format (such as a compound string) and, for resources, supply the text in the appropriate widget creation argument list or call to XtSetValues.

                              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.

                            7. Images, Pixmaps, and Localization

                              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:

                              1. If the environment variable XBMLANGPATH is set, the value of that variable is the search path.

                              2. If XBMLANGPATH is not set but XAPPLRESDIR is set, XmGetPixmapByDepth uses a default search path with entries that include $XAPPLRESDIR, the user's home directory, and vendor-dependent system directories.

                              3. If neither XBMLANGPATH nor XAPPLRESDIR is set, XmGetPixmapByDepth uses a default search path with entries that include the user's home directory and vendor-dependent system directories.

                                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.

                              4. Comparing Approaches to Localization

                                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.


                                [ Previous | Next | Contents | Glossary | Home | Search ]