小松鼠嚇了一跳,有了魔法眼鏡後,這世界看起來完全不一樣了

2011年8月21日 星期日

WebKit Kindle DX backport

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,也不知道怎麼操作,介面還需要修改。中文輸入法也還沒整合進去。 

2011年8月15日 星期一

Kindle DX 的酷音中文輸入法 (2)

(上接 Kindle DX 的酷音中文輸入法
(更新** GitHub 專案 https://github.com/tjwei/KindleChewing )
檔案 Source and Binary 在此 目前預設是使用許氏鍵盤,可用 Sym 切換漢語拼音。我沒有包入普通的注音鍵盤,因為 kindle 上面數字鍵比較不好打,而且鍵盤上沒有標注音符號。普通的注音輸入法,沒有特別不能用的理由,但雖然 alt-q alt-w 的方式,可以正確輸入 1,2 等等數字,但 . < ; - 這些鍵不能直接輸入,所以還是有些音打不出來,需要用其它鍵代替。
更新:
  • 修改 post key event 的方式,讓一些 kindlet 也能使用。
  • 簡單的處理了螢幕旋轉的狀況。
原理說明:
  1. khk.jar 是一個假的 msp.jar。msp.jar 就是 kindle 裡面的採地雷/五子棋小遊戲。Kindle 會在使用者介面啟動時,載入 msp.g 這個 class。msp 大致上還能猜出跟 Mine Sweeper 之間的關聯,但是一個 class 叫 g 就有點怪。不過這是由於 kindle 的程式碼被弄亂過得原因。總之,這個是寫死的。這個 class 不能叫做 msp.h, msp.g2, msp.gg, msp2.g,就只能叫做 msp.g,不然 kindle 主程式不會主動過來招呼你的,因為跟你不熟。當然你也可以假裝成為其他 kindle 認識的人,比方說像是 browser, pictureviewer, pdfreader, mobireader 之類的,甚至是 home,但比較起來,採地雷看起來最人畜無害,所以選擇假扮 msp。
  2. 假扮 msp 的方式參考 http://www.mobileread.com/forums/showthread.php?t=61093 ,但只有精神上類似,因為 kindle 內部改了很多。不用完全模仿 msp 的格式,任何 class 都行。只要記得把 meta info 包進去就行了。反正重點只是要讓 kindle 呼叫 g() 這個constructor。名稱叫 khk 的原因是要搶在 msp.jar 之前載入,先搶先贏。如果你叫做 msp2.jar,就只能繼續玩踩地雷了。不過這算是不太保險的 hack。因為沒有人保證 khk.jar 一定會在 msp.jar 前面載入。完全只是因為 kindle 啟動 script 裡面的 booklet/*.jar 造成 cvm 的 command option 中, khk 會比 msp 前面。
  3. khk 可用,msp 就不能用了。當然,其實可以修改 msp 程式碼,讓 msp.g 載入我們的程式碼之後,繼續他原來的功能。但這樣就失去這種方式的意義了。這個輸入法的優點就是不用修改主程式碼。
  4. 這版的 khk 用到了 AppContextBridge 這個(隱藏?)功能。不然我不知道怎麼送 keyEvent 到 kinlet 中。
  5. im 參考了 launchpad kiterm 。不過修改了很多地方,可能只剩下(沒用到的) daemonize,還有 screen 和 pixop。
  6. khk 是用 eclipse 然後包進所有的 kindle jar 用 cdc 1.0 模式編譯。
  7. im 是用 scratchbox 編譯。kindle dx 的 libstdc++ 分常舊,雖然網路上面常常看到推薦的 toolchain 是 scratchbox-toolchain-cs2007q3-glibc2.5-*,但裡面的 libstdc++.so 是 6.0.9,而 kindle 是 6.0.8,不要看這 8 和 9 差不多,這可能會造成一些 c++ 的程式發生 version `GLIBCXX_3.4.9' not found 錯誤。所以我用 scratchbox-toolchain-arm-linux-2006q3。如果不用 c++ 的話,似乎是沒什麼問題。用 c++ 也不見得總是會有問題。
  8. 原本想試試看加入 google 語音輸入,但錄了辦天才發現 dx 沒有辦法錄音。kindle 3 才行。不過錄音的時候,也不會產生錯誤訊息,只是沒有聲音而已。 原則上,khk 配合 curl, 和 flac 即可達到語音輸入的功能。kindle 內的 busybox wget 似乎無法送出客製化 header,不然連 curl 也不需要。
  9. freetype的用法 是參考 freetype 的教程和這篇
  10. DBus 的使用方式是參考這篇。 雖然 glib 裡面有 dbus 支援,但是 kindle dx 的 glib 太舊,所以只好用 C API了。
CanBeFound 的 kindle 3 的中文輸入法 的比較:
  1. CanBeFound 的方式是修改 SymbolPopup 的方式來處理。這是一個好的方法。事實上,我的第一個想法也是如此,畢竟 symbol popup 是 kindle 裡面長得最像輸入法的東西,其實這也是我之前弄磚 kindle 的原因。 慘的是磚了之後才發現已經有人完成這個想法。
  2. 我的方式的最大優點是,source 可以公開。因為完全不用修改 kindle 的程式碼。 
  3. 第二個優點是使用 D-Bus 做訊息溝通。所以其他程式只要寫個 D-Bus 處理器就能使用。而且對於 kindle framework 的依賴可能比較小一點。
  4. kindle 裡面的程式,可以選擇輸入時不使用 symbol popup。這時,symbol popup based 方式就無效。比方 kindle 的 home 介面,你可以直接叫出酷音輸入文字,然後搜尋框就會跑出來。Sym 鍵則是要在搜尋框出來後,才能叫出 SymbolPopup。
  5. 但除此之外,都是 CanBeFound 使用 SymbolPopup 的方式比較直接比較好。
  6. 大部分輸入文字的地方,如果程式師不特地亂搞,照規矩來,其實都可以叫出 SymbolPopup。所以第 4 點沒有太大意義。
  7. SymbolPopup 可以很容易編譯。msp 比較麻煩一點。其實也可以把 DBus 處理的部份讓 SymbolPopup  來啟動。但主要的考量是能否公開程式碼的問題。
  8. 使用 SymbolPopup 的優點是簡潔。kindle 裡面的 eventqueue 不只一條,至少 msp.g 能抓到的那條,無法處理 kindlet 的訊息。所以我必須要用到 AppContextBridge 來跨越 context 送訊息。看起來似乎不太腳踏實地,也增加了對於 kindle framework 的依賴。而 SymbolPopup 的好處是,程式需要符號輸入時,會自己去把你叫出來,這就不用擔心什麼 context, thread group 什麼的問題了。
  9. SymbolPopup 因為在 Kindle 的框架內,所以不用擔心旋轉顯示的問題,也能在適當的位置顯示。我的外掛的方式,因為有個內奸在裡面,所以某種程度上也能整合的不錯,但比較累。
  10. CanBeFound 的輸入法可以在 browser 內輸入,但是我的 dx 沒辦法。我想應該是 browser 的問題。因為我也有讓 symbol popup 輸入中文字的測試程式,但是在 dx 的 browser 裡面,只有符號能輸入,中文不行。不過問題是我的外掛輸入法在 dx 的 browser 裡,連英文也無法輸入,這點我就不太清楚為什麼了。

2011年8月10日 星期三

Kindle DX 的酷音中文輸入法


這是一個基於酷音輸入法的 kindle DXG 2.5.8 的中文輸入法。檔案 Source and Binary 在此
目前預設是使用許氏鍵盤,詳細的原理與使用方式之後再詳述。
(和 這個 kindle 3 的中文輸入法原理不同,各有優缺點)

使用方式:

  1. ssh 進 kindle
  2.  mntroot rw 然後將 khk.jar 放到 /opt/amazon/ebook/booklet 下。
  3. 將 mnt/us/chewing 下的 .so 和輸入法資料檔放到  /mnt/us/chewing
  4. 將 im 執行檔放在任何地方都可。
  5. /etc/init.d/framework restart
  6. 執行 LD_LIBRARY_PATH=/mnt/us/chewing ./im
  7. alt-shift-space 可叫出輸入法,sym 切換許氏/漢語拼音 。Aa 切換中英文。
 Bug:
  1. 瀏覽器裡面無法使用,應該是 kindle dx 的瀏覽器 netfront3 的問題。不過搜尋列可以使用。
  2. 我還沒有處理螢幕旋轉,所以螢幕選轉後,要 alt-shift-space 兩次叫出輸入視窗。
  3. 閱讀器裡面直接輸入中文不會跳出搜尋窗,不過先用英文按出搜尋窗之後,就能輸入中文。

(下接: Kindle DX 的酷音中文輸入法 (2))