汗顏 (about telnet)
Hmmm… 今天看到九月的OS X Workshop (proposal) — OLD MATERIAL TO BE STORED AND CLEANED UP,其中有一段:
“MacBlue Telnet OS X (blueapple 還沒問)”
看了真是叫人汗顏。自從五月我把會遇到的問題都解決了以後,就再也沒動力繼續搞這個玩意兒了。 ^^;
寫程式和數學證明不一樣,數學證明你只要把該有的條件給解決掉,原命題本身在邏輯上就自動成立;而寫程式就算把會遇到困難的地方全都解決掉,你想要的軟體也不會自動蹦出來---你仍然必須做苦工把程式一行一行寫出來,連接所有的解決方案,協調他們之間的運作。念資工輔數學三年後只有一個感想:寫程式好煩啊!
在這上面第一個遇到的問題,我認為是字體。OS X 很多軟體上 BBS 看到的 ASCII art 實在醜到不行!原本應該相連的色塊變成一個一個小方格,怎麼看怎麼不順眼;不然就是英文字體在等幅環境下醜陋無比。於是我逆向了 MacBlue Telnet 所用的字體格式,幸好這格式沒壓縮過,非常簡單清楚,還有現成的 HashMap 可用,實在很不賴。這裡有它轉成的 GIF 檔。(這事大概是 2003 年尾或 2004 年初就完成的 orz)
第二個我想就是 ANSI-Control Sequence parsing 的正確性吧。系統內建 Terminal 在這方面不盡理想,於是我讀了一些 document 寫了個 textModel 。這個還沒實際跑過,不知道哪裡還要再加強。
第三就是速度了,Terminal 不開 Anti-aliasing 那會醜得很難看,可是開了速度又很龜。我想捨棄 OS X 的繪字功能自己開 buffer 畫點陣圖也許是條路。於是用了 NSBitmapImageRep 和 NSImageView 實測了繪圖速度,80 x 24 標準的 Terminal 環境下,在我的 ibook dual USB G3 500Mhz (with ATI rage 128, 8M VRAM) 上可達到約 6.x fps,好像有點差強人意。不過這是每次都 display 整個 view 的結果,要是能夠針對變更的範圍 display ,相信速度可以再提升。另外自己畫圖有個好處:一字雙色。之前用 REALbasic QP 出來一個雛形就利用了 MacBlue Telnet 中文字體展示了一字雙色之可能。
好,都沒說到重點,其實最重要的是中文,分成顯示和輸入兩部份。顯示由於是自己搞 bitmap rendering ,所以完全沒有問題,MacBlue Telnet 內附的 Hashmap 相當正確。在輸入上就比較麻煩了!目前在 Mac 上有兩套以 wxWidgets 為基礎正在開發中的跨平台 BBS 軟體: BBMan 與 PCManX 。我看過 BBMan 的 source,處理 input 的地方只是很簡單地 on_key 之類的去抓,沒有辦法中文輸入。PCManX 已經懶得看 source 了,不過我猜也是一樣的方法,所以在中文輸入上都會有問題!用 wxWidgets 大概只有兩種解決辦法:
一、等 wxWidgets 的 on_key 用點奇技淫巧支援 platform input ;
二、另外用個 Text Field 處理中文輸入。
現在的 BBMan 與 PCManX (on OSX)都是用第二種方法來達成中文支援,以傳訊息為例,要送中文字,輸入法本身要按一次 enter 送字給 text field,text field 要再按一次送字給 BBS,在 BBS 中還要再按一次 Enter 把訊息送出去,稍嫌累贅。中文輸入問題在 Carbon 下比較沒那麼嚴重,不過我不會寫 Carbon 程式;在 Cocoa 下我原本打算 implement NSTextInput protocol 用整個 bitmap view 來接 keyDown: (要成為 First Responder)並送 interpretKeyEvents: 給 platform input manager ,這好像是比較正式的做法,不過後來我偷懶在底下多搞一個 NSTextView 的 subclass 並且去攔截 input manager 呼叫的 insertText: ,就不用多按 Enter 了(雖然界面有點怪)。
抓到輸入法的文字以後,還得轉碼成 big5 給 BBS 吃。這個部份以前寫 Encoding Service 時就已經碰過,NSString 的 initWithData:length:encoding: 即可達成,很簡單。
另外還有一個技術點,就是網路程式的寫法。除了 bsd socket 外,Cocoa 也提供了Asynchronous I/O 機制,以 NSFileHandle 作 wrapper,利用 notification 來作 callback 的動作。這邊在寫 QPOP-Killer 的時候也有練習過,應該也不會太難。
說了那麼多,我想表達的只有一件事!那就是… 我真的(曾經)有在做事!請大家原諒我吧!XD

“今天開學是吧?可是沒人逼你寫暑假作業啊(因為你暑假也沒在寫)。”
---digdog. 9/1, 2004