All internationalized programs should set the locale desired by the user as defined in the locale environment variables. For programs using the desktop toolkit, the programs call the XtSetLanguageProc()
function prior to calling any toolkit initialization function; for example, XtAppInitialize()
. This function does all of the initialization necessary prior to the toolkit initialization. For nondesktop programs, the programs call the setlocale()
function to set the locale desired by the user at the beginning of the program.
Locale environment variables (for example, LC_ALL
, LC_CTYPE
, and LANG
) are used to control the environment. Users should be aware that the LC_CTYPE
category of the locale is used by the X and Xm libraries to identify the locale-specific features used at run time. Yet, the LC_MESSAGES
category is used by the message catalog services to load locale-specific text. Refer to "Extracting Localized Text" for more information. Specifically, the fonts and input method loaded by the toolkit are determined by the setting of the LC_CTYPE
category.
String encoding (for example, ISO8859-1 or Extended UNIX Code (EUC), in an application's source code, resource files, and User Interface Language (UIL) files) should be the same as the code set of the locale where the application runs. If not, code conversion is required.
All components are shipped as a single, worldwide executable and are required to support the R5 sample implementation set of locales:
US, Western/Eastern Europe, Japan, Korea, China, and Taiwan.
Applications should be written so that they are code-set-independent and include support for any multibyte code set.
The following are the functions used for locale management:
For example:
-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1
The last two fields of this XLFD name are iso8859
and 1
. These fields specify that the ISO8859-1 standard glyphs are contained in the font. Further, it specifies that the character code values of the ISO8859-1 standard are used to index the corresponding glyph for each character.
The font charset used by the application to render data depends on the locale you select. Because the font charset of the data changes is based on the choice of locale, the font specification must not be hardcoded by the application. Instead, it should be placed in a locale-specific app-defaults
file, allowing localized versions of the app-defaults
file to be created.
Further, the font should be specified as a fontset. A fontset is an Xlib concept in which an XLFD is used to specify the fonts. The font charset fields of the XLFD are specified by the Xlib code that creates the fontset and fills in these fields based on the locale that the user has specified.
For many languages (such as Japanese, Chinese, and Korean), multiple font charsets are combined to support single encoding. In these cases, multiple fonts must be opened to render the character data. Further, the data must be parsed into segments that correspond to each font, and in some cases, these segments must be transformed to convert the character values into glyphs indexes. The XFontset
, which is a collection of all fonts necessary to render character data in a given locale, also deals with this set of problems. Further, a set of rendering and metric routines are provided that internally take care of breaking strings into character-set-consistent segments and transforming values into glyph indexes. These routines relieve the burden of the application developer, who needs only the user fontsets and the new X11R5 rendering and metric application program interfaces (APIs).
XmFontSet
for specifying the locale-dependent fonts. Specific fonts within a font set should be specified using XLFD naming conventions without the charset field specified. The resource name for an XFontset
is *fontSet
. Refer to "Localized Resources" for a list of font resources.
Applications directly using Xlib to render text (as opposed to using XmString
functions or widgets) may take advantage of the string-to-fontSet converter provided by Xt. For example, the following code fragment shows how to obtain a fontset when using Xt and when not using Xt:
/* pardon the double negative... means "If using Xt..." */
#ifndef NO_XT
typedef struct {
XFontSet fontset;
char *foo;
} ApplicationData, *ApplicationDataPtr;
static XtResource my_resources[] = {
{ XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet),
XtOffset (ApplicationDataPtr, fontset), XtRString,
"*-18-*"}}
#endif /* NO_XT */
...
#ifdef NO_XT
fontset = XCreateFontSet (dpy, "*-18-*", &missing_charsets,
&num_missing_charsets. &default_string);
if (num_missing_charsets > 0) {
(void) fprintf(stderr, "&s: missing charsets.\n",
program_name);
XFreeStringList(missing_charsets);
}
#else
XtGetApplicationResources(toplevel, &data, my_resources,
XtNumber(my_resources), NULL, 0);
fontset = data.fontset;
#endif /* NO_XT */
XFontStruct
, unless they are being used for a specific charset and a specific character set. Use of XFontStruct
may be limiting if the server you are connecting to does not support the specific charsets needed by a locale. The resource name for an XFontStruct
is *font.XmString
to draw localized text are required to specify an XFontList
name for specifying fonts. A font list is a list of one or more fontsets or fonts, or both. It is used to convey the list of fonts and fontsets a widget should use to render text. For more complicated applications, a font list may specify multiple font sets with each font set being tagged with a name; for example, Bold, Large, Small, and so on. The tags are to be associated with a tag of an XmString
segment. A tag may be used to identify a specific font or fontset within a font list.
Table 2-1 Font Set and Font List Syntax
Here are some examples of font resource specifications:
app_foo*fontList: -adobe-courier-medium-r-normal--24-240-75-75-m-\
150-*:
The preceding fontList specifies a fontset, consisting of one or more 24-point Adobe Courier fonts, as appropriate for the user's locale.
app_foo*fontList: -adobe-courier-medium-r-normal--18-*; *-gothic-\
*-18-*:
This fontList specifies a fontset consisting of an 18-point Courier font (if available) for some characters in the users data, and an 18-point Gothic font for the others.
Motif-based applications sometimes need direct access to the font set contained in a font list. For example, an application that uses a DrawingArea
widget may want to label one of the images drawn there. The following sample code shows how to extract a font set from a font list. In this example, the tag XmFONTLIST_DEFAULT_TAG
looks for the font set because this is the tag that says "codeset of the locale." Applications should use the tag XmFONTLIST_DEFAULT_TAG
for any string that could contain localized data.
XFontSet FontList2FontSet( XmFontList fontlist)
{
XmFontContext context;
XmFontListEntry next_entry;
XmFontType type_return = XmFONT_IS_FONT;
char* font_tag;
XFontSet fontset;
XFontSet first_fontset;
Boolean have_font_set = False;
if ( !XmFontListInitFontContext(&context, fontlist)) {
XtWarning("fl2fs: can't create fontlist context...");
exit 0;
}
while ((next_entry = XmFontListNextEntry(context) != NULL) {
fontset = (XFontSet) XmFontListEntryGetFont(next_entry,
&type_return);
if (type_return == XmFONT_IS_FONTSET ) {
font_tag = XmFontListEntryGetTag(next_entry);
if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag) {
return fontset;
}
/* Remember the 1st fontset, just in case... */
if (!have_font_set) {
first_fontset = fontset;
have_font_set = True;
}
}
}
if (have_font_set)
return first_fontset;
return (XFontSet)NULL;
}
Yet, when selecting the base font names of a font set for various locales, this task can be difficult because an XLFD font specification consists of 15 fields. For localized usage, the following fields are critical for selecting font sets:
Throughout this documentation, the following convention should be used when specifying localized fonts:
-dt-%F-%W-%S-normal-%A-*-*-*-%SP-*
The following describes the minimum set of recommended values for each field to be used within the desktop for the critical fields when specifying font sets in resource (app-defaults) files.
XmStringCreateLocalized()
. The tag associated with localized text is XmFONTLIST_DEFAULT_TAG
, which is used to match an entry in a font list. Applications that mix several fonts within a compound string using XmStringCreate()
should use XmFONTLIST_DEFAULT_TAG
as the tag for any localized string.
More importantly, for interclient communications, the XmStringConvertToCT()
function associates a segment tagged as XmFONTLIST_DEFAULT_TAG
as being encoded in the code set of the locale. Otherwise, depending on the tag name used, the Xm library may not be able to properly identify the encoding on interclient communications for text data.
A localized string segment inside an XmString
can be drawn with a font list having a font set with XmFONTLIST_DEFAULT_TAG. Use of a localized string is recommended for portability.
The following is an example of creating a font list for drawing a localized string:
XmFontList CreateFontList( Display* dpy, char* pattern)
}
SmFontListEntry font_entry;
XmFontList fontlist;
font_entry = XmFontListEntryLoad( dpy, pattern,
XmFONT_IS_FONTSET,
XmFONTLIST_DEFAULT_TAG);
fontlist = XmFontListAppendEntry(NULL, font_entry);
/* XmFontListEntryFree(font_entry); */
if ( fontlist == NULL ) {
XtWarning("fl2fs: can't create fontlist...");
exit (0);
}
return fontlist;
}
int main(argc,argv)
int argc;
char **argv;
}
Display *dpy; /* Display */
XtAppContext app_context;/* Application Context */
XmFontList fontlist;
XmFontSet fontset;
XFontStruct** fontstructs;
char** fontnames;
int i,n;
char *progrname; /* program name without the full pathname */
if (progname=strrchr(argv[0], `/')){
progname++;
}
else {
progname = argv[0];
}
/* Initialize toolkit and open display.
*/
XtSetLanguageProc(NULL, NULL, NULL);
XtToolkitInitialize():
app_context = XtCreateApplicationContext();
dpy = XtOpenDisplay(app_context, NULL, progname, "XMdemos",
NULL, 0, &argc, argv);
if (!dpy) {
XtWarning("fl2fs: can't open display, exiting...");
exit(0);
}
fontlist = CreateFontList(dpy, argv[1] );
fontset = FontList2FontSet( fontlist );
/*
* Print out BaseFontNames of Fontset
*/
n = XFontsOfFontSet( fontset, &fontstructs, &fontnames);
printf("Fonts for %s is %d\n", argv[1], n);
for (i = 0 ; i < n ; ++i ) printf("font[%d} - %s\n", i,\
fontnames[i] );
exit(1);
}
A localized string can be written in resource files because a compound string specified in resource files has a locale-encoded segment with Xm_FONTLIST_DEFAULT_TAG
. For example, the fontList resource in the following example is automatically associated with XmFONTLIST_DEFAULT_TAG
.
The following set oflabelString: Japanese string
*fontList:-dt-interface system-medium-r-normal-L*-*-*-*-*-*-*:
XmString
functions is recommend for internationalization:
XmString
functions is not recommend for internationalization because it takes a direction that may not work with languages not covered:
The local input method means that the input method is built in the Xlib. It is typically used for a language that can be composed using simple rules and that does not require language-specific features. The network-based input method means that the actual input method is provided as separate servers, and Xlib communicates with them through the XIM protocol to do the language-specific composition.
Text
widget to do all text input. XmIm
functions are recommended because the style and geometry management needed for an input method is managed by the VendorShell
widget class. The application need only worry about handling key events, focus, and communicating the current input location within the drawing area. Using these functions requires some basic knowledge of the underlying Xlib input method architecture, but a developer need only be concerned with the XmIm
pieces of information.
The core Xlib provides the common set of interfaces that allow an application to display intermediate feedback during preediting. By registering the application's callbacks and setting the preediting style to XNPreeditCallbacks
, an application can get the intermediate preediting data from the input method and can draw whatever it needs.
Applications intended to do sophisticated language processing may recognize extensions within a specific XIM implementation and its input method engines. Such applications are on the leading edge and will require familiarity with details of the XIM functions.
Text
or TextField
widget is recommended. Besides resources, all of the XmTextField
and XmText
functions are available for getting and for setting localized text inside a Text[Field]
widget.
Most XmText
functions are based on the number of characters, not on the number of bytes. For example, all XmTextPosition()
function positions are character positions, not byte positions. The XmTextGetMaxLength()
function returns the number of bytes. When in doubt, remember that positions are always in character units.
The width of a Text
or TextField
widget is determined by the resource value of XmNcolumns
. But, this value means the number of the widest characters in the font set, not the number of bytes or columns. For example, suppose that you have selected a variable-width font for the Text
widget. The character i may have a width of 1 pixel, while the character W may have a width of 7 pixels. When a value of 10 is set for XmNcolumns
, this is considered a request to make the Text
widget wide enough to be able to display at least 10 characters. So the Text
widget must use the width of the widest character to determine the pixel width of its core widget. With this example, it may be able to display 10 W characters in the widget, or 70 i characters. This structure for XmNcolumns
may cause problems in locales whose code set is a multibyte and a multicolumn encoding. As such, this value should be set within a localized resource.
The following section identifies the set of functions available for applications that are used to manage input methods. For applications that use the Text
and TextField
widgets, refer to "Input Method (Keyboards)".
TextField
or Text
widget to do so. For example, an application using a DrawingArea
widget may allow the user to type in text directly into the DrawingArea. In this case, the application could use the Xlib XIM functions as described in later sections, or alternatively, the application may use the XmIm
functions of Motif 1.2. The XmIm
functions allow an application to connect to and interact with an input method with a minimum of code. Further, it allows the Motif VendorShell
widget to take care of geometry management for the input method on the application's behalf.
Although the XmIm
functions are shipped in all implementations of Motif 1.2, the functions are not documented in Motif 1.2. OSF has announced its intention to augment and document the XmIm
functions for Motif 2.0. The functions described here are the Motif 1.2 XmIm
functions.
XmIm
functions do not support preedit callback style or status callback style input methods. The preedit callback can be used by the Xlib API. For more information, see "XIM Management".
Following are the XmIm
functions you can safely use in a Motif 1.2-based application. The formal description of the parameters and types can be found in the Xm.h
header file.
XOpenIM()
and queries the input method for supported styles.
XmbLookupString()
; converts one or more key events into a character. Return value is identical to XmbLookupString()
.
XmImSetValues()
and XmImSetFocusValues()
functions allow the application to pass information needed by the input method. It is important for the application to pass all values even though not all values are needed (for each supports preedit and status style). This is because the application can never be sure which style has been selected by the user or the VendorShell
widget. Following are the arguments and data types of each value that should be passed in each call to the XmImSet[Focus]Values()
function.
XmIm
functions are used in the following manner:
XtSetLanguageProc(NULL,
NULL,
NULL)
to initialize the locale.
XmImRegister(
widget
)
to open the input method and establish a connection.
XmImSetValues()
and passing all of the values listed above. This function takes an arg_list and a number_args argument. The arglist is loaded by calling XtSetArg()
.
XtAddEventHandler()
function, for the manager widget of the widget obtaining input from the input method. The event handler is for the FocusChangeMask mask. The handler should call XmImSetFocusValues()
when gaining focus and should call XmImUnsetFocus()
when losing focus. When setting focus for the input method, pass the full set of values listed above.
XmImUnregister()
to notify the input method that you are breaking the connection between the widget and the input method.
XmImSetValues()
to notify the input method any time one or more of the input method values listed above change (for example, spotLocation).
XOpenIM()
.
Table 2-2 XIM Callbacks
This section describes how the user, the application developer, and the implementation combine to establish the language environment of the application. Two general approaches to localizing applications are also discussed. The following three methods can be used:
Also note that the Xm library functions do not depend on the LC_MESSAGE category when specifying the location from which localized resources are loaded. Refer to the XtSetLanguageProc() man page for more information.
The messaging support is based on both the XPG4 and System V Release 4 (SVR4) interfaces for accessing message catalogs.
There are two sets of message extraction functions in the desktop environment: XPG4 functions and Xlib functions.
example.msg file:
$quote "
$ every message catalog should have a beginning set number.
$set 1 This is the set 1 of messages
1 "Hello world\n"
2 "Good Morning\n"
3 "example: 1000.220 Read permission is denied for the file
%s.\n"
$set 2
1 "Howdy\n"
gencat
utility to generate the message catalog example.cat
as follows:
gencat example example.msg
#include <locale.h>
#include <nl_types.h>
char *MF_EXAMPLE = "example.cat"
main()
{
nl_catd catd;
int error;
(void)setlocale(LC_ALL, "");
catd = catopen(MF_EXAMPLE, 0);
/* Get the message number 1 from the first set.*/
printf( catgets(catd,1,1,"Hello world\n") );
/* Get the message number 1 from the second set.*/
printf( catgets(catd, 2, 1,"Howdy\n") );
/* Display an error message.*/
printf( catgets(catd, 1, 4,"example: 100.220
Permission is denied to read the file %s.\n") ,
MF_EXAMPLE);
catclose(catd);
}
In general, for any error or warning messages to be displayed to the user through a system environment toolkit widget or gadget, externalize the messages through message catalogs.
For dialog messages to be displayed through a toolkit component, externalize the messages through localized resource files. This is done in the same way as localizing resources, such as the XmLabel
and XmPushButton
classes' XmNlabelString
resource or window titles.
For example, if a warning message is to be displayed through an XmMessageBox
widget class, the XmNmessageString
resource cannot be hardcoded within the application source code. Instead, the value of this resource must be retrieved from a message catalog. For an internationalized application expected to run in different locales, a distinct localized catalog must exist for each of the locales to be supported. In this way, the application need not be rebuilt.
Localized resource files can be put in the /usr/lib/X11/%L/appdefaults subdirectories, or they can be pointed to by the XENVIRONMENT
environment variable. The %L variable is replaced with the name of the locale used at run time.
XmString
. The rest are of type color or char*. See the Motif 1.2 Reference Manual for detailed descriptions of these resources. In each case, the application should not hardcode these resources. If resource values need to be specified by the application, it should be done with the app-defaults
file, ensuring that the resource can be localized.
Only the widget class resources are listed here; subclasses of these widgets are not listed. For example, the XmDrawnButton
widget class does not introduce any new resources that are localized. However, it is a subclass of the XmLabelWidget
widget class; therefore, its accelerator resource, acceleratorText
resource, and so on, are also localized and should not be hardcoded by an application.
Table 2-3 Localized Resources
Note that the XmRowColumn
widget has additional string resources that may be localized. These resources are listed in the XmRowColumn man page, under the heading "Simple Menu Creation Resource Set." As the title implies, these resources affect only RowColumn
widgets created with the XmCreateSimpleMenu()
function. The resources affected are: *buttonAccelerators
, *buttonAcceleratorText
, *buttonMnemonics
, *optionLabel
, and *optionMnemonic
. These resources are not included in Table 2-3 because they are rarely used and apply to RowColumn only when creating a simple menu.
app-defaults
files, allowing them to be localized. The type for each list is XmStringList
.
Table 2-4 Resources Used for Reading Lists
*title:
and *iconName:
resources. The encoding of each is automatically detected for clients doing proper locale management. All of these are of type char or XmString
.
Table 2-5 Resources Used for Setting Titles and Icon Names
Text[Field]
resources that are locale-sensitive or about which the developer of an internationalized application should know.
Table 2-6 Locale-Sensitive Text[Field] Resources
Table 2-7 Localized Resources for Input Method Customization
Table 2-8 Pixmap Resources
A pixmap is a screen image that is stored in memory so that it can be recalled and displayed when needed. The desktop 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 must be localized.
The desktop maintains caches of pixmaps and images. The XmGetPixmapByDepth()
function 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, the XmGetPixmapByDepth()
function searches for an X bitmap file whose name matches the requested image name. The XmGetPixmapByDepth()
function calls the XtResolvePathname()
function to search for the file. If the requested image name is an absolute path name, that path name is the search path for the XtResolvePathname()
function. Otherwise, the XmGetPixmapByDepth()
function constructs a search path in the following way:
XmGetPixmapByDepth()
function uses a default search path with entries that include $XAPPLRESDIR, the user's home directory, and vendor-dependent system directories.
XmGetPixmapByDepth()
function uses a default search path with entries that include the user's home directory and vendor-dependent system directories.
XtResolvePathname()
function, the XmGetPixmapByDepth()
function substitutes the requested image name for %B. The paths may also include other substitution fields accepted by the XtResolvePathname()
function. In particular, the XtResolvePathname()
function 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.
Because there is no string-to-pixmap converter supplied by default, pixmaps are generally set by the application at creation time by first retrieving the pixmap with a call to XmGetPixmap()
. XmGetPixmap()
uses the current locale to determine where to locate the pixmap. (See the XmGetPixmap() man page for a description of how locale is used to locate the pixmap.)
XmFontList
resources are of type XmFontList
. In almost all cases, a fontset should be used when specifying a fontlist element. The only exception is when displaying character data that does not appear in the character set of the user (for example, displaying math symbols or dingbats).
Table 2-9 Localized Font Resources
Applications should perform proper locale management with the assumption that a locale may have from 1 to 4 bytes per coded character.
Table 2-10 Base Operating System Internationalized Functions
Table 2-10 Base Operating System Internationalized Functions (continued)