<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
 >

  <channel rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/!feeds/list">
    <title>mutt-j Wiki</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/!feeds/list</link>
    <description>
      SourceForge.jp Wiki pages for mutt-j project.    </description>
        <dc:date>2011-03-24T15:52:01+09:00</dc:date>
        <items>
      <rdf:Seq>
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/Linux%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/FrontPage" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/ambiguous_width%E3%81%BE%E3%81%A8%E3%82%81" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/ncurses%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%AEwcwidth" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90" />
                <rdf:li rdf:resource="http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4" />
              </rdf:Seq>
    </items>
  </channel>

      <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/Linux%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95">
    <title>Linuxでの対応方法</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/Linux%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95</link>
    <dc:identifier>Linuxでの対応方法</dc:identifier>
    <dc:date>2011-03-24T15:52:01+09:00</dc:date>
        <description>
      <![CDATA[= Linux でのテーブル変更方法 =
Linuxでは、/usr/share/i18n/charmaps/UTF-8.gz が文字幅情報を含んでいるテーブルである。これを書き換えればよい。

直接書き換えるのは危険なので、新たにUTF-8-CJK.gzを作成する。手順は以下の通り。

 1. samples/UTF-8-CJK を用意する。
 2. gzip で圧縮する。
 3. ]]>
    </description>
    <content:encoded>
      <![CDATA[<h1 id="h1-Linux.20.E3.81.A7.E3.81.AE.E3.83.86.E3.83.BC.E3.83.96.E3.83.AB.E5.A4.89.E6.9B.B4.E6.96.B9.E6.B3.95">Linux でのテーブル変更方法</h1><p>Linuxでは、/usr/share/i18n/charmaps/UTF-8.gz が文字幅情報を含んでいるテーブルである。これを書き換えればよい。
</p><p>直接書き換えるのは危険なので、新たにUTF-8-CJK.gzを作成する。手順は以下の通り。
</p><ol><li>samples/UTF-8-CJK を用意する。
</li><li>gzip で圧縮する。
</li><li>rootになり、cp -p UTF-8-CJK.gz /usr/share/i18n/charmaps/ を実行する。
</li><li>localedef -i ja_JP -c -f UTF-8-CJK ja_JP.UTF-8-CJK を実行する。
</li></ol><p>このあと、使用するlocaleを変更する。 setenv LANG ja_JP.utf8cjk とする。
</p><h2 id="h2-.E6.B3.A8.E6.84.8F.E7.82.B9">注意点</h2><p>FreeBSDではうまくいった、U2184-U2189は未定義のため、localedefではエラーとなる模様。
</p><h1 id="h1-.E5.8F.82.E8.80.83URL">参考URL</h1><p>* <a href="http://d.hatena.ne.jp/macks/20090304" class="external" rel="nofollow">http://d.hatena.ne.jp/macks/20090304</a> と <a href="http://d.hatena.ne.jp/macks/20090305" class="external" rel="nofollow">http://d.hatena.ne.jp/macks/20090305</a></p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/FrontPage">
    <title>FrontPage</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/FrontPage</link>
    <dc:identifier>FrontPage</dc:identifier>
    <dc:date>2011-03-24T09:16:45+09:00</dc:date>
        <description>
      <![CDATA[= このプロジェクトのWiki =

[ファイル置き場]

[ソースコード解析]

[ambiguous_widthまとめ]

[FreeBSDでの対応方法]

[Linuxでの対応方法]]]>
    </description>
    <content:encoded>
      <![CDATA[<h1 id="h1-.E3.81.93.E3.81.AE.E3.83.97.E3.83.AD.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AEWiki">このプロジェクトのWiki</h1><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4">ファイル置き場</a>
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90">ソースコード解析</a>
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/ambiguous_width%E3%81%BE%E3%81%A8%E3%82%81">ambiguous_widthまとめ</a>
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95">FreeBSDでの対応方法</a>
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/Linux%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95">Linuxでの対応方法</a></p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/ambiguous_width%E3%81%BE%E3%81%A8%E3%82%81">
    <title>ambiguous_widthまとめ</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/ambiguous_width%E3%81%BE%E3%81%A8%E3%82%81</link>
    <dc:identifier>ambiguous_widthまとめ</dc:identifier>
    <dc:date>2011-03-22T14:21:13+09:00</dc:date>
        <description>
      <![CDATA[= ambiguous width のリソース等 =
ambiguous widthについては、[http://www.unicode.org]にある、
East Asian Width Technical Report #11 (http://www.unicode.org/reports/tr11-5/)
に説明がある。

Unicode文字には6つの種類がある。
Ambiguou]]>
    </description>
    <content:encoded>
      <![CDATA[<h1 id="h1-ambiguous.20width.20.E3.81.AE.E3.83.AA.E3.82.BD.E3.83.BC.E3.82.B9.E7.AD.89">ambiguous width のリソース等</h1><p>ambiguous widthについては、<a href="http://www.unicode.org" class="external" rel="nofollow">http://www.unicode.org</a>にある、
East Asian Width Technical Report <a href="http://sourceforge.jp/projects/mutt-j/tracker/detail/11" class="tracker">#11</a> (<a href="http://www.unicode.org/reports/tr11-5/)" class="external" rel="nofollow">http://www.unicode.org/reports/tr11-5/)</a>
に説明がある。
</p><p>Unicode文字には6つの種類がある。
Ambiguous, Full Width, Half Width, Narrow, Wide, Not East Asian Neutral
</p><p>テーブルの定義は
<a href="http://www.unicode.org/Public/6.0.0/ucd/EastAsianWidth.txt" class="external" rel="nofollow">http://www.unicode.org/Public/6.0.0/ucd/EastAsianWidth.txt</a>
</p><p>ここでAがambiguous,FがFull Width,HがHalf Width,NaがNallow,WがWide,NがNot。
</p><p>また、<a href="http://www.m17n.org/mlarchive/mule-ja/200905/msg00009.html" class="external" rel="nofollow">http://www.m17n.org/mlarchive/mule-ja/200905/msg00009.html</a> からの
スレッドでも問題になっていて、LC_CTYPEで変更するのは危険と。
ncursesが端末と通信して幅を決められればベターというアイデアが出ている。
</p><p>ただし、00A2のように、Nでも実際の表示が2バイト幅のものもある。
</p><p>これも便利
<a href="http://www.utf8-chartable.de/" class="external" rel="nofollow">http://www.utf8-chartable.de/</a>
</p><p>unisetは
<a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html" class="external" rel="nofollow">http://www.cl.cam.ac.uk/~mgk25/unicode.html</a>
</p><h2 id="h2-slang.20.E3.81.AE.E3.83.91.E3.83.83.E3.83.81">slang のパッチ</h2><p><a href="http://mailman.jedsoft.org/pipermail/slang-users-l/2008/000630.html" class="external" rel="nofollow">http://mailman.jedsoft.org/pipermail/slang-users-l/2008/000630.html</a> にs-langへの
パッチがある。ただメインストリームには含まれていない。
</p><p>にある。
</p><h1 id="h1-.E5.AE.9F.E9.9A.9B.E3.81.AE.E8.A1.A8.E7.A4.BA">実際の表示</h1><p>teraterm で確認したところ、以下のようになった。転送されてくる文字はUTF-8な
文字である。理由は、teratermが、文字をwctomb()で変換している為なのだそうだ。
どうなるかについては、
<a href="http://www.massangeana.com/mas/charsets/jis2ucs.htm" class="external" rel="nofollow">http://www.massangeana.com/mas/charsets/jis2ucs.htm</a> や
<a href="http://gihyo.jp/admin/serial/01/charcode/0007" class="external" rel="nofollow">http://gihyo.jp/admin/serial/01/charcode/0007</a> に記述がある。
</p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95">
    <title>FreeBSDでの対応方法</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%A7%E3%81%AE%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95</link>
    <dc:identifier>FreeBSDでの対応方法</dc:identifier>
    <dc:date>2011-03-21T11:52:42+09:00</dc:date>
        <description>
      <![CDATA[= FreeBSDでの対応方法 =

/usr/share/locale/ja_JP.UTF-8 を作り直す。

元データは/usr/src/share/mklocale/UTF8-src 。これを修正する。このファイルは
少なくても6.xから8.2まで変更がないようだ。修正した結果はsvnにUTF-9.srcとして
登録済み。


]]>
    </description>
    <content:encoded>
      <![CDATA[<h1 id="h1-FreeBSD.E3.81.A7.E3.81.AE.E5.AF.BE.E5.BF.9C.E6.96.B9.E6.B3.95">FreeBSDでの対応方法</h1><p>/usr/share/locale/ja_JP.UTF-8 を作り直す。
</p><p>元データは/usr/src/share/mklocale/UTF8-src 。これを修正する。このファイルは
少なくても6.xから8.2まで変更がないようだ。修正した結果はsvnにUTF-9.srcとして
登録済み。
</p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/ncurses%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0">
    <title>ncursesのデバッグ</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/ncurses%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0</link>
    <dc:identifier>ncursesのデバッグ</dc:identifier>
    <dc:date>2011-03-02T06:59:02+09:00</dc:date>
        <description>
      <![CDATA[=== ncursesのデバッグ ===
基本的に、別画面を出して、gdb から等外プロセスにattachすればよい。

ncursesにはトレース機能がついている。
通常では利用できない。トレース付きのライブラリを
別途インストールするようになっているが、それは
static link用だったため、なぜかリンクエラーが出てしまった。
同じ名前のものがlibcにあるため、どちらを使う]]>
    </description>
    <content:encoded>
      <![CDATA[<h3 id="h3-ncurses.E3.81.AE.E3.83.87.E3.83.90.E3.83.83.E3.82.B0">ncursesのデバッグ</h3><p>基本的に、別画面を出して、gdb から等外プロセスにattachすればよい。
</p><p>ncursesにはトレース機能がついている。
通常では利用できない。トレース付きのライブラリを
別途インストールするようになっているが、それは
static link用だったため、なぜかリンクエラーが出てしまった。
同じ名前のものがlibcにあるため、どちらを使うかで
エラーが出ている様子。
</p><p>コンパイル時にデバッグとトレースを有効にしてコンパイル
すればOK。その後、プログラム内でtrace()関数を呼び出す。
これは man curses_trace に書いてある。フルトレースすると
けっこうな量になる。
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/PutAttrChar">PutAttrChar</a>の中でマルチバイト文字列を出力している。
PUTCというマクロを使っている。このマクロを処理した後、_nc_outputchars が2
になっているので2バイト(UCS2)処理は正しく行われている様子。
</p><p>もうちょっと追ってみる。
</p><p>doupdateの996行目あたり
<pre> 994         UpdateAttrs(SP_PARM, normal);
 995
 996     NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
 997     WINDOW_ATTRS(CurScreen(SP_PARM)) = WINDOW_ATTRS(NewScreen(SP_PARM));
</pre>で、画面に表示される。そこまでは、
</p><p><a href="http://sourceforge.jp/projects/mutt-j/wiki/TransformLine">TransformLine</a>(955行目)あたりから、<a href="http://sourceforge.jp/projects/mutt-j/wiki/PutRange">PutRange</a>-&gt;<a href="http://sourceforge.jp/projects/mutt-j/wiki/EmitRange">EmitRange</a>-&gt;<a href="http://sourceforge.jp/projects/mutt-j/wiki/PutChar">PutChar</a>-&gt;<a href="http://sourceforge.jp/projects/mutt-j/wiki/PutAttrChar">PutAttrChar</a>。
メモリ上は正しくUCS2な文字が入っている様子。ただ、996行目の_nc_flush(実体は
flushを呼び出すだけを実行すると、文字が表示され、桁がずれる。
</p><p>wnoutrefresh()のあたりにブレークポイントを仕掛け、winという構造体の中身を
ダンプ。これが画面に対応しているデータを保持しているらしい。それを見ると、
win-&gt;_lineが各行データを保持しているらしい。ここには、各1文字毎に文字の値と
属性値を保持している。中身は確かに、1つの文字毎にきちんと格納されている。
ということで、内部データ(UCS2)での保持については問題なくできているはず。
ワイド文字-&gt;マルチバイト文字に変換し、エスケープシーケンスで出力する時に
おかしい?
_nc_getchという関数があるが、これは、チャイルドプロセスを起こす時などに、
ESCシーケンスで画面を消したりするのに使われるようだが、画面表示の時には使われない。
</p><p>さらに、_nc_flush()の所にブレークポイントを仕掛け、その時の状態を見る。
1バイト文字では、1バイトずつバッファに文字が入り、そのまま出力される。
UCS文字の場合は、_nc_flush()が呼び出されてもバッファに文字が入っていない。
3回呼び出された後、バッファにUTF-8文字が入り、そのあとに1バイトの空白文字
が入っている。よって、_nc_flushに来る前に空白が付けられている。</p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%AEwcwidth">
    <title>FreeBSDのwcwidth</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%AEwcwidth</link>
    <dc:identifier>FreeBSDのwcwidth</dc:identifier>
    <dc:date>2011-03-01T23:46:28+09:00</dc:date>
        <description>
      <![CDATA[== FreeBSDのwcwidth ==
wcwidth()は /usr/include/wchar.h に定義されている。定義部分は


{{{
#if __XSI_VISIBLE
int     wcswidth(const wchar_t *, size_t);
int     wcwidth(wchar_t);
#define wcwidth(_c)     __wcwi]]>
    </description>
    <content:encoded>
      <![CDATA[<h2 id="h2-FreeBSD.E3.81.AEwcwidth">FreeBSDのwcwidth</h2><p>wcwidth()は /usr/include/wchar.h に定義されている。定義部分は
</p><pre>#if __XSI_VISIBLE
int     wcswidth(const wchar_t *, size_t);
int     wcwidth(wchar_t);
#define wcwidth(_c)     __wcwidth(_c)
#endif
</pre><p>gcc -E で展開した結果を見る限り、__XSI_VISIBLEは有効になっている。
</p><p>さらにそこから、/usr/include/_ctype.hを呼び出している。実体は__wcwidth()。_ctype.hの中に定義されている__wcwidth()は以下の通り。
</p><pre>static __inline int
__wcwidth(__ct_rune_t _c)
{
        unsigned int _x;

        if (_c == 0)
                return (0);
        _x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R);
        if ((_x &amp; _CTYPE_SWM) != 0)
                return ((_x &amp; _CTYPE_SWM) &gt;&gt; _CTYPE_SWS);
        return ((_x &amp; _CTYPE_R) != 0 ? 1 : -1);
}
</pre><p>さらに、__maskrune()は、やはり!_ctype.h中に定義がある。
</p><pre>static __inline int
__maskrune(__ct_rune_t _c, unsigned long _f)
{
        return ((_c &lt; 0 || _c &gt;= _CACHED_RUNES) ? ___runetype(_c) :
                _CurrentRuneLocale-&gt;__runetype[_c]) &amp; _f;
}
</pre><p>___runetype()が実際に判別する関数。これは、/usr/src/sys/lib/libc/locale/runetype.c に実体がある。
</p><pre>unsigned long
___runetype(__ct_rune_t c)
{
        size_t lim;
        _RuneRange *rr = &amp;_CurrentRuneLocale-&gt;__runetype_ext;
        _RuneEntry *base, *re;

        if (c &lt; 0 || c == EOF)
                return(0L);

        /* Binary search -- see bsearch.c for explanation. */
        base = rr-&gt;__ranges;
        for (lim = rr-&gt;__nranges; lim != 0; lim &gt;&gt;= 1) {
                re = base + (lim &gt;&gt; 1);
                if (re-&gt;__min &lt;= c &amp;&amp; c &lt;= re-&gt;__max) {
                        if (re-&gt;__types)
                            return(re-&gt;__types[c - re-&gt;__min]);
                        else
                            return(re-&gt;__map);
                } else if (c &gt; re-&gt;__max) {
                        base = re + 1;
                        lim--;
                }
        }

        return(0L);
}
</pre><p>ここで、!_CurrentRuneLocaleやRuneEntry,RuneRangeは、/usr/include/runetype.hに定義がある。_CurrentRuneLocaleは、/usr/src/lib/libcの下を検索してみると、たとえばlibc/locale/utf_8.c の!_utf8_init()で、LC_CTYPEファイルから読み込まれている。LC_CTYPEは、mklocaleコマンドで作成される。そのソースは<strong>/usr/src/share/mklocale/UTF-8.src</strong>である。これが、<strong>wcwidth()関数で、文字幅を定義してある実体</strong>。その構造は、先のrunetype.hに定義がある。またman mklocaleにも記述がある。
</p>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90">
    <title>ソースコード解析</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90</link>
    <dc:identifier>ソースコード解析</dc:identifier>
    <dc:date>2011-03-01T22:14:52+09:00</dc:date>
        <description>
      <![CDATA[== 漢字がきちんと表示されない件の解析メモ ==
=== 現象 ===
mutttをUTF-8環境(LANGが ja_JP.UTF-8)の所で使うと、キー入力した時、Unicodeで、幅が不定な文字、例えば「★」の表示が乱れる。幅が定まっている文字、例えば「〒」は乱れない。現象としては下記の通り。

  * FreeBSD8.1の場合
    * クライアントがOpenSUSEのmlt]]>
    </description>
    <content:encoded>
      <![CDATA[<h2 id="h2-.E6.BC.A2.E5.AD.97.E3.81.8C.E3.81.8D.E3.81.A1.E3.82.93.E3.81.A8.E8.A1.A8.E7.A4.BA.E3.81.95.E3.82.8C.E3.81.AA.E3.81.84.E4.BB.B6.E3.81.AE.E8.A7.A3.E6.9E.90.E3.83.A1.E3.83.A2">漢字がきちんと表示されない件の解析メモ</h2><h3 id="h3-.E7.8F.BE.E8.B1.A1">現象</h3><p>mutttをUTF-8環境(LANGが ja_JP.UTF-8)の所で使うと、キー入力した時、Unicodeで、幅が不定な文字、例えば「★」の表示が乱れる。幅が定まっている文字、例えば「〒」は乱れない。現象としては下記の通り。
</p><ul><li>FreeBSD8.1の場合
<ul><li>クライアントがOpenSUSEのmltermの場合は、★が*になって表示される。
</li><li>クライアントがOpenSUSEのgnome-terminalの場合は、1文字入力すると「★」は正しく表示されるが、2文字続けて入力すると、前の★に被さって次の★が表示される。
</li><li>クライアントがOpenSUSEのgnome-terminal で、VTE_CJK_WIDTH=1を設定した場合、連続して★を入力しても、正しく表示されるが、バックスペースを入力すると、1バイト分しか戻らない。
</li><li>クライアントがWindowsのteraterm(4.68)の場合、★を入力した後、カーソルが3バイト分進む。
</li></ul></li></ul><h3 id="h3-.E3.82.BD.E3.83.BC.E3.82.B9.E3.81.AF.E3.81.A9.E3.81.86.E3.81.AA.E3.81.A3.E3.81.A6.E3.81.84.E3.82.8B.3F">ソースはどうなっている?</h3><p>入力された文字列をハンドリングしているのは、 enter.c内の _mutt_enter_string()である。ここの、
</p><pre>
 287       clrtoeol ();
 288       move (y, x + my_wcswidth (state-&gt;wbuf + state-&gt;begin, state-&gt;curpos - state-&gt;begin));
 289     }
 290     mutt_refresh ();
 291 
 292     if ((ch = km_dokey (MENU_EDITOR)) == -1)
 293     {
 294       rv = -1; 
 295       goto bye;
 296     }

</pre><p>の、mutt_refresh()を何回か通過した時に、入力された文字列が表示される。
</p><p>実際にキーが入力されるのを待ち合わせるのは、keymap.cの中にある km_dokey()の中。更にその中から、
</p><pre>  94 #ifdef KEY_RESIZE
  95   /* ncurses 4.2 sends this when the screen is resized */
  96   ch = KEY_RESIZE;
  97   while (ch == KEY_RESIZE)
  98 #endif /* KEY_RESIZE */
  99     ch = getch ();
 100   mutt_allow_interrupt (0);
 101 
</pre><p>で、mutt_getch()が呼ばれる。ここで★(UTF8では、E2 98 85)を入力すると、まず「E2」が帰る。ちなみに、Ctrl-Gを押すと、エラーが帰るように、mutt_getch()内でハードコードされている。入力した文字は、<strong>大域変数<a href="http://sourceforge.jp/projects/mutt-j/wiki/LastKey">LastKey</a></strong>に格納される。その後、mapテーブルを検索した後、retry_generic()を呼び出し、結果を返す。
</p><pre>
 663         k = mbrtowc (&amp;wc, &amp;c, 1, &amp;mbstate);
 664         if (k == (size_t)(-2))
 665           continue;
 666         else if (k &amp;&amp; k != 1)
 667         {
 668           memset (&amp;mbstate, 0, sizeof (mbstate));
 669           continue;
 670         }
 671       }

</pre><p>次に、マルチバイト文字(UTF-8)からワイド文字(UCS-2)への変換を行う。これは、mbrtowc()関数を呼び出すことで行う。1バイトのみの解析なので、戻り値は-2(解析できなかった)が返り、ループの先頭に戻る。もう一度mutt_getch()を呼び出し、UTF-8の2バイト目を得る。これもmbrtowc()で解析失敗するので、-2が返る。3回目のループで、UTF-8の3バイト目を得る。ここで、結果が1となり、mbrtowcの引数wcにはUCS-2の文字が返る。kが1なので、mbstateの初期化は行わない。
<pre>
 699       else if (wc &amp;&amp; (wc &lt; ' ' || IsWPrint (wc))) /* why? */
 700       {
 701         if (state-&gt;lastchar &gt;= state-&gt;wbuflen)
 702         {
 703           state-&gt;wbuflen = state-&gt;lastchar + 20;
 704           safe_realloc (&amp;state-&gt;wbuf, state-&gt;wbuflen * sizeof (wchar_t));
 705         }
 706         memmove (state-&gt;wbuf + state-&gt;curpos + 1, state-&gt;wbuf + state-&gt;curpos, (state-&gt;lastchar - state-&gt;curpos) * sizeof (wchar_t));
 707         state-&gt;wbuf[state-&gt;curpos++] = wc;
 708         state-&gt;lastchar++;
 709       }
</pre>701行目のif文が真なので、703行目に移動する。すると、lastcharに20を加算したものをwbuflenとし、そのサイズをwchar_t単位(実際はint)で割り当て、wbufのcurposからwbufのcurpos+1に、lastcharからcurposの、wchar_t単位でのバイト数を移動する。言い換えれば、wbufの先頭1要素を空ける。その後、先頭にwcをコピーし、ポインタを1つずらす。またループの先頭に戻る。
</p><p>ループに戻るとmy_wcwidth()が呼ばれるところがある。ここで、bufの先頭文字の大きさが返る。UCS-2文字なので2が返る。この文字(buf内にある文字)をmy_addwch()で描画する。その後mutt_addwch()で今度はマルチバイトに変換する。bufにUTF-8文字が設定され、3が返る。
</p><p>その後、my_wcswidth()が呼ばれ、2が返る。
</p><h3 id="h3-wcwidth.28.29.E3.81.AF.E5.91.BC.E3.81.B0.E3.82.8C.E3.82.8B.3F">wcwidth()は呼ばれる?</h3><p>文字の大きさを決めるのはwcwidth()だが、それは呼ばれていない様子。ncurses内にも呼び出している所はあるが、ブレークポイントを仕掛けても引っかからない。--without-wc-funcsを指定しているからか。
</p><p><strong>→嘘。</strong>ちゃんと呼んでいるところがあった。ただし、wcwidthではなくて<strong>__wcwidth</strong>。で、★だと戻りが1,〒だと2になることを確認。そこで一旦止めて、★の場合、強引に戻り値を2にしたら表示が正しくなった。これが原因か。
</p><p><span style="text-decoration: underline;">wcwidthの仕組みは<a href="http://sourceforge.jp/projects/mutt-j/wiki/FreeBSD%E3%81%AEwcwidth">FreeBSDのwcwidth</a>にまとめる。
</span></p><h3 id="h3-.E3.81.A9.E3.81.86.E3.82.84.E3.81.A3.E3.81.A6.E6.8F.8F.E7.94.BB.E3.81.95.E3.82.8C.E3.82.8B.3F">どうやって描画される?</h3><p>シングルバイトの場合は、1バイトずつ、マルチバイトの場合は、_mutt_enter_string()でUTF-8文字の組み立てを終え、3バイトになってから、mutt_addwch()を呼び出す。この中で、addstr()を呼び出している。addstr()を呼び出す前に引数bufの中身がどうなっているかを見ると、
</p><pre>★の場合

[2011-02-13 20:54:35] before_addwch w=0002 wbuf=2605
[2011-02-13 20:54:35] addstr buf=ffffffe2 ffffff98 ffffff85        0
[2011-02-13 20:54:35] before move2 y,x=35,11
[2011-02-13 20:54:36]    a
[2011-02-13 20:54:36] ★

</pre><pre>〒の場合

[2011-02-13 20:59:43] before move1 y,x=35,9
[2011-02-13 20:59:43] before_addwch w=0002 wbuf=3012
[2011-02-13 20:59:43] addstr buf=ffffffe3 ffffff80 ffffff92        0
[2011-02-13 20:59:43] before move2 y,x=35,11
[2011-02-13 20:59:43]    a
[2011-02-13 20:59:43] 〒
</pre><p>で、正しく3バイトがcursesの方に渡されている。
</p><h2 id="h2-.E3.81.9D.E3.81.AE.E4.BB.96">その他</h2><ul><li><a href="http://sourceforge.jp/projects/mutt-j/wiki/ncurses%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0">ncursesのデバッグ</a>
</li></ul>]]>
    </content:encoded>
      </item>
        <item rdf:about="http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4">
    <title>ファイル置き場</title>
    <link>http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4</link>
    <dc:identifier>ファイル置き場</dc:identifier>
    <dc:date>2009-02-18T16:46:53+09:00</dc:date>
        <description>
      <![CDATA[= コンパイル済みパッケージ置き場 =
== CentOS4.7用 ==
* [[LinkAttach(mutt-1.5.19-1Ja.i386.rpm)]]

* [[LinkAttach(libiconv-1.12-1.i386.rpm)]]]]>
    </description>
    <content:encoded>
      <![CDATA[<h1 id="h1-.E3.82.B3.E3.83.B3.E3.83.91.E3.82.A4.E3.83.AB.E6.B8.88.E3.81.BF.E3.83.91.E3.83.83.E3.82.B1.E3.83.BC.E3.82.B8.E7.BD.AE.E3.81.8D.E5.A0.B4">コンパイル済みパッケージ置き場</h1><h2 id="h2-CentOS4.7.E7.94.A8">CentOS4.7用</h2><p>* <a href="http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4/attach/mutt-1.5.19-1Ja.i386.rpm" title="mutt-1.5.19-1Ja.i386.rpm" alt="mutt-1.5.19-1Ja.i386.rpm" id="la-mutt-1.5.19-1Ja.i386.rpm-1" class="link-attach"><img border="0" alt="" src="http://static.sourceforge.jp/wiki/images/icons/mime/24x24/rpm.png">mutt-1.5.19-1Ja.i386.rpm</a>
</p><p>* <a href="http://sourceforge.jp/projects/mutt-j/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4/attach/libiconv-1.12-1.i386.rpm" title="libiconv-1.12-1.i386.rpm" alt="libiconv-1.12-1.i386.rpm" id="la-libiconv-1.12-1.i386.rpm-1" class="link-attach"><img border="0" alt="" src="http://static.sourceforge.jp/wiki/images/icons/mime/24x24/rpm.png">libiconv-1.12-1.i386.rpm</a></p>]]>
    </content:encoded>
      </item>
    </rdf:RDF>

