I am improving a few window managers so that text in Japanese (and other various languages) can be used for window titles, icon names, and so on.
I determined two principles. At first, the fruits must be
contributed to the official version. I will not make
Japanese version separate from the official version.
The second principle is that all that users need should
be configuration of locale. Don't design so that users
have to configure each software (such as MultiByte
option
in ~/.foobar-rc file
).
There are many works which releases "Japanese (or other local) support patches" or "Japanesed (or other local) versions". Followings are the merits of this way of works:
I don't think I can maintain the Japanized fork version forever. Also, I think that free software developers in the world should know about i18n problem. These are why I decided to send my patches to the upstream developers.
To make my patch be adoped by the upstream developer, the patch need a certain level of quality.
At first, other languages must not be sacrifised to achieve
Japanese support. Most of my work are related to substituting
XFontStruct-related functions [for example,
XLoadQueryFont()
, XDrawString()
] by
XFontSet-related functions
[for example, XCreateFontSet()
, XmbDrawString()
].
However, XFontSet-related functions depend on assumptions that
OS (or X Window System) support "locale" and users set
LC_CTYPE
locale properly. When locale is not set (i.e., the default
behavior), ASCII is used. Most of 8-bit-character-code users
in the world don't know about locale and of course they don't
set LC_CTYPE
locale. Even many developers of window managers
think XFontSet-related functions are only for multibyte languages
and are not 8-bit-clean. Of course the idea is wrong.
Thus, my patches were written so that they can be compilied even when OS and X Window System don't support locale. Furthermore, even on OS / X Window System which support locale, when users don't set locale properly, my patches will use XFontStruct-related functions. Some strict i18n people may think "Not setting locale is a bad manner and softwares don't need to support such users". However, I think such a "correct opinion" is be accepted by real users in the world, and I compromised.
Another difficulty is English. We need to prepare documents in English, discuss with other developers in English, write comments in source code in English, and so on. Nomenclature for variables and subroutines needs to use English (not Japanese or other languages). Many Japanese developers strongly hesitate to use English.
Visit a bookstore in Japan and find Linux/BSD corner. You can find several books related to configuration of Japanese environment. In my opinion, it is a wrong situation.
Why such books are sold? It is because a user has to do many configurations to use Japanese in Linux/BSD. If only one configuration were enough, a book would not be needed. Why many configurations are needed? One of the reason is that each software requires its own configurations to use Japanese.
Ideally, a user needs to specify "Japanese" just once somewhere, then all softwares should work in Japanese.
In case of window managers, specification of XFontSet mode and
fonts. In my patches, I made XFontSet mode is automatically chosen
when locale is properly set, as written above. I can imagine
another algorithm like: XFontSet mode is chosen when locale
starts with "ja
", "ko
", or "zh
",
like Sawfish before I sent
a patch. However, in future, UTF-8 will be widely used and it
is also multibyte (thus XFontSet mode is needed).
It is not very easy to specify fonts. One of main purposes of window managers is to decolate windows using some designs, i.e., idea of beauty. Thus, default font is chosen to realize the developers' idea of design. However, it is not realistic to list up many fonts for many langauges as a default setting. Many developers of window managers don't know about languages and fonts in the world. Even in future, we cannot expect developers and designers will know that.
Many window manager develoers live in Latin-1 font languages and they are not interested in other langauges. Thus, software should have a mechanism to supplement fonts for other languages.
However, it sometimes occurs that Japanese (or other language) font is not available which corresponds to specified latin-1 font. Not sometimes. It very often occurs! (Imagine difficulty to develop a font with thousands of characters [each of them consists of many strokes] for Japanese while a latin-1 font contains only about 200 characters.) However, it is a bad choise not to display Japanese (or other language) at all because of lack of a font of similar design.
I took two kind of solutions. A simpler solutions is to add
",*
" to a fontset parameter for XCreateFontSet()
function. This method ignores decoration or design completely,
but all languages can be displayed if any fonts are available.
Another solution is to search for a font which is as similar as
the specified font. This algorithm is complex and depends on
developers' taste.
When I checked IceWM, it had already been internationalized
using XFontSet. However, it needed to be activated by MultiByte
option in a configuration file. (For a while in past, the option was
activated as a default).
I modified so that users don't need to specify MultiByte
option.
Also, I modified so that ",*
" will be automatically added
at the end of the font specification.
After that, I wrote a code to search for similar fonts, but it is not adopted by IceWM.
Sawfish had already had an internationalization feature using XFontSet.
It was made so that XFontSet mode was activated when the locale begins
with "ja
", "ko
", or "zh
".
The developers of Sawfish consider deeply on internationalization. When I sent a patch to automatically activate XFontSet mode in case the locale is appropriately configured, they tested my patch extensively to gave me many suggestions. Thus the algorithm to automatically activate XFontSet mode was improved as following:
setlocale(LC_CTYPE, "")
returns NULL
,
XFontStruct mode will be used,
setlocale()
returns "C
" or
"POSIX
, XFontStruct mode will be used,
XSupportsLocale()
fails, XFontStruct mode will be used, and
XFontSet
will be used.
Sawfish adopted an algorithm to search for a similar font for a specified font.
TWM is a part of XFree86 distribution and is expected to be a reference or a standard, I thought it is very bad situation that TWM is not internationalized.
Since TWM is a part of XFree86 distribution, I don't need to consider a possibility that XFontSet-related functions are not available. However, TWM will need to support XFontSet mode and XFontStruct mode. Since I thought TWM should be as simple as possible and I didn't introduced an algorithm to search for a similar font. Also, I found a function to read a configuration file was not 8-bit-clean and I fixed that.
My patch will be adoped since XFree86 4.0.2.
CTWM had already been internationalized by using XFontSet-related functions. However, it was determined in compilation-time (Not run-time) which mode (XFontStruct mode or XFontSet mode) will be used. In such case, developers of Linux (or other OS) distributions will have to ignore half of the world.
First I sent a patch to add ",*
" at the end of a parameter
to XCreateFontSet()
function and it will be adopted in the
next version. Next, I sent a patch to automatically select XFontSet mode
or XFontStruct mode in run-time, but I have not got a reply.
When I checked Blackbox, it had not been internationalized using XFontSet-related functions. Thus, I sent a patch (XFontSet wrappere) based on My Linux Japanization to the Blackbox developers and found that they were developing internationalization features. However, my algorithm to automatically activate XFontSet mode was adopted.
Since I thought a look and design is important in Blackbox, I sent a patch to find a similar font and the patch will be adopted.
I found it is more difficult to internationalize Window Maker than other window managers. Main part of window manager and widget are separated. Also, several string-handling algorithms in Window Maker depend on 1 character equals to 1 byte.