前書き
xtermでいうとこの~/.Xresourcesに書くような
XTerm*background: #000000 XTerm*foreground: #ffffff XTerm*color0: #242424
こんな感じの部分を~/.fbtermrcで設定できるようにする
以前からこんな機能ほしかったけどfbterm自体あんまり使わないからかかなかった
でもまたお世話になりそうなんで書く
というか書かないとデフォルトの色は見にくい、今まで誰もやらなかったのが不思議なほどだよ
やり方
patchを書いたので
https://raw.github.com/silenvx/PKGBUILD/master/fbterm/config_colors.patch
ここから各自落として当てたら使えます
archlinux系の人は
% git clone https://github.com/silenvx/PKGBUILD.git % cd PKGBUILD/fbterm % makepkg -i
で入る
~/.fbtermrcには
color-0=000000 color-1=952519 color-2=69821b color-3=af8700 color-4=3387cc color-5=a757a8 color-6=418179 color-7=a0a8b0 color-8=444444 color-9=ff5f55 color-10=73d144 color-11=ffd348 color-12=89bdff color-13=d787ff color-14=71bebe color-15=c3c6ca
こんな感じで24bitの16進数で色を書いて0から15までの色を指定できる
どんな感じかはどっかに落ちてるであろう256colors2.plを使って確認するといい
但しtmux上でないと画面がバグるので注意
たぶんhttps://joeldotfiles.googlecode.com/svn/trunk/256colors2.pl このあたりに落ちてると思う
patchを書くためにしたソースコードとの戯れ方 (ここから下は読む必要ない)
既にbgとfgならば~/.fbtermrcにて
color-background=0
こんな書き方が可能なのでこの変数名を使ってソースコード全体に検索をかけることにする
ソースコードを展開させて、そこをカレントディレクトリにしたのちfindする
% find . -type f -exec grep -nH 'color-background' {} + ./src/screen_render.cpp:80: Config::instance()->getOption("color-background", color); ./src/fbconfig.cpp:184: "color-background=0\n" ./src/fbconfig.cpp:231: { "color-background", required_argument, 0, 'b' }, ./src/fbconfig.cpp:267: " -b, --color-background=NUM specify background color\n" ./src/fbshell.cpp:328: Config::instance()->getOption("color-background", color); ./doc/fbterm.1.in:52:\fB-b, --color-background=\fR\fInum\fR
実際に値を使って何かしているのは
./src/screen_render.cpp:80: Config::instance()->getOption("color-background", color); ./src/fbshell.cpp:328: Config::instance()->getOption("color-background", color);
この2つなのでまずは上から見ていく
void Screen::initFillDraw() (略) Config::instance()->getOption("color-background", color); if (color > 7) color = 0; bgcolor = color;
initFillDraw()関数内の処理のようだ、関数名にiniとdrawが使われていることから描写に関する初期化処理だろう
color-backgroundの変数には0から7の値のうちどれかを入れることになっているので
if文で判定して、範囲外なら0にしていることから察するに
検索でヒットした行はcolor-backgroundの値を取得しているようだ
この時に気づいたんだが、今見てるのは背景に関する処理っぽいし
文字と背景は処理違う気がしてきたのでcolor-foregroundで検索し直した
% find . -type f -exec grep -nH 'color-foreground' {} + ./src/fbconfig.cpp:183: "color-foreground=7\n" ./src/fbconfig.cpp:230: { "color-foreground", required_argument, 0, 'f' }, ./src/fbconfig.cpp:266: " -f, --color-foreground=NUM specify foreground color\n" ./src/fbshell.cpp:324: Config::instance()->getOption("color-foreground", color); ./doc/fbterm.1.in:49:\fB-f, --color-foreground=\fR\fInum\fR
fbconfig.cppは見るからに設定ファイルに関する処理なのでで残った選択肢からfbshell.cppの方を見ると
このファイルの
static const Color defaultPalette[NR_COLORS] = {
ここに256色の パレットカラーがあることに気づいたのでとりあえず~/.Xresourcesに書いてるのと同じ値を
0番から15番に記入してコンパイルして試しに実行してみると予想通り色が変更された
ちなみにxtermの場合は./256colres.hと./charproc.cで定義されているみたいだ
ソースコードまでは確認してないがxtermの場合はbgと256色の0番は違うのでfbtermもそれに倣ってpatchを書いていく
ひとまずは0番から15番までの色を~/.fbtermrcで指定できるように改変していく
仕様としては~/.fbtermrcに
color-0=000000 color-1=FF0000
みたいな感じで書いていけるようにする
まずは設定の追加方法を知るためにtermを指定できるようにするpatchが既にあるのでそれを参考にする
http://code.google.com/p/fbterm/issues/attachmentText?id=48&aid=480002000&name=fbterm-1.7-term.patch
それで見た結果、
Config::instance()->getOption("term", term, sizeof(term));
こんな感じで呼び出すだけで設定が抜き取れそうだったのでさっそく改変して
s8 hoge[32] = "hoge" Config::instance()->getOption("hoge", hoge, sizeof(hoge)); setenv("HOGE", hoge, 1);
こんな感じのをsrc/lib/shell.cppのvoid Shell::createShellProcess(s8 **command)に埋め込んでみて
~/.fbtermrcにhoge=foobar的なのを書いて、% echo $HOGE でfoobarが出力されるのを確認した
けど最初にhogeを代入する必要があったのか疑問だな…~/.fbtermrcから設定を取ってくるときに未定義だとNULLっぽいし
そういうわけで後は
static const Color defaultPalette[NR_COLORS] = {
からconstとって勝手に代入するようにするだけ
このColor型は
% find . -type f -exec grep -nH 'Color' {} +|grep struct ./src/screen.h:29:struct Color { ./src/fbshell.h:82: struct Color *mPalette;
src/screen.hで定義されていて
struct Color { u8 red, green, blue; };
unsigned char型が3つ並んでるだけです
ここまで分かれば後はアルゴリズムは思いつきますが、どこに書けばいいのかわかりません
とりあえずdefaultPalette変数が使われてる前で書き換えさえすれば問題なさそうなので検索する
% find . -type f -exec grep -nH 'defaultPalette' {} + ./src/fbshell.cpp:42:static const Color defaultPalette[NR_COLORS] = { ./src/fbshell.cpp:522: memcpy(mPalette, defaultPalette, sizeof(defaultPalette)); ./src/fbshell.cpp:539: screen->setPalette(defaultPalette); ./src/fbshell.cpp:572: screen->setPalette(mPaletteChanged ? mPalette : defaultPalette); ./src/fbshell.cpp:582: screen->setPalette(defaultPalette);
それぞれの処理は
void FbShell::request(RequestType type, u32 val) void FbShell::switchVt(bool enter, FbShell *peer)
このどちらかの関数かで行われてる
それぞれの関数の最初の処理に青と緑だけ色をつける処理を書いてみたところ
void FbShell::switchVt(bool enter, FbShell *peer)
こっちの方で書いた緑色が表示されたのでとりあえずこの関数の先頭に書き換える処理を書く
そうと決まればどんな風に書けばいいか想像する
まず取得する値は文字列になるので6byte
1byteの数字の範囲は0~F
2byteを16進数の1byteに変換する
それが3組できて、それぞれの対応した1byteをred,green,blueに代入する
そして試しにcolor-0だけいじるようにしたpatchがこれ
diff -Narup fbterm-1.7.orig/src/fbshell.cpp fbterm-1.7/src/fbshell.cpp --- fbterm-1.7.orig/src/fbshell.cpp 2014-03-19 20:26:38.615617000 +0900 +++ fbterm-1.7/src/fbshell.cpp 2014-03-19 20:27:41.665617000 +0900 @@ -39,7 +39,7 @@ #define screen (Screen::instance()) #define manager (FbShellManager::instance()) -static const Color defaultPalette[NR_COLORS] = { +static Color defaultPalette[NR_COLORS] = { {0x00, 0x00, 0x00}, /* 0 */ {0xaa, 0x00, 0x00}, /* 1 */ {0x00, 0xaa, 0x00}, /* 2 */ @@ -552,6 +552,31 @@ static s32 tty0_fd = -1; void FbShell::switchVt(bool enter, FbShell *peer) { + s8 color[7]={0}, rgb[3]={0}; + u32 i,j,x; + Config::instance()->getOption("color-0", color, sizeof(color)); + for(i=0;i<3;i++){ + for(j=0;j<2;j++){ + x=i*2+j; + if(('0' <= color[x]) && (color[x] <= '9')) + rgb[i]|=(color[x]-48); + else if(('A' <= color[x]) && (color[x] <= 'F')) + rgb[i]|=(color[x]-55); + else if(('a' <= color[x]) && (color[x] <= 'f')) + rgb[i]|=(color[x]-87); + else + goto NoTouch; + if(!j) + rgb[i]<<=4; + } + if(i==2){ + defaultPalette[0].red=rgb[0]; + defaultPalette[0].green=rgb[1]; + defaultPalette[0].blue=rgb[2]; + } + } +NoTouch: + if (tty0_fd == -1) tty0_fd = open("/dev/tty0", O_RDWR); if (tty0_fd != -1) { seteuid(0);
後はcolor-15までループさせればいいだけなのでループさせてから
処理をオブジェクト化して終了
後書き
backgroundとforegroundの色を独立して書くのは何かもう面倒臭いからまたやりたくなったら書きます
これで使いやすいブラウザがあれば最強なんだが
w3mは最高に使いにくい
vimperatorライクで使えたら最高なんだがな…