puttyのコンソールでIMEの切り替え時カーソル色を変更するパッチを書いた(初めてのOSS活動)
※追記:コンパイルしたexeファイル
1年くらい前に、人力はてなでこんな質問をしました。
question:1164473105
kaoriya版gvimではwindowsのIMEを使うので、『has('multi_byte_ime')』でIMEの状態を取得し、IMEのON/OFFでカーソル色を変更できます。
puttyなどの仮想端末を使った場合は、vimは接続先のソフトを使い、
インプットメソッドは仮想端末からWindowsのIMEを使って入力するので、
IMEの状態を取得することができないようです。
四苦八苦してもvimのみでは解決できそうにもなかったので、
putty自体にvimrcにこれと同じ機能を実装すれば良いのでは?と思って、初めてのOSS活動をしました。
if has('multi_byte_ime') || has('xim') " 日本語入力ON時のカーソルの色を設定 highlight CursorIM guibg=dodgerblue guifg=NONE endif
その時に自分で書いたパッチを公開していなかったので、今まで色んなソフトを使わせて頂いているので、
私も少しでもフィードバックできればと思い、パッチを公開します。
どこを編集したらいいのかもわからず、taglist.vim*1を使ってじっくりソースを解析したり、ソースの相談をさせて他方にさせて頂いたり*2、C言語は全く使った事がなかったので、C特有の事に関しては周りのC言語経験者に相談して書きました。
なので色々とご指摘やレビューなどして頂けるとうれしいです。
問題がなければ、近々ごった煮の「蛭子屋」さんにパッチを送ってみたいと思います。
手順
- ソースとパッチを取得する
- コンパイル環境を揃える
- パッチをあてる
パッチファイルを取得する
【putty0.60のソースを取得する】
http://the.earth.li/~sgtatham/putty/0.60/putty-0.60.tar.gz
【puttyのごった煮パッチを取得する】
http://yebisuya.dip.jp/DL/putty-0.60-JP_Y-2007-08-06.zip
私が書いた、パッチを保存する
diff -urN config.c config.c --- config.c 2008-03-23 22:33:27.468750000 +0900 +++ config.c 2008-03-23 22:33:25.843750000 +0900 @@ -616,7 +616,7 @@ static const char *const colours[] = { "Default Foreground", "Default Bold Foreground", "Default Background", "Default Bold Background", - "Cursor Text", "Cursor Colour", + "Cursor Text", "Cursor Colour", "IME Cursor colour", "ANSI Black", "ANSI Black Bold", "ANSI Red", "ANSI Red Bold", "ANSI Green", "ANSI Green Bold", diff -urN settings.c settings.c --- settings.c 2008-03-23 22:33:28.296875000 +0900 +++ settings.c 2008-03-23 22:33:26.531250000 +0900 @@ -687,10 +687,10 @@ gppi(sesskey, "Xterm256Colour", 1, &cfg->xterm_256_colour); gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour); - for (i = 0; i < 22; i++) { + for (i = 0; i < 23; i++) { static const char *const defaults[] = { "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0", - "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85", + "0,255,0", "0,0,255", "0,0,0", "85,85,85", "187,0,0", "255,85,85", "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187", "85,85,255", "187,0,187", "255,85,255", "0,187,187", "85,255,255", "187,187,187", "255,255,255" diff -urN windows/putty.lng windows/putty.lng --- windows/putty.lng 2008-03-23 22:33:28.921875000 +0900 +++ windows/putty.lng 2008-03-23 22:33:27.156250000 +0900 @@ -192,7 +192,8 @@ Default Background=標準の背景 Default Bold Background=標準の強調背景 Cursor Text=カーソル上の文字 -Cursor Colour=カーソルの色 +Cursor Colour=IME_OFF時カーソルの色 +IME Cursor Colour=IME_ON時カーソルの色 ANSI Black=ANSI 黒 ANSI Black Bold=ANSI 黒 太字 ANSI Red=ANSI 赤 diff -urN windows/window.c windows/window.c --- windows/window.c 2008-03-23 22:33:29.000000000 +0900 +++ windows/window.c 2008-03-23 22:33:27.265625000 +0900 @@ -1409,12 +1409,12 @@ { int i; static const int ww[] = { - 256, 257, 258, 259, 260, 261, + 256, 257, 258, 259, 260, 261, 262, 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 }; - for (i = 0; i < 22; i++) { + for (i = 0; i < 23; i++) { int w = ww[i]; defpal[w].rgbtRed = cfg.colours[i][0]; defpal[w].rgbtGreen = cfg.colours[i][1]; @@ -1454,6 +1454,7 @@ { COLOR_WINDOW, 258, 259 }, /* Default Background */ { COLOR_HIGHLIGHTTEXT, 260, 260 }, /* Cursor Text */ { COLOR_HIGHLIGHT, 261, 261 }, /* Cursor Colour */ + { COLOR_HIGHLIGHT, 262, 262 }, /* IME Cursor Colour */ }; for (i = 0; i < (sizeof(or)/sizeof(or[0])); i++) { @@ -2387,12 +2388,48 @@ WPARAM wParam, LPARAM lParam) { HDC hdc; + HIMC hImc = NULL ; + BOOL bIMEOpen = FALSE ; static int ignore_clip = FALSE; static int need_backend_resize = FALSE; static int fullscr_on_max = FALSE; static UINT last_mousemove = 0; + static BYTE defCursorPal[3] ; switch (message) { + case WM_IME_NOTIFY : /* IME_Notify_Message */ + if(wParam == IMN_SETOPENSTATUS){ + hImc = ImmGetContext(hwnd); + if(hImc){ + BOOL bIMEOpen = ImmGetOpenStatus(hImc); + if(bIMEOpen){ + /* default cursor color setting */ + defCursorPal[0] = defpal[261].rgbtRed ; + defCursorPal[1] = defpal[261].rgbtGreen ; + defCursorPal[2] = defpal[261].rgbtBlue ; + + /* IME_ON cursor color setting */ + defpal[261].rgbtRed = defpal[262].rgbtRed; + defpal[261].rgbtGreen = defpal[262].rgbtGreen; + defpal[261].rgbtBlue = defpal[262].rgbtBlue; + + init_palette(); + InvalidateRect(hwnd,NULL,FALSE); + UpdateWindow(hwnd); + } + else { + /* IME_OFF cursor color setting */ + defpal[261].rgbtRed = defCursorPal[0] ; + defpal[261].rgbtGreen = defCursorPal[1] ; + defpal[261].rgbtBlue = defCursorPal[2] ; + + init_palette(); + InvalidateRect(hwnd,NULL,FALSE); + UpdateWindow(hwnd); + } + } + } + break ; case WM_TIMER: if ((UINT_PTR)wParam == TIMING_TIMER_ID) { long next;
コンパイル環境を整える
コンパイルはCygwinでの説明を書きます。が、『VisualC』『BorlandC』などのMakefileもあるので、Cygwin以外でも全然問題ありません。※追記2008/3/25:Visual C++でビルドしてみましたが、パッチを当てるとエラーが発生する事を確認しました。私のパッチ手順が間違っているか、ソースに手を加える必要がでてきます。確認を怠っていい加減な事書いてしまって、すいませんでした。
cygwinのsetup時に下記パッケージをインストールする。
他にもなにかインストールしかもしれないですが、必要なコマンドが足りなければインストールしてください。
パッチをあてる
まずは、cygwinでワークディレクトリでも作っておき
【例】
~/work/
puttyのソースファイル「putty-0.60.tar.gz」を配置し、cygwin上でファイルを展開します。
tar zxf putty-0.60.tar.gz
次にごった煮パッチを展開し、パッチファイルをputtyソースディレクトリに移動します。(putty-0.60-JP_Y.patchとputtyd.icoのみ使用)
ここでは、まだicoファイルは移動しません。
unzip putty-0.60-JP_Y-2007-02-06.zip mv ./putty-0.60-JP_Y-2007-08-06/putty-0.60-JP_Y.patch ./putty-0.60/
次に、ごった煮パッチを当てます。(パッチを置く階層が間違っているとファイル名を聞かれます。パッチ実行後は問い合わせないなしで完了します)
cd ./putty-0.60 patch -Np0 < putty-0.60-JP_Y.patch
次に、IMEカーソル色パッチを当てます。同じくputty-0.60のソースディレクトリにIMEパッチファイルを配置し、パッチを実行します。
patch -Np0 < putty-0.60-JP_Y_IME.patch
次に、Makeファイルを作成する為に「mkfiles.pl」を実行します。
perl ~/work/putty-0.60/mkfiles.pl
次に、ごった煮パッチのzipで解凍したファイルに含まれていたicoファイルをwindowsディレクトリに配置します。*3
~/work/putty-0.60/windows/puttyd.ico
次に、Makeを実行します。
make -f ~/work/putty-0.60/windows/Makefile.cyg
コンパイルが開始されるので、暫く待ちます。
完了したらwindowsディレクトリに、putty.exeができてているはずです。
必要なファイルは「ごった煮版パッチ」のzipファイルに入っていたファイルだけですので、後で移動させてあげるといいと思います。
これで完了です。
動作確認は、コンパイルしたputty.exeを起動し、『ウインドウ』→『色』に「IME_OFF時カーソルの色」と「IME_ON時カーソルの色」が入っている事を確認します。
次に、puttyを起動してコンソールを表示させ、IMEの切り替えで色が変わる事を確認します。