WebKit Kindle DX backport

Posted by TJ Wei on 星期日, 8月 21, 2011 with 2 comments
Kindle DX 的 netfront 瀏覽器雖然堪用,但是很多網頁讀不出來。
比方說我的部落格首頁就會出現記憶體不足的訊息,網頁呈現的效果雖然似乎挺清爽乾淨,但是 DX 螢幕有 824x1200 的解析度,足以顯示完整的網頁。
整體來看,還是 kindle 3 的瀏覽器較佳。一個作法是直接讓 DX 執行 kindle 3 的作業系統。非常神奇的是,居然沒有什麼問題。但既然 kindle 基於 open source,也釋出了修改過的程式碼,所以我試著將 kindle 3 的 webkit 移植到 dx 上。
初步的結果如下:

還不是很完整,但至少能在 google 裡打個搜尋,顯示一些網頁。
過程是 Directfb -> Gtk+ -> WebKit
  • 編譯環境; scratchbox
    • toolchain 用的是 glibc2.5 2007q1。雖然說 libstdc++ 和 kindle dx 的不相容,但 2006q3 太舊了,很難編譯。而且 gtk+ 用的是 C 而不是 C++,webkit 雖然用 C++ 但是沒有用到 libstdc++ 而是自帶的程式庫,所以問題不大。這點從android 極為貧乏的 C++ runtime 可見端倪。因為顯然同樣是 WebKit based 的 Android web browser 不需要完整的 libstdc++。所以 glibc2.5 的 toolchain 應該都可以。
    • 在 amd64 的 linux 下使用 scratchbox i386 binary, kernel 要增加 vdso32=0 的參數,不然會有 Inconsistency detected by ld.so: rtld.c: 1192: dl_main: Assertion `(void *) ph->p_vaddr ==  的錯誤
    • 我的 cputransp 跑不起來,所以我自己編譯了一個 static linked x64 qemu-arm。然後寫了一個 wrapper 來吃 binfmt 餵進來  --sbox 的參數。除了 pthread 外,似乎沒什麼問題。跑 configure 時,一些 pthread 的測試程式會停不下來,也許是 qemu 的問題。當碰到這個問題的時候,都是手動修改 configure.in 裡面的測試程式,讓他直接通過。
  • 我在 /mnt/us 上弄了個 200mb 的 ext3 loop filesystem,mount 到 /usr/local 上。之後只要 設好 ld.so 或者設定 LD_LIBRARY_PATH=/usr/local/lib 即可,不會影響原系統。
  • 編譯 DirectFB
    • 用的是 kindle 3 的 source。設定 --prefix=/usr/local,gfxdriver=none
    • 編譯所需的 jepg 和 libpng 時,設定 --prefix=/usr。libpng 需要 1.2 版的。我當初一時不察,用了 libpng 1.4 ,所以修改了一點 DirectFB 的程式碼解決 libpng 1.2 的相容問題,還要額外的安裝 libpng 1.4 到 /usr/local
    • 編譯上沒有什麼問題,然後把 /usr/local copy 到 kindle 完成安裝上。可以利用 ssh+tar 或者 ssh mount 來複製檔案。
    •  kindle 的 eink framebuffer 是 4bit 灰階,無法被 directFB 直接支援,所以只好當成 indirect fb 來使用。如果你在這裡花上零點五秒來想想該怎麼解決這個問題,你會發現 amazon 的 lab126 想的解法和你一樣。他用了一個 LUT8 (8bit indexed color) 的 virtual framebuffer 來假裝是真正的 frame buffer,然後就能順利建構 DirectFB 。接下來只要設法讓 virtual frame buffer 和真正的 frame buffer 來互通有無即可。lab126 用的是 call back 的方式讓使用者程式自行決定如何處理。雖然從程式碼來看, lab126 取得 frame buffer address 的方式似乎有點不保險。
    • kindle 3 的 eink 比 DX 多了好幾種 update eink screen 的方式。
    • lab126 版的 DirectfB 基本上有考慮到 DX 的按鍵,除了一個 keymap 的檔案。所以要修改這個檔案,不然之後有些按鍵會出問題。我順便把 Sym 鍵設成 Tab。
    • 要用 no-vt 模式執行。可將 no-vt 加入 ~/.directfbrc 裡面。 
  • 編譯 GTK+
    • 編譯基本上沒有太大的問題,但是很繁雜。有些 kindle 3 source 沒有 autogen.sh 或者 configure 時,就 aclocal && autoconf && automake。還不行,就抓一份相同版本的正版 source ,然後把 lab126 版 copy 過去。
    • DX 的 glib 太舊了,要弄個新版的到 /usr/local 裡。在 scratchbox 中,我也順便把新版的 glib 裝到 /usr/ 下,之後編譯會比較輕鬆。
    • 雖然沒什麼道理,但 gtk-doc 似乎不裝到 /usr/ 下,automake 就抓不太到。雖然常常 configure 時可以關掉 gtk-doc,但有時需要 autogen 的時候, 不裝個  gtk-doc 就過不了關。autogen 應該是設計來簡化問題的,而不是用來增加問題的。 
    • automake 版本要用 SBOX_DEFAULT_AUTOMAKE 設定到 1.9。不然會有 tar-ustar 錯誤。
    •  直接編譯完,執行 gtk-demo 會出現像是 這裡的情形。我的作法是在 gdk_init 裡面加上自己的 kindle dirty rect callback ,把更動過得方塊更新到 eink screen 上。這樣, gtk-demo 就能正常顯示。
    • 如果前面 directfb 的 keymap 沒改好,會發生 gtk-demo 裡面上下鍵無法使用的狀況。
    • 我遇到了 字體都變成方格這個問題。google 查詢到,似乎某些 pango + cairo 的組合會發生這種情形,所以我將 pango 和 cairo 換成稍微新一點的版本。lab126 有更動 cairo 程式碼,不過看起來只是 hack 某些 font 資訊的問題,不是什麼致命的問題,所以我直接使用無修正板。
    • 我設定了 gtkrc-2.0 ,讓字體大一點,也設定了 fontconfig 來使用 /usr/java/lib/fonts 中相對應的字型。
    • 除了 gtk-demo,我試了 leafpad,gtkterm, gqview。 leafpad 和 gtkterm 都能正確編譯執行,但是視窗要修改或者設定成大一點,最好是全螢幕。原因是 gtk游標會在螢幕正中間,如果 gtk 程式的視窗太小,會因為鼠標沒有在視窗上而抓不到 keyboard focus。這大概是 directfb的 wm 的特性。gqview 也可執行和操作,但是似乎圖形顯示有問題。gtkterm 需要 vte,編譯 vte 時,需要 termcap。雖然用 ncurses 取代 termcap 也行,但是 ncurses 我編不起來,也懶得弄。除了 gtkterm 外,vte 本身應該也能跑。和 kindle 上其他的 terminal 程式相比,vte based terminal 的一大優點是可以顯示正確顯示 utf8 中文。LXDE 的 gpicview 雖然標榜純 gtk,但其實有用到 X11。光是 gdkx.h 也就罷了,其中有用到 X11 的檔案,所以無法直接編譯。gedit 因為需要 gtksourceview 一堆的,看起來太複雜了,就沒有真的弄起來。
  • WebKit
    • 查看 kindle 3 的 source code 裡的 Changelog,到 2009年5月18日,所以下載了 webkit r43841。
    • 解開後將 kindle 3 裡面修改過的 source 複製並且覆蓋過去。
    • 修改 configure.ac,讓 directfb 變成 default。因為 build-webkit 似乎沒有這個選項。
    • 執行 WebKitTools/Script/build-webkit --gtk,我選擇關掉 xslt還有一些不需要的選項。
    • make 過程會出現錯誤,因為一些 .h 檔沒有放對位置。可以修改 GNUMakefile 或者 source,或把 .h ln -s 到適當地位置。總之,依個人喜好,讓他編譯過去就是了。
    • 還有一些錯誤是 kindle profiling 相關的,我直接刪除相關的部份。
    • GtkPerf 的 link 會出問題,要把 .libs/libWebcore.a 連進去。
    • make install 後把 /usr/local copy 到 kindle 就行了。
    • 編出來的 GtkLauncher 可以執行,但是 kindle 的 proxy 需要特別的 x-fsn http header,所以暫時還不能上網。可以嘗試用 GtkLauncher 瀏覽 kindle 裡面的 local 檔案,要用完整檔名。如果發現只看到 html 的 source code,那是因為沒有 mime data。將你電腦裡面的 /usr/share/mime copy 去 kindle 即可。
    • 這個版本的 webkit settings 沒有支援 user-agent 修改,也沒有支援 proxy,更沒有支援客製化的 http header,所以修改程式碼送出適當的 header,和使用 proxy。
    • 修改被 lab126 修改過的 GtkLauncher 程式碼,讓 urlbar 顯示出來。
    • urlbar 可以輸入,但是 google 搜尋框無法輸入文字。經 google 查詢後,發現是 ICU 問題。我用的是 ICU 3.6,在 scratchbox 中無法順利編譯,因為 pkgdata 無法執行。我修改 makefile,讓 pkgdata 能順利執行,完成 make。但是顯然我漏了什麼。依照這裡的方式,重新編譯。這時,輸入框就能輸入了。
    • 我不曉得如何用鍵盤完整的操作,GtkLauncher,即使打開 caret browsing,也不知道怎麼操作,介面還需要修改。中文輸入法也還沒整合進去。 
Categories: ,