Gtk UTF-8 vs Shift_JIS

Gtkでの日本語を含むファイル名の扱いを調べるのを目的としたプログラムです。
glade3.6.7 + gtk2.16 + ICU4.8.1 + VisualStudio 2010 Express の環境で、File Chooser、ドラッグ&ドロップ(DnD)で日本語のパス名を受け取り、ファイルをオープンします。ファイルオープンには敢えて fopen を使います。つまり、ファイル名はShift_JISの char* で指定しなければならないということになります。
このプログラムは、何かのユーティリティを意図したものではなく、文字エンコードを調べるために使った実験用プログラムです。概要は下のほうにありますが、まずは、実験用のプログラムの現物です。VisualStudio2010 Express のソリューションごと梱包しています(TICU.zip)。IDEデバッグで使用することを前提としています。リリースビルドはセットアップしていません。

IDEデバッグで実行するのを前提としていますが、コンソール(bash、com.exe)で実行する場合は、実行フォルダの場所にgladeファイル(TICU.glade)を置いてください。

TICU/
├ Debug/
│  └ TICU.exe
├ glade-3.6.7-with-gtk-2.16-Debug-Win32-msvc100.props
├ icu4c-4.8.1.1-Win32-msvc100.props
├ main.cpp
├ TICU.glade
├ TICU.sln

上記フォルダ構成の元で、実行フォルダをTICU/とすれば、次のようなコマンドで実行します。

etc@etcpc /cygdrive/c/projects/TICU
$ ./Debug/TICU.exe

概要

  1. File Chooser あるいは、DnDされたファイルのパス名を取得します。
  2. 一旦ラベルウィジェットに設定します。
  3. ラベルウィジェットの notify イベントをコールバック関数で捕まえます。
  4. コールバック関数内で、Shift_JIS に変換し、ファイルをオープンします。
  • 各きっかけでファイル名のエンコードを調べてTextViewにトレース情報として出力します。

一旦ラベルウィジェットに設定するのは、本質的なものではありません。ラベルウィジェットを介したイベントを利用することで、処理を一元化できると共に、File ChooserとDnDのパス名のエンコーディングの違いがより明確になるものと期待した所業です。

File Chooser

Gtk内部はUTF-8です。当然ながら、File Chooserが返すファイル名はUTF-8です。 日本語を含んでいてもGtkウィジェットに対して、そのまま使用できます。

ドラッグ&ドロップ(DnD)

DnDされたファイル名は、URI形式になっています。 日本語はパーセントエンコードされています。これは、gtkのユーティリティ関数を使って、UTF-8の通常のファイル形式に変換できます。

ファイルオープン

fopenを使っています。Windows(OS)のファイル名はShift_JISなので、UTF-8Shift_JISに変換します。関数 g_win32_locale_filename_from_utf8 (filename); を使います。

Windowsプログラムでありがちな、TCHAR、_T()などの国際化、汎用テキストマップなどは関係しません*1。また、ICUは変換に関与していません。エンコードの変換自体は、gtkの関数のみで行っています。

このプログラムではエンコードの種類を調べる目的で、ICUを利用しました。ICUエンコード検出関数はなかなか曲者です。可能性のあるエンコード名をすべてリストアップするので、日本語であると共に、フランス語やトルコ語であるとも検出されます。そのため、最終的な判断では 付与されているConfidence(信頼度)を考慮します。これは、0〜100の値を取り、100は完全に信頼できるという意味らしいです。しかし、今回のようなパス名の場合だと、文字列中に大量のASCII文字が混在するので、微妙な数値が出ることがあります(80とか85とか)。このような問題はありますが、実際の変換には参照していないので、今回はこれ以上の探求は行いませんでした。

環境のまとめ

次のライブラリが必要です。

  • glade3-3.6.7-with-GTK+(glade3.6.7、gtk2.16)
    • インストーラになっているので、起動して適当な場所にインストールして下さい。
    • 環境変数 Path と GTK_HOME が自動で設定されるはずです。例えば、次のようになります。
  • icu4c-4_8_1_1-Win32-msvc10
    • 展開して、適当な場所に置いてください。
    • 環境変数として、例えば、次のようにします(dllのために必要です)。
      • PATH=c:\Program Files(x86)\icu\bin
    • また、vs2010のソリューションに使用しているプロパティシート(icu4c-4.8.1.1-Win32-msvc100.props)で使用しているマクロのために、環境変数ICU_HOMEを、例えば次のように設定します。

GNOME glade本家
ICU本家

*1:今回はソースコード内で日本語リテラル文字列を使っていないので、ソースコードエンコードも関係しません。