[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[debian-users:14945] Bug#JP/794: marked as done (Wchar incompatibility between glibc2 and Xlib)
Akira YOSHIYAMA <yosshy@xxxxxxxxxxxxx>さんの Sun, 25 Apr 1999 00:35:48 +0900付けの
message-id <19990425003548V.yosshy@xxxxxxxxxxxxx>
subject Bug#JP/794: Wchar incompatibility between glibc2 and Xlib
のメッセージにより以下のバグ報告は「処理済」とされました。
もし、間違ったバグ報告を「処理済」にしてしまった場合は
必要に応じてバグ報告を再発行し、そして/または、ただちに問題を修正してください。
(注: これは Debian JP Bug Tracking System が発行している
自動応答メッセージで、debian-users メイリングリストにも送られています。
あなたがシステム管理者で、このメッセージが何について書かれている
かよくわからないのでしたら、どこかに深刻なメールシステムの誤設定がある
ことを示しています。すぐに私まで連絡をいただけないでしょうか)
(NB: If you are a system administrator and have no idea what I'm
talking about this indicates a serious mail system misconfiguration
somewhere. Please contact me immediately.)
--
Debian JP Bug Tracking System / owner@bugs.debian.or.jp
Received: from tkf.att.ne.jp (tkf.att.ne.jp [165.76.17.6])
by lists.debian.or.jp (8.9.2+3.1W/3.6W-Debian-JP-980308) with ESMTP id AAA24161
for <794-done@bugs.debian.or.jp>; Mon, 26 Apr 1999 00:38:22 +0900 (JST)
Subject: Re: Bug#JP/794: Wchar incompatibility between glibc2 and Xlib
In-Reply-To: Your message of "Sat, 27 Feb 1999 12:42:01 +0900"
<19990227124201H.watanaru@xxxxxxxxxxxxxxxx>
References: <19990227124201H.watanaru@xxxxxxxxxxxxxxxx>
X-Mailer: Mew version 1.93 on Emacs 20.3 / Mule 4.0 (HANANOEN)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Message-Id: <19990425003548V.yosshy@xxxxxxxxxxxxx>
Date: Sun, 25 Apr 1999 00:35:48 +0900
From: Akira YOSHIYAMA <yosshy@xxxxxxxxxxxxx>
X-Dispatcher: imput version 980905(IM100)
Lines: 65
吉山@目黒です。
ほったらかしにしていたのですが、レポートに2つ疑問があります。
1)Debian 2.[01] の XFree86 は X_LOCALE なしでコンパイルされている
2)X は標準Cライブラリのワイド文字のエンコーディング(?)に依存しない
以上の事実より、とりあえずバグを閉じます。何か分かればまたバグレポー
ト願います。
---
Name: 吉山あきら Akira Yoshiyama
E-mail: yosshy@debian.or.jp (yosshy@xxxxxxxxxxxxx)
From: watanaru@xxxxxxxxxxxxxxxx
Subject: Bug#JP/794: Wchar incompatibility between glibc2 and Xlib
Date: Sat, 27 Feb 1999 12:42:01 +0900
> Package: wcsmbs-locale
> Version: 0.4.1
>
> ○ Netscape のフォームとワイド文字
>
> Netscape のフォーム内の一行入力欄 (Motif) で日本語の表示が化けるのは
> libc 側と Xlib 側でワイド文字の表現方法が違っているからです。現行の
> libc (glibc2.0.7 + wcsmbs-locale) の mbtowc()などでワイド文字を作ると、
> その表現法は UCS (ユニコード) になりますが、Xlib では Xlib 独自の表現
> 法を使っているので、libc の関数を使って作ったワイド文字を Xlib のテキ
> スト描画関数などに渡しても Xlib では適切に解釈することができません。
>
> そこで私は Xlib が理解することのできる形式でワイド文字を作れる
> wcsmbs.so ライブラリを作って使っています。
>
>
> ○ Debian 2.0 と X Window System
>
> この X 用ライブラリを使うには、基本的にはこのレポートに添付のソースを
> コンパイルしてインストールするだけでよいのですが、Debian2.0 の場合、X
> Window System が「X_LOCALE が定義された」状態でコンパイルされているの
> で、このままだとうまく作動しません。
>
> X_LOCALE が定義されていると、Xlib は setlocale() のかわりに
> _Xsetlocale() を使うようにコンパイルされてしまいます。何かのアプリケー
> ションを実行させた場合を考えてみると、アプリケーションは setlocale()
> を使ってロケール設定をしているのに、Xlib 内の関数は、_Xsetlocale() を
> 使って現在のロケール設定を知ろうとするというような状況になります。
> _Xsetlocale() と setlocale() とは何のつながりもないので (そもそも
> _Xsetlocale() は setlocale() を持っていないシステムのために用意されて
> いるもので、両方存在するのは変です)、アプリケーションが setlocale()
> を使ってどんなロケール設定をしようと、_Xsetlocale() が持っているロケー
> ル情報はつねにデフォルトのまま ("C" ロケール、つまり英語) になります。
>
> つまり環境変数 "LANG" を "ja_JP.ujis" に設定しても、Xlib 側は英語のま
> まのふるまいになってしまいます。例えば Netscape で日本語メニューを使
> うリソース設定にしても半角文字しか表示されず、全角文字は X に無視され
> てしまうのはこのためです。Netscape の場合、Debian の netscape4-ja パッ
> ケージなどに入っている liblocale.so を使うと、このメニュー等の日本語
> 化の問題は解決しますが、この場合、ロケール設定が libc 側には反映され
> なくなるので、libc 側のふるまいが英語になってしまいます (ワイド文字関
> 係のところはユニコードになります。liblocale.so 内の setlocale() が使
> われるようになるので、適切な wcsmbs.so がロードされないからです)。
>
> しょうがないので、私は X_LOCALE をはずした状態で、X をコンパイルしな
> おして使用しています。
Return-Path: <watanaru@xxxxxxxxxxxxxxxx>
From: watanaru@xxxxxxxxxxxxxxxx
To: submit@bugs.debian.or.jp
Subject: Wchar incompatibility between glibc2 and Xlib
Message-Id: <19990227124201H.watanaru@xxxxxxxxxxxxxxxx>
Date: Sat, 27 Feb 1999 12:42:01 +0900
X-Dispatcher: imput version 980506
Mime-Version: 1.0
Content-Type: Text/plain; charset=iso-2022-jp
Lines: 527
Package: wcsmbs-locale
Version: 0.4.1
○ Netscape のフォームとワイド文字
Netscape のフォーム内の一行入力欄 (Motif) で日本語の表示が化けるのは
libc 側と Xlib 側でワイド文字の表現方法が違っているからです。現行の
libc (glibc2.0.7 + wcsmbs-locale) の mbtowc()などでワイド文字を作ると、
その表現法は UCS (ユニコード) になりますが、Xlib では Xlib 独自の表現
法を使っているので、libc の関数を使って作ったワイド文字を Xlib のテキ
スト描画関数などに渡しても Xlib では適切に解釈することができません。
そこで私は Xlib が理解することのできる形式でワイド文字を作れる
wcsmbs.so ライブラリを作って使っています。
○ Debian 2.0 と X Window System
この X 用ライブラリを使うには、基本的にはこのレポートに添付のソースを
コンパイルしてインストールするだけでよいのですが、Debian2.0 の場合、X
Window System が「X_LOCALE が定義された」状態でコンパイルされているの
で、このままだとうまく作動しません。
X_LOCALE が定義されていると、Xlib は setlocale() のかわりに
_Xsetlocale() を使うようにコンパイルされてしまいます。何かのアプリケー
ションを実行させた場合を考えてみると、アプリケーションは setlocale()
を使ってロケール設定をしているのに、Xlib 内の関数は、_Xsetlocale() を
使って現在のロケール設定を知ろうとするというような状況になります。
_Xsetlocale() と setlocale() とは何のつながりもないので (そもそも
_Xsetlocale() は setlocale() を持っていないシステムのために用意されて
いるもので、両方存在するのは変です)、アプリケーションが setlocale()
を使ってどんなロケール設定をしようと、_Xsetlocale() が持っているロケー
ル情報はつねにデフォルトのまま ("C" ロケール、つまり英語) になります。
つまり環境変数 "LANG" を "ja_JP.ujis" に設定しても、Xlib 側は英語のま
まのふるまいになってしまいます。例えば Netscape で日本語メニューを使
うリソース設定にしても半角文字しか表示されず、全角文字は X に無視され
てしまうのはこのためです。Netscape の場合、Debian の netscape4-ja パッ
ケージなどに入っている liblocale.so を使うと、このメニュー等の日本語
化の問題は解決しますが、この場合、ロケール設定が libc 側には反映され
なくなるので、libc 側のふるまいが英語になってしまいます (ワイド文字関
係のところはユニコードになります。liblocale.so 内の setlocale() が使
われるようになるので、適切な wcsmbs.so がロードされないからです)。
しょうがないので、私は X_LOCALE をはずした状態で、X をコンパイルしな
おして使用しています。
○ Version など
Debian:
version 2.0
wcsmbs-locale:
version 0.4.1
libc6:
version 2.0.7t-1.wcsmbs.4.1
xlib6g:
version 3.3.2.3-1
前述の通り、X_LOCALE が定義された状態でコンパイルされているので、こ
の定義をはずして自力コンパイルしたものを使っています。
netscape:
version 4.07
RedHat 5.2 に入っていたものを 'alien' コマンドで .deb 化して、
Debian 上で使っています。netscape で wcsmbs.so の作動をチェックす
るには、環境変数 LANG を "ja_JP.ujis" にするだけで、あとは英語(デ
フォルト)設定のままでよいと思います。
ちなみにフォームの一行入力欄の初期値が表示されないとか(リセットボ
タンがあれば、それを押せば表示されますけど)、ファイルリクエスタの
挙動がおかしいとか、その辺の問題は wcsmbs.so を変えても解決しませ
ん。
○ X 用 wcsmbs.so のソースコード (EUC 用)
(コンパイルするには X のソースが必要です。)
/*
* wcsmbs-xeuc.c
* a wcsmbs.so library for Linux (glibc 2.0.7, wcsmbs-locale 0.4.1
* and X11R6.3)
*
* written by Narumi Watanabe, 1999/02/01
*
* COMPILE:
* gcc -fPIC -shared -Wl,-soname,wcsmbs.so -o wcsmbs-x.so \
* wcsmbs-xeuc.c -I$X11SRC/lib/X11 -L/usr/X11R6/lib -lX11
* ^^^^^^^
* INSTALL:
* cp wcsmbs-x.so /usr/lib/wcsmbs/ja_JP.ujis/wcsmbs-x.so
* cd /usr/lib/wcsmbs/ja_JP.ujis
* mv wcsmbs.so wcsmbs-ucs.so
* ln -s wcsmbs-x.so wcsmbs.so
*/
#include <stdio.h>
#include <wchar.h>
#include "Xlibint.h"
#include "XlcGeneric.h"
#define CLR_MSB(c) ((c) & 0x7f)
#define SET_MSB(c) ((c) | 0x80)
#define IS_MSB(c) ((c) & 0x80)
static unsigned char ShiftCode[4];
#define SS2 ShiftCode[2]
#define SS3 ShiftCode[3]
static XLCd get_lcd(void)
{
static XLCd lcd = NULL;
if (lcd == NULL) {
if (lcd = _XOpenLC(NULL)) {
if (_XlcNCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "euc", 3)) {
_XCloseLC(lcd);
lcd = NULL;
}
else if (XLC_GENERIC(lcd, codeset_num) < 1 || (XLC_GENERIC_PART(lcd)->codeset_list[0])->length != 1) {
_XCloseLC(lcd);
lcd = NULL;
}
}
if (lcd) {
CodeSet codeset;
if (XLC_GENERIC(lcd, codeset_num) >= 3) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[2];
if (codeset->parse_info && codeset->parse_info->encoding)
SS2 = *codeset->parse_info->encoding;
}
if (XLC_GENERIC(lcd, codeset_num) >= 4) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[3];
if (codeset->parse_info && codeset->parse_info->encoding)
SS3 = *codeset->parse_info->encoding;
}
}
#ifdef DEBUG
if (lcd == NULL)
printf("can't open lcd.\n");
else {
int i;
char *msg;
int enc;
CodeSet codeset;
for (i = 0; i < XLC_GENERIC(lcd, codeset_num); ++i) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[i];
msg = "";
enc = 0;
if (codeset->parse_info == NULL)
msg = "(no parse info)";
else if (codeset->parse_info->encoding == NULL)
msg = "(no encoding)";
else
enc = *(unsigned char *)codeset->parse_info->encoding;
printf("-cs%d: %02x %s\n", i, enc, msg);
}
printf("-mb_cur_max=%d\n", XLC_PUBLIC(lcd, mb_cur_max));
}
#endif /* DEBUG */
}
return(lcd);
}
static int wc_codeset_no(XLCd lcd, wchar_t wc)
{
int i;
wc &= XLC_GENERIC(lcd, wc_encode_mask);
for (i = 0; i < XLC_GENERIC(lcd, codeset_num); ++i)
if (wc == (XLC_GENERIC_PART(lcd)->codeset_list[i])->wc_encoding)
return(i);
return(-1);
}
#ifdef DEBUG
void show_str(const char *s, int len)
{
int i;
char buf[32];
if (s == NULL)
len = 0;
if (len >= sizeof(buf))
len = sizeof(buf) - 2;
for (i = 0; i < len; ++i) {
buf[i] = s[i];
if (buf[i] & 0x80) {
++i;
buf[i] = s[i];
}
}
buf[i] = 0;
printf("\"%s\"", buf);
}
#endif /* DEBUG */
size_t dll_mbrtowc_locale(wchar_t *pwc, const char *s, size_t slen, mbstate_t *ps)
{
XLCd lcd;
wchar_t wc;
unsigned char ch;
if ((lcd = get_lcd()) == NULL)
return((size_t)-1);
#ifdef DEBUG
printf("-mbrtowc: %p, %p, %d\n\t<- ", pwc, s, slen);
if (s)
show_str(s, slen);
printf("\n");
#endif
if (s == NULL)
return(XLC_PUBLIC(lcd, is_state_depend));
if (*s == '\0') {
if (pwc)
*pwc = 0;
return(0);
}
if (slen <= 0)
return((size_t)-1); /* ??? */
ch = *(unsigned char *)s;
if (!IS_MSB(ch)) {
wc = ch | (XLC_GENERIC_PART(lcd)->codeset_list[0])->wc_encoding;
slen = 1;
}
else {
CodeSet codeset;
int len, wc_shift;
if (ch < 0xa0) {
if (ch == SS2) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[2];
len = codeset->length;
if (slen < 1 + len)
return((size_t)-1);
slen = 1 + len;
++s;
}
else if (ch == SS3) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[3];
len = codeset->length;
if (slen < 1 + len)
return((size_t)-1);
slen = 1 + len;
++s;
}
else
return((size_t)-1);
}
else if (XLC_GENERIC(lcd, codeset_num) >= 2) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[1];
len = codeset->length;
if (slen < len)
return((size_t)-1);
slen = len;
}
wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
wc = 0;
for ( ; --len >= 0; ) {
if ((ch = *(unsigned char *)s++) < 0xa0)
return((size_t)-1);
wc = (wc << wc_shift) | CLR_MSB(ch);
}
wc |= codeset->wc_encoding;
}
if (pwc)
*pwc = wc;
#ifdef DEBUG
printf("\t-> wc=%08x, len=%d\n", wc, slen);
#endif
return(slen);
}
size_t dll_mbsnrtowcs_locale(wchar_t *dst, const char **src, size_t srclen, size_t dstlen, mbstate_t *ps)
{
XLCd lcd;
unsigned char *s, ch;
int wc_shift, wc_encoding_cs0;
size_t nwc;
wchar_t wc;
if ((lcd = get_lcd()) == NULL)
return((size_t)-1);
#ifdef DEBUG
printf("-mbsnrtowcs: %p, %p, %d, %d\n\t<- ", dst, *src, srclen, dstlen);
if (s = *(unsigned char **)src)
show_str(s, srclen);
printf("\n");
#endif
wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
wc_encoding_cs0 = (XLC_GENERIC_PART(lcd)->codeset_list[0])->wc_encoding;
s = (unsigned char *)*src;
if (dstlen == 0)
dst = NULL;
nwc = 0;
for ( ; srclen > 0 && (ch = *s) != '\0' ; ) {
if (!IS_MSB(ch)) {
wc = ch | wc_encoding_cs0;
--srclen;
++s;
}
else {
CodeSet codeset;
int len;
if (ch < 0xa0) {
if (ch == SS2) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[2];
len = codeset->length;
if ((size_t)(1 + len) > srclen)
return((size_t)-1);
--srclen;
++s;
}
else if (ch == SS3) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[3];
len = codeset->length;
if ((size_t)(1 + len) > srclen)
return((size_t)-1);
--srclen;
++s;
}
else
return((size_t)-1);
}
else if (XLC_GENERIC(lcd, codeset_num) >= 2) {
codeset = XLC_GENERIC_PART(lcd)->codeset_list[1];
len = codeset->length;
if ((size_t)len > srclen)
rerutn((size_t)-1);
}
else
return((size_t)-1);
srclen -= len;
wc = 0;
for ( ; --len >= 0; ) {
if ((ch = *s++) < 0xa0)
return((size_t)-1);
wc = (wc << wc_shift) | CLR_MSB(ch);
}
wc |= codeset->wc_encoding;
}
++nwc;
if (dst) {
*dst++ = wc;
if (nwc >= dstlen)
break;
}
}
if (dst != NULL && nwc < dstlen)
*dst = 0;
*src = (srclen > 0 || *s == '\0') ? NULL : (char *)s;
return(nwc);
}
size_t dll_mbsrtowcs_locale(wchar_t *dst, const char **src, size_t dstlen, mbstate_t *ps)
{
return(dll_mbsnrtowcs_locale(dst, src, (size_t)~0, dstlen, ps));
}
size_t dll_wcrtomb_locale(char *d, wchar_t wc, mbstate_t *ps)
{
XLCd lcd;
int dlen = 0;
CodeSet codeset;
int i, wc_shift;
#ifdef DEBUG
void *dtop = d;
#endif
if ((lcd = get_lcd()) == NULL)
return(-1);
#ifdef DEBUG
printf("-wcrtomb: %p, %08x\n", d, wc);
#endif
if (d == NULL)
return(XLC_PUBLIC(lcd, is_state_depend));
if (wc == 0) {
*d = '\0';
return(0);
}
if ((i = wc_codeset_no(lcd, wc)) < 0)
return(-1);
codeset = XLC_GENERIC_PART(lcd)->codeset_list[i];
if (ShiftCode[i]) { /* SS2 or SS3 */
*d++ = ShiftCode[i];
++dlen;
}
wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
i = codeset->length;
d += i;
dlen += i;
for ( ; --i >= 0; ) {
*(--d) = (codeset->side == XlcGR) ? SET_MSB(wc) : CLR_MSB(wc);
wc >>= wc_shift;
}
#ifdef DEBUG
printf("\t-> ");
show_str(dtop, dlen);
printf("\n");
#endif
return(dlen);
}
int dll_wcsnrtombs_locale(char *dst, const wchar_t **src, size_t srclen, size_t dstlen, mbstate_t *ps)
{
XLCd lcd;
wchar_t wc, *ws;
int wc_shift;
size_t dpos;
if ((lcd = get_lcd()) == NULL)
return((size_t)-1);
#ifdef DEBUG
printf("-wcsnrtombs: %p, %p, %d, %d\n", dst, *src, srclen, dstlen);
#endif
wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
ws = *(wchar_t **)src;
if (dstlen == 0)
dst = NULL;
dpos = 0;
for ( ; (srclen > 0) && (wc = *ws); --srclen, ++ws) {
int i;
CodeSet codeset;
if ((i = wc_codeset_no(lcd, wc)) < 0)
return((size_t)-1);
codeset = XLC_GENERIC_PART(lcd)->codeset_list[i];
if (dst == NULL) {
if (ShiftCode[i]) /* SS2 or SS3 */
++dpos;
dpos += codeset->length;
}
else {
int len = codeset->length;
unsigned char *ptr;
if (ShiftCode[i]) {
if (dpos + 1 + len > dstlen)
break;
dst[dpos++] = ShiftCode[i];
}
else {
if (dpos + len > dstlen)
break;
}
dpos += len;
ptr = dst + dpos;
for ( ; --len >= 0; ) {
*(--ptr) = (codeset->side == XlcGR) ? SET_MSB(wc) : CLR_MSB(wc);
wc >>= wc_shift;
}
}
}
if (dst != NULL && dpos < dstlen)
dst[dpos] = '\0';
#ifdef DEBUG
printf("\t-> ");
if (dst)
show_str(dst, dpos);
printf("\n");
#endif
*src = (srclen == 0 || *ws == 0) ? NULL : (wchar_t *)ws;
return(dpos);
}
int dll_wcsrtombs_locale(char *dst, const wchar_t **src, size_t dstlen, mbstate_t *ps)
{
return(dll_wcsnrtombs_locale(dst, src, (size_t)~0, dstlen, ps));
}
int dll_ctype_get_mb_cur_max(void)
{
XLCd lcd;
if ((lcd = get_lcd()) == NULL)
return(1);
return(XLC_PUBLIC(lcd, mb_cur_max));
}
(ソースコードおわり)
------------------------------------
渡辺成身 (watanaru@xxxxxxxxxxxxxxxx)