XScreenSaverのロック画面で文字化け
Lubuntu で画面ロックすると、ロック解除するときに XScreenSaver のロック画面が表示されますが、この画面のパスワードのラベルが文字化けしててとっても気持ち悪いんです。ずーっと直そうと思ってはいたのですが、ちょっとググっても解決策は見つからないし、機能的な問題はないのでだいぶ放置してました。今回、一念発起してちゃんと調べたのでメモを残しておきます。
Lbuntu のロケールを日本語にしてインストールし、画面のロックから復帰すると以下のようなダイアログが表示されます。

ユーザー名のところは「Username」なのにパスワードのところだけ「□□□□□」になってて、察するに「パスワード」なんだけど日本語非対応のフォントだからトウフになっているんじゃないかなーと。
ということで、まずは XScreenSaver のフォントを変えてみることにします。
基本的なことですが、X Windown のアプリのフォントを変更するには、通常はリソースファイルの編集で可能です。リソース管理は Xt (X Toolkit) で実現しています。
Xのアプリの中には Xt を使用していないものもあり、そういうものには通用しませんが、ほとんどないんじゃないですかね。
で、リソースファイルに戻りますが、指定方法がいろいろあります。いろいろありすぎてリソースファイルを編集したけど全然変わらないなんてこともよくあるくらいです。
おすすめなのは XAPPRESDIR 環境変数を使用する方法です。
mkdir ~/app-defaults
- ~/.bashrc に「
export XAPPLRESDIR="$HOME/app-defaults"
」追加 cp /usr/lib/X11/app-defaults/XScreenSaver ~/app-defaults/
vi ~/app-defaults/XScreenSaver
でリソース編集
デフォルトの /usr/lib/X11/app-defaults/ のリソースファイルをそのままコピーしてきて、~/app-defaults/ のを優先して使ってねっていう指定方法です。
デフォルトのリソースファイルではフォントはこんな感じになっていました。だめじゃん。
! FIXME: This font doesn't look all that particularly good, but biwidth seems to no
t look good either.
*Dialog.headingFont: Ubuntu bold 16
*Dialog.bodyFont: Ubuntu 14
*Dialog.errorFont: Ubuntu bold 14
*Dialog.labelFont: Ubuntu 14
*Dialog.unameFont: Ubuntu 12
*Dialog.buttonFont: Ubuntu bold 14
*Dialog.dateFont: Ubuntu 9
念のためこのフォントがあるか調べてみます。
$ xlsfonts -fn "Ubuntu 14"
xlsfonts: pattern "Ubuntu 14" unmatched
ないし。
X で使えるフォントはオプションなしで xlsfonts
を実行するとズラーッと出てきます。
$ xlsfonts
-adobe-avant garde gothic-book-o-normal--0-0-0-0-p-0-iso8859-1
-adobe-avant garde gothic-book-o-normal--0-0-0-0-p-0-iso8859-15
:
このフォント名は XLFD という命名ルールでハイフンで区切った14項目からなっています。最後の2つが文字セット(CHARSET)なので、日本語の入った iso10646(いわゆるUnicode) の文字セットのものを探します。
$ xlsfonts -fn '-*-iso10646-*'
-arabic-newspaper-medium-r-normal--0-0-100-100-p-0-iso10646-1
-arabic-newspaper-medium-r-normal--32-246-100-100-p-137-iso10646-1
:
-efont-fixed-medium-r-normal--0-0-75-75-c-0-iso10646-1
-efont-fixed-medium-r-normal--10-100-75-75-c-100-iso10646-1
-efont-fixed-medium-r-normal--10-100-75-75-c-50-iso10646-1
-efont-fixed-medium-r-normal--12-120-75-75-c-120-iso10646-1
-efont-fixed-medium-r-normal--12-120-75-75-c-60-iso10646-1
-efont-fixed-medium-r-normal--14-140-75-75-c-140-iso10646-1
-efont-fixed-medium-r-normal--14-140-75-75-c-70-iso10646-1
-efont-fixed-medium-r-normal--16-160-75-75-c-160-iso10646-1
-efont-fixed-medium-r-normal--16-160-75-75-c-80-iso10646-1
-efont-fixed-medium-r-normal--24-240-75-75-c-120-iso10646-1
-efont-fixed-medium-r-normal--24-240-75-75-c-240-iso10646-1
:
「normal–」のあとの10とか12とかがポイント数なので、もとの設定になるべく近い数値を選び、以下のように変更します。
*Dialog.headingFont: -efont-fixed-medium-r-normal--16-*-*-*-*-*-iso10646-1
*Dialog.bodyFont: -efont-fixed-medium-r-normal--14-*-*-*-*-*-iso10646-1
*Dialog.errorFont: -efont-fixed-bold-r-normal--14-140-75-75-c-140-iso10646-1
*Dialog.labelFont: -efont-fixed-medium-r-normal--14-*-*-*-*-*-iso10646-1
*Dialog.unameFont: -efont-fixed-medium-r-normal--12-*-*-*-*-*-iso10646-1
*Dialog.buttonFont: -efont-fixed-bold-r-normal--14-140-75-75-c-140-iso10646-1
*Dialog.dateFont: -efont-fixed-medium-r-normal--10-*-*-*-*-*-iso10646-1
あと、「New Login」ボタンはいらないので消します。
*newLoginCommand:
リソースファイルを修正したら、xscreensaver を再起動しますが、マニュアルどおり↓にやってもうまく行きませんでした。
If you change a setting in the .xscreensaver file while XScreenSaver is
already running, it will notice this, and reload the file as needed. But
if you change a setting in the X Resource Database, you will need to
restart XScreenSaver for those changes to take effect:
xrdb < ~/.Xdefaults
xscreensaver-command --restart
X のリソースを変更したら –restart で再起動、みたいなことが書いてあるのですが、これでは反映されませんでした。xrdb を使っていないせいかもしいれませんが。
なので、再起動は以下のように行います。
$ killall xscreensaver
$ xscreensaver -no-splash &
メニューから「画面ロック」でロックし、クリックかキー入力で復帰させると、日本語が出てきました。

「New Login」ボタンも消えてめでたしめでたし。。。けど、なーんかいや。なんで「パスワード」だけ日本語なの?
ソースを調べてみます。ソースは XScreenSaver のダウンロードページから xscreensaver-6.12.tar.gz をダウンロードしました。
1607行目あたり:
/* Show the logged in user before the first password field. */
if (!emitted_user_p)
{
lines[i].text = _("Username:");
lines[i].font = ws->label_font;
lines[i].fg = ws->xft_foreground;
lines[i].fg2 = lines[i].fg;
lines[i].bg = ws->background;
lines[i].type = LABEL;
lines[i].align = LEFT;
lines[i].float_p = True;
i++;
lines[i].text = ws->user; /* $USER */
lines[i].font = ws->label_font;
lines[i].fg = ws->xft_text_foreground;
lines[i].fg2 = lines[i].fg;
lines[i].bg = ws->passwd_background;
lines[i].type = TEXT_RO;
lines[i].align = RIGHT;
i++;
}
lines[i].text = trim (ws->msgs[j].msg); /* PAM prompt text */
lines[i].font = ws->label_font;
lines[i].fg = ws->xft_foreground;
lines[i].fg2 = lines[i].fg;
lines[i].bg = ws->background;
lines[i].type = LABEL;
lines[i].align = LEFT;
lines[i].float_p = True;
i++;
「_(“Username:”)」のようにユーザー名の行のラベルは gettext(3) で処理しているのに、パスワードの行はしていません。コメントにあるように、PAMのAPIから取得したプロンプト文字列を設定しているだけです。
なんか片手落ちな気がしますが、まぁいいでしょう。gettext(3) を使っているんだから、moファイルを用意してあげて、ユーザー名のほうのラベルも日本語にしちゃえばいいわけです。
moファイルは gettext(3) のバイナリ形式のメッセージカタログファイルで、/usr/share/local/ja/LC_MESSAGES/xscreensaver.mo という感じで置けば利用されますが、Lubuntu の環境ではファイルは存在しませんでした。
幸い XScreenSaver のソースファイルに po/ja.po というメッセージカタログがありましたので、po ファイルから mo ファイルを生成します。
$ msgfmt -o xscreensaver.mo ja.po
できあがった moファイルを規定の位置にコピーします。
$ sudo cp xscreensaver.mo /usr/share/local/ja/LC_MESSAGES/
再起動します。
$ killall xscreensaver
$ xscreensaver -no-splash &
出てきたロック画面は以下の通り、「Username」が「ユーザ名」になりました。

ようやくスッキリしました。\(^o^)/
ところが、ログアウトや再起動するともとに戻ってしまいました。たぶん環境変数 XAPPRESDIR が効いていない環境で XScreenSaver を起動していると見込んで、設定>LXQt設定>セッション を見てみたら「環境(詳細)」タブに環境変数の設定があったので設定しました。

これで毎回ちゃんと日本語が表示されるようになりました。
今回、久々に X Window のアプリをいじりました。たぶん20年以上ぶりです。ですが、基本的なところは当時の知識でも少しは役に立つことにちょっと驚きました。