2011/05/17

難忘的AIX日

From Evernote:

難忘的AIX日

距離上次比較認真在用AIX的日子可能快五年了。今天有一個機會又要用到AIX,不過其實我不是AIX專家,很多東西都是現學現賣,畢竟如果不是工作上需要,誰會去搞一台R6裝AIX來玩。不過還好,整體看起來,今天還算順利,雖然遇到很多問題,但總算都有解決:
  1. 磁碟空間不足,需要擴增LV的空間
  2. 使用者預設檔案大小限制1G
  3. ISO檔使用問題
  4. DB2安裝問題:沒有X Window,只能用db2_install安裝
  5. WAS安裝問題:沒有X Window,只能用Silent Mode安裝
  6. SWAP太小!非常嚴重。
  7. COMM. SERVER安裝問題:必須用smit安裝
整體工作分配大致是這樣:
taskpie20110516
其中傳檔花了蠻多時間,因為廠商區的網路頻寬被限制住,除此之外花最多時間是在搞檔案大小問題,LVM,SWAP,SMIT這些東西。

今天最驚險部份發生在設定WAS的時候,因為客戶提供的機器實在有夠兩光,RAM只有1G,而且SWAP只有開512M,而且誰會沒事去注意這個?所以,當我db2跑起來而且dmgr跟nodeagent都搞定後,準備要啟動server01的時候,怎麽弄都無法啟動,回到console下指令的時候才發現大事不妙,不管執行什麼程式,只要不是目前正在跑得程式全都無法啟動,顯示的訊息都是:no swap space!靠夭咧,這下完全動不了,所有指令全部無效,最慘的是連kill,reboot跟shutdown這些都沒用,而且想到機器根本不在台北,看來這種狀況非得在機器上接console線才能處理,而且還要去跟客戶解釋這個狀況﹍簡直快昏倒了。還好,天無絕人之路,靈機一動想說dmgr好像還可以用,雖然dmgr似乎沒辦法把自己停下來,可是nodeagent可以!於是進去admin console把nodeagent停下來之後,終於﹍console恢復正常了。事不宜遲,現在第一件事當然是趕快研究一下SWAP如何加大,給你4G總夠了吧,害我差點搞掛一台R6!

今天的經驗發現,AIX有些很龜毛的限制,比如每個使用者都有建立檔案大小的限制,預設值是1G,很衰的是DB2的壓縮檔剛好超過1G一點點。所以傳檔的時候怎麽傳都會失敗,想說是見鬼了喔,一開始不太相信怎麽會有這麼龜毛的限制,結果查了一下,媽的﹍還真的是這麼龜毛。光這問題也害我卡了快辦個小時﹍

順道一題AIX的LVM還蠻強的,原本Linux的LVM我已經覺得很好用了說,結果看到AIX的LVM﹍嗯﹍這就是Benz跟Toyota的差別!

2011/05/16

很模糊,但很有感覺。

夭壽好吃牛肉麵在麻辣火鍋店?

全Linux生活:第16天 - 在Linux下編譯Windows DLLs

From Evernote:

全Linux生活:第16天 - 在Linux下編譯Windows DLLs

最近工作上要做一個Windows下的JNI DLL,這原本在純Windows下是很簡單的事,但在Linux下,是有那麼一點麻煩。在Linux下要做cross platform compile,有幾個選擇:MingGW,Cygwin。但如果考量到team work的話,要強迫其他人也要使用Linux來寫程式也說不過去,所以目前暫時不考慮"純種"的cross platform compilation,我的作法是使用Windows下的C/C++ Compiler來進行編譯,考量到Comiler大小與不要有runtime相依性問題,那選擇有3個Visual C++ 6.0,MinGW Windows版,Borland C++ 5.5(什麼﹍這鬼東西還有人用嗎?)。當然,可以免費使用的只有MinGW與Borland C++ 5.5,而且Size最小的是Borland C++ 5.5,只需要50MB左右,最大的是Visual C++ 6.0,約180MB,第二名是MinGW,約120MB。

可是這些東西在Linux下可以用嗎?當然是不能直接用,但是透過WINE就可以。這樣做最大的好處是同一個專案可以在Linux與Windows下通用(甚至Mac OS X,但一樣要裝WINE才行)。

不囉唆,先準備JNI環境:
  1. 首先在Eclipse建立一個HelloWorldJNI專案
  2. 建立目錄結構如下圖:
    helloworldjni_structure
    其中jdk_include目錄內的檔案請從32位元Windows版的JDK中複製取得。

如果想用Visual C++ 6.0,請服用:
  1. 取得VIsual C++ 6.0:噓﹍不要問很恐怖﹍
  2. 安裝Visual C++ 6.0:

    $ wine <PATH-TO-MSVC60-CD>/setup.exe

  3. 在Eclipse建立MSVC60專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf "~/.wine/drive_c/Program Files/Microsoft Visual Studio/Common" <PATH-TO-MSVC60-PROJECT>
    $ cp -rvf "~/.wine/drive_c/Program Files/Microsoft Visual Studio/VC98" <PATH-TO-MSVC60-PROJECT>

    msvc60_structure

  5. 複製並修改vcvars32.bat:

    $ cp <PATH-TO-MSVC60-PROJECT>/VC98/Bin/VCVARS32.BAT <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/vcvars32.bat
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/vcvars32.bat

    @echo off
    set MSVC60_HOME=%CD%\..\..\..\msvc60

    rem
    rem Root of Visual Developer Studio Common files.
    set VSCommonDir=%MSVC60_HOME%\Common

    rem
    rem Root of Visual Developer Studio installed files.
    rem
    set MSDevDir=%MSVC60_HOME%\Common\msdev98

    rem
    rem Root of Visual C++ installed files.
    rem
    set MSVCDir=%MSVC60_HOME%\VC98

    rem
    rem VcOsDir is used to help create either a Windows 95 or Windows NT specific path.
    rem
    set VcOsDir=WIN95
    if "%OS%" == "Windows_NT" set VcOsDir=WINNT

    rem
    echo Setting environment for using Microsoft Visual C++ tools.
    rem

    if "%OS%" == "Windows_NT" set PATH=%MSDevDir%\BIN;%MSVCDir%\BIN;%VSCommonDir%\TOOLS\%VcOsDir%;%VSCommonDir%\TOOLS;%PATH%
    if "%OS%" == "" set PATH="%MSDevDir%\BIN";"%MSVCDir%\BIN";"%VSCommonDir%\TOOLS\%VcOsDir%";"%VSCommonDir%\TOOLS";"%windir%\SYSTEM";"%PATH%"
    set INCLUDE=%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
    set LIB=%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%

    set VcOsDir=
    set VSCommonDir=

  6. 建立cl.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/cl.bat

    echo off
    @call bin\vcvars32.bat
    cl %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\cl -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -MD -LD ${moduleName}\\${moduleName}.c -Fe${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\cl -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -MD -LD ${moduleName}\\${moduleName}.c -Fe${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>

  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse

如果想用MingGW,請服用:
  1. 取得MingGW:MinGW官網

    $ wget http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/mingw-get-inst-20110316/mingw-get-inst-20110316.exe/download


  2. 安裝MingGW:

    $ wine <PATH-TO-DOWNLOAD-DIR>/mingw-get-inst-20110316.exe

  3. 在Eclipse建立MINGW專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf ~/.wine/drive_c/MingGW/* <PATH-TO-MINGW-PROJECT>

    mingw_structure

  5. 建立mingwenv.bat:
     
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/mingwenv.bat

    @echo off
    set MINGW_HOME=..\..\..\mingw
    set PATH=%MINGW_HOME%\bin;%MINGW_HOME%\mingw32\bin;%PATH%
     
  6. 建立gcc.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/gcc.bat

    echo off
    @call bin\mingwenv.bat
    gcc %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -shared ${moduleName}\\${moduleName}.c -o ${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -shared ${moduleName}\\${moduleName}.c -o ${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>

  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse -1


如果想用Borland C++ 5.5,請服用:
  1. 取得Borland C++ 5.5:Codegear官網
  2. 安裝Borland C++ 5.5:

    $ wine <PATH-TO-DOWNLOAD-DIR>/freecommandLinetools.exe

  3. 在Eclipse建立BCC55專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf ~/.wine/drive_c/Borland/BCC55/* <PATH-TO-BCC55-PROJECT>

    bcc55_structure

  5. 建立bcc55env.bat:
     
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/bcc55env.bat

    @echo off
    set BCC55_HOME=..\..\..\bcc55
    set PATH=%BCC55_HOME%\bin;%PATH%
     
  6. 建立bcc32.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/bcc32.bat

    echo off
    @call bin\bcc55env.bat
    bcc32 %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\bcc32 -Ijdk_include -Ijdk_include\\win32 -I..\\..\\..\\bcc55\\Include -L..\\..\\..\\bcc55\\Lib -I${moduleName} -WD ${moduleName}\\${moduleName}.c -o${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\bcc32 -Ijdk_include -Ijdk_include\\win32 -I..\\..\\..\\bcc55\\Include -L..\\..\\..\\bcc55\\Lib -I${moduleName} -WD ${moduleName}\\${moduleName}.c -o${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>
     
  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse -2


2011/05/15

全Linux生活:第15天 - 製作光碟ISO

From Evernote:

全Linux生活:第15天 - 製作光碟ISO

在Linux下製作ISO真是出奇的簡單,用dd或mkisofs就搞定了。
從硬碟資料產生ISO,請服用:

     $ mkisofs -o /tmp/cd.iso /source_directory

從光碟機產生ISO,請服用:

     $ dd if=<device> of=/tmp/image.iso

其中<device>就是光碟機的裝置,我目前的Ubuntu是/dev/sr0,但有些可能是叫/dev/cdrom或/dev/hdc或/dev/sdb之類的,如果真的不確定,可以用指令查一下:

     $ dmesg|grep CD-ROM
     [    3.693625] scsi 1:0:0:0: CD-ROM            HL-DT-ST DVD+-RW GA31N    A102 PQ: 0 ANSI: 5
     [    3.706587] cdrom: Uniform CD-ROM driver Revision: 3.20
     [    3.706778] sr 1:0:0:0: Attached scsi CD-ROM sr0

如果什麼都沒有,哪你可能要懷疑一下你的電腦是不是有光碟機?不過還是可以來找看看,查一下系統目前有哪些磁碟裝置:

     $ ls -l /sys/block/*/device
     lrwxrwxrwx 1 root root 0 2011-05-15 11:02 /sys/block/sda/device -> ../../../0:0:0:0
     lrwxrwxrwx 1 root root 0 2011-05-15 11:32 /sys/block/sdb/device -> ../../../5:0:0:0
     lrwxrwxrwx 1 root root 0 2011-05-15 11:02 /sys/block/sr0/device -> ../../../1:0:0:0

然後看一下裝置type是不是5,因為5表示ROM,如果看到是0,表示是DISK:

     $ cat /sys/block/sda/device/type
     0
     $ cat /sys/block/sdb/device/type
     0
     $ cat /sys/block/sr0/device/type
     5

如果吃飽太閒沒事幹,想知道有哪些type是什麼意思,可以查一下:

     $ cat /usr/include/scsi/scsi.h|grep TYPE_
     #define TYPE_DISK           0x00
     #define TYPE_TAPE           0x01
     #define TYPE_PROCESSOR      0x03    /* HP scanners use this */
     #define TYPE_WORM           0x04    /* Treated as ROM by our system */
     #define TYPE_ROM            0x05
     #define TYPE_SCANNER        0x06
     #define TYPE_MOD            0x07    /* Magneto-optical disk -
                                          * - treated as TYPE_DISK */
     #define TYPE_MEDIUM_CHANGER 0x08
     #define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
     #define TYPE_NO_LUN         0x7f



2011/05/14

這條路到底要搞多久啊?

這個時候,最適合在這個位置想事情。

瑪莉亞二號報到!

瑪莉亞二號報到! by nanotiny
瑪莉亞二號報到!, a photo by nanotiny on Flickr.

全Linux生活:第11天 - PDF印表機

From Evernote:

全Linux生活:第11天 - PDF印表機

又是工作上的需要,我要將列印資料輸出到PDF檔案,以前在Windows下,有很多選擇可以選,如CutePDF,PDFCreater﹍可是在Linux下,這些都不能用,那用WINE執行呢?很抱歉,還是不能用,親自測試的結果是,CutePDF連安裝程式都跑不完就掛了,PDFCreater看起來還不錯,至少安裝程式跑完了,虛擬印表機也有出現,但實際列印時,好像石沉大海一樣,沒有任何反應。嚴格說起來,WINE在Printing的支援度,只能說還是不行,光看WINEHQ-Printing這份清單還有那麼多叉叉就已經三條線了﹍

     Screenshot-Printing - The Official Wine Wiki - Google Chrome

想在WINE下使用PDF Printer目前看起來只有Adobe Arcobat比較有機會(實在懶得試了,況且我手上也有沒有任何版本的Acrobat,但至少有人說可以用)。

不過話說回來,幹麼一定要使用Windows環境的PDF Printer?是頭殼壞掉嗎?其實Linux下的PDF Printer也是很多,最簡單的就是CUPS-PDF。
安裝CUPS-PDF:

     $ sudo apt-get install cups-pdf

這樣就ok了,接著在『控制中心』的『列印』裡面就可以看到已預設裝好一個『PDF』的虛擬印表機:

     Screenshot-列印 - localhost

在Linux下,只要列印的時候選這台就對了。接下來,我們會很好奇那如果是WINE下的Microsoft Word,Excel,Visio這些軟體可以使用Linux下的Printer嗎?答案是,可以的。實際使用結果是:不管Linux或WINE下的應用程式,都可以使用這個PDF Printer,同理如果是一般印表機應該也是ok的。

要注意的是,CUPS-PDF產生PDF檔時,不會像Windows下的PDF Printer一樣跳一個視窗出來問你要存到哪裡,而是直接產生一個PDF檔到${HOME}/PDF下面,如果想修改存檔路徑或是檔名或其他參數,可以看一下/etc/cups/cups-pdf.conf設定檔。


2011/05/08

"爆醬"花

From Evernote:

"爆醬"花

滿出來了。
2011-04-20+13.17.46

全Linux生活:第7天(2) - EUDC.TTE

From Evernote:

全Linux生活:第7天(2) - EUDC.TTE

這其實不是我日常生活會遇到的問題,而是工作上的需要,只是剛好也是跟非Windows環境(AIX&Linux)有關的議題。最近我們正在進行的一個提案,需要在AIX與Linux環境下進行"難字"列印,其實說穿了就是所謂的"使用者造字"。目前常見的是使用滿天星公司的字霸系統,我沒去研究字霸有沒有AIX或Linux版,可是這個客戶的字霸是Windows版,我們以前的系統雖然Server端是AIX系統,但至少客戶端都還是Windows,因此難字的顯示與列印全交給Windows與字霸就好了。但這次這個提案的作法從頭到尾都沒有Windows,這時候如果列印資料中有難字該如何列印呢?

我們稍微研究了一下字霸的作法發現一件事,那就是其實字霸採用的是標準Windows使用者造字的模式,也就是它會在Windows掛一個EUDC.TTE的字型檔在系統中:

     [HKEY_CURRENT_USER\EUDC\950]
     "SystemDefaultEUDCFont"="C:\\WINDOWS\\EUDC.tte"

只是這副檔名有點怪,*.TTE是什麼鬼?這個檔其實是個標準的truetype字型檔,如果把副檔名TTE改成TTF,可以發現Windows是認得這個檔的,檔案點兩下甚至可以開得起來。

所以接下來要做的事就比較簡單了。我們只要把這個檔讀出來,把我們要的字畫出來問題就解決了。講到這裡,我只能說Java真是佛心來的!針對Truetype的處理Java早就內建了,我們只要用就好了,以下是大致的用法:

    private Font eudc;
    private Font eudc24;
    public boolean reloadEudcFont() {
      try {
        File eudcFile = new File(eudcFontPath);
          if (eudcFile.exists()) {
            eudc = Font.createFont(Font.TRUETYPE_FONT, eudcFile);
            eudc24 = eudc.deriveFont(Font.PLAIN, 24);
            return true;
        }
        eudc = null;
        eudc24 = null;
      } catch (Throwable t) {
        t.printStackTrace();
      }
      return false;
    }

接下來,要抓某個難字的bitmap大致可以這樣做:

    public int[] grepUdcImage(int width, int height, char c) {
      try {
        int w = width;
        int h = height;
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics g = image.getGraphics();
        if (regularFont.canDisplay(c))
          g.setFont(regularFont);
        else
          g.setFont(eudc24);
        g.setColor(Color.WHITE);
        g.drawString("" + c, 0, h - 5);
        int[] pixels = new int[w * h];
        PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
        try {
          pg.grabPixels();
        } catch (InterruptedException e) {
          logger.error("Interrupted waiting for pixels!");
        }
        if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
          logger.error("Image fetch aborted or errored!");
        }
        return pixels;
      } catch (Throwable t) {
        t.printStackTrace();
      }
      return null;
    }

要注意一點,這個TTE檔內部的編碼是Unicode,所以要找出我們要的難字,你必須知道那個字的Unicode。因為我們沒有MS950(BIG5)跟Unicode的對照表(這部份其實是字霸另一個主要功能),所以只要先有人幫我們把該轉的碼先轉好,到我們這邊的處理就沒有問題了,關於這點,倒是不用擔心,因為我們要列印的字,在使用者鍵入難字的時候早就把難字轉成Unicode了,畢竟目前使用者日常操作的電腦百分之兩百一定是Windows,如果萬一真的不是Windows,比方說是手機或iPad(或Android),反正它也打不出難字,所以也不用擔心。

全Linux生活:第7天 - Bluetooth & bluez

From Evernote:

全Linux生活:第7天 - Bluetooth & bluez

藍牙滑鼠終於可以用了!其實第2天的時候就已經把藍牙滑鼠與電腦配對,只是當時配對時沒有弄好,導致清單雖然可以看到滑鼠,但是不能使用,最慘的是想移除也移除不了,不知哪裡出了錯?後來因為太忙就先放著不管了。今天想說應該要來處理一下這個問題了。於是用dpkg看了一下ubuntu的到底是使用什麼藍牙套件:
     $ dpkg --get-selections|grep blue
     bluez                        install
     bluez-alsa                   install
     bluez-cups                   install
     bluez-gstreamer              install
     gnome-bluetooth              install
     libbluetooth3                install
     libgnome-bluetooth8          install
     pulseaudio-module-bluetooth  install
看起來應該是bluez,接下來看看有什麼線索可以下手:
     $ dpkg -L bluez|grep /bin/
     /usr/bin/bluetooth-agent
     /usr/bin/bluez-simple-agent
     /usr/bin/bluez-simple-service
     /usr/bin/bluez-test-adapter
     /usr/bin/bluez-test-audio
     /usr/bin/bluez-test-device
     /usr/bin/bluez-test-discovery
     /usr/bin/bluez-test-input
     /usr/bin/bluez-test-manager
     /usr/bin/bluez-test-network
     /usr/bin/bluez-test-serial
     /usr/bin/bluez-test-service
     /usr/bin/bluez-test-telephony
     /usr/bin/ciptool
     /usr/bin/dfutool
     /usr/bin/hcitool
     /usr/bin/l2ping
     /usr/bin/l2test
     /usr/bin/rctest
     /usr/bin/rfcomm
     /usr/bin/sdptool
在經過一陣亂猜跟亂試的過程後,發現hcitool這個東西比較有搞頭,看一下它有哪些參數可以用:
     $ hcitool --help
     hcitool - HCI Tool ver 4.91
     Usage:
         hcitool [options] <command> [command parameters]
     Options:
         --help    Display help
         -i dev    HCI device
     Commands:
         dev     Display local devices
         inq     Inquire remote devices
         scan    Scan for remote devices
         name    Get name from remote device
         info    Get information from remote device
         spinq    Start periodic inquiry
         epinq    Exit periodic inquiry
         cmd     Submit arbitrary HCI commands
         con     Display active connections
         cc      Create connection to remote device
         dc      Disconnect from remote device
         sr      Switch master/slave role
         cpt     Change connection packet type
         rssi    Display connection RSSI
         lq      Display link quality
         tpl     Display transmit power level
         afh     Display AFH channel map
         lp      Set/display link policy settings
         lst     Set/display link supervision timeout
         auth    Request authentication
         enc     Set connection encryption
         key     Change connection link key
         clkoff    Read clock offset
         clock    Read local or remote clock
         lescan    Start LE scan
         lewladd    Add device to LE White List
         lewlrm    Remove device from LE White List
         lewlsz    Read size of LE White List
         lewlclr    Clear LE White list
         lecc    Create a LE Connection
         ledc    Disconnect a LE Connection
         lecup    LE Connection Update
    
     For more information on the usage of each command use:
         hcitool <command> --help
又經過一陣亂試之後,發現以下結論:
     掃描藍牙裝置可以用:
     $ hcitool scan
     Scanning ...
         00:07:61:FC:C2:B9    Logitech Bluetooth Mouse M555b
     取得藍牙裝置名稱:
     $ hcitool name 00:07:61:FC:C2:B9
     Logitech Bluetooth Mouse M555b
     取得藍牙裝置資訊:
     $ sudo hcitool info 00:07:61:FC:C2:B9
     [sudo] password for rudy:
     Requesting information ...
         BD Address:  00:07:61:FC:C2:B9
         Device Name: Logitech Bluetooth Mouse M555b
         LMP Version: 2.0 (0x3) LMP Subversion: 0x229
         Manufacturer: Broadcom Corporation (15)
         Features: 0xbc 0x02 0x04 0x38 0x08 0x00 0x00 0x00
             <encryption> <slot offset> <timing accuracy> <role switch>
             <sniff mode> <RSSI> <power control> <enhanced iscan>
             <interlaced iscan> <interlaced pscan> <AFH cap. slave>

     裝置配對:
     $ bluez-simple-agent hci0 00:07:61:FC:C2:B9
     設定信任關係:
     $ bluez-test-device trusted 00:07:61:FC:C2:B9 yes
     連線藍牙滑鼠:
     $ bluez-test-input connect 00:07:61:FC:C2:B9

這樣就ok了!以上步驟跟直接使用gnome-bluetooth的GUI介面設定結果相同,且設定結果也會反應在GUI介面上,看起來gnome-bluetooth內部也是使用bluez套件作為底層的指令。



2011/05/03

小確幸

原來這就是"小確幸"!


Roof

我們都太忙了,忙到忘了到屋頂看風景。


全Linux生活: 第3天 - Alt+PrintScreen

From Evernote:

全Linux生活: 第3天

第3天,好啦其實是第2天拖過12點了。補充一點,免得以後忘了,因為剛剛要抓執行畫面的圖,遇到了一個小問題,Windows下的Alt+PrintScreen可以用嗎?答案是......當然不行囉,又不是第一天用Linux,頭殼壞掉才會覺得Alt+PrintScreen會很順利的可以用。

後來發現,其實也不是不能用啦,只是要調整一下就好,再說單按PrintScreen是可以用的。Linux其實有支援PrintScreen與Alt+PrintScreen,只是Alt+PrintScreen跟另一個Linux Kernel的Magic SysReq Key衝突,請看 Wikipedia: Magic SysReq Key。只要將Kernel參數:kernel.sysreq設為0就ok了:

     $ sudo sysctl -w kernel.sysreq=0

不過這樣下次開機後又回恢復成1,所以想永久改變可以加一行到/etc/sysctl.conf裡面:

     kernel.sysreq=0

所以以後按了Alt-PrintScreen之後就會出現:

Alt+PrintScreen畫面

PS:後來發現好像是只有Ubuntu 10.10以後才有這問題,請看: ALT+PrtSc not recognised: breaks built-in screenshot function

全Linux生活: 第2天 - Evernote & nevernote

From Evernote:

全Linux生活: 第2天 - Evernote & nevernote

Evernote是我常用的記事軟體, 會用它其實沒什麼原因, 因為它有Android版, 雖然不是什麽殺手級的軟體, 手機跟電腦隨時都可以看到相同的東西, 對我來說還蠻方便的。

進入第二天想說來看一下Linux下是否可使用. 果然, 毫無意外的, 它真的沒有Linux版!真搞不懂, 它用了一堆Linux下常見的Libraries, 不過都是Windows版, 結果自己卻沒有Linux原生的版本。

Evernote Web版, 其實做得還不錯, 跟Windows版"幾乎"相同, 甚至有點更好的感覺. 不過Web版有一個所有Web版的軟體共通的缺點:沒網路就變成廢物了。像我常去的客戶那兒, 是在地下室, 收訊經常差到一個不行, 這時候Web版就沒鳥用了。

於是開始動Evernote+WINE的腦筋。剛開始以為很順利,結果程式跑起來說少了riched20.dbg,應該是我的riched20安裝時沒有包含除錯資訊的riched20.dbg檔. 唉,年紀大了,有點懶得在解下去,改天有力氣再說吧。但在找解法的同時,(這軟體的名字實在夠GY)有看到另一個比較簡單的解法,抓nevernote來用(os: 這軟體的名字實在夠GY)!

Nevernote是Java寫的,這也害我在裝得過程小卡了一下,因為之前很少用Debian系列的Linux,Ubuntu的apt-get還不錯,但nevernote只有獨立的deb package,apt repository裡找不到,只好撩下去看了一下dpkg怎麽用,還好跟rpm差不多,所以就很爽快地給它dpkg -i nevernote-xxxxxx.deb下去......沒錯,如果這樣就成功就真見鬼了。羚羊咧,又是相依性問題,這問題跟rpm -ivh一樣,果然兄弟兩都是同一個爸媽生的。其實我是可直接用--ignore-depends或--force-xxx硬幹下去,因為它只是需要有JRE環境,我也裝了最新的Orcale JDK,path跟JAVA_HOME也都ok,可是良心告訴我不能在第二天就幹種事,所以我執行apt-get -f install來修復相依性問題並安裝了default-jre與openjdk-6,最後再dpkg -i nevernote-xxx.deb下去就ok了。

看圖:
執行畫面:nevernote

雖然畫面沒有Windows版或Web版漂亮,但用起來還算ok,至於WINE+Evernote就有時間再說了,nevernote真是佛心來的(忍不住還是os: 這名字真是夠GY的)!