歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> 關於Unix >> 構造Linux的圖形化安裝程序(2)(1)

構造Linux的圖形化安裝程序(2)(1)

日期:2017/3/6 15:37:20   编辑:關於Unix
主要介紹在安裝程序裝入內存之後,如何啟動圖形環境並設置中文語言環境。文中除了介紹安裝程序對這兩個功能的具體編程實現,還介紹了 Linux 中文化的一些基本知識,包括如何定制安裝程序顯示中所需要的Locale環境(Glibc和X Window系統兩部分),po文件的處

主要介紹在安裝程序裝入內存之後,如何啟動圖形環境並設置中文語言環境。文中除了介紹安裝程序對這兩個功能的具體編程實現,還介紹了Linux中文化的一些基本知識,包括如何定制安裝程序顯示中所需要的Locale環境(Glibc和X Window系統兩部分),po文件的處理。在安裝程序的第二階段運行結束之後,整個安裝程序已經被調入了內存,這時控制從安裝程序的加載程序轉到了安裝程序的主程序執行。這時的安裝程序就像是一個從Linux的控制台環境啟動的程序,這個程序進行自動檢測並進行基本的設備配置。為了進行圖形化安裝,安裝程序的主程序會啟動XFree86子系統並設置,同時設置當前的語言環境為中文環境。

1. 多語言環境支持

為了在Linux下實現多語言支持,必須在定制安裝程序時,引入與glibc和圖形環境兩者對應的多語言環境支持。對於glibc環境而言,它是整個 Linux中文化的基礎,我們需要在/usr/share/locale目錄下保存Locale信息,在/usr/share/consolefonts 目錄下保存字體信息,在/usr/lib/gconv目錄下保存字符轉換模塊的信息。

對於X Windows環境,我們需要在/usr/X11R6/lib/X11/locale目錄下保存X Locale的配置,同時在/usr/X11R6/lib/X11/fonts目錄下保存正常顯示所需要的字體集。

在安裝程序啟動之後,必須正確設置LC_*變量同時調用setlocale函數。為了能顯示中文,安裝程序還必須加載正確的中文字體。

1.1. 國際化的基本概念

國際化(Internationalization,簡寫為I18N)是指軟件在設計結構和機制上支持多語言的擴展特性,其功能和代碼設計不針對某一特定語言和地域。Locale是ANSI C語言中最基本的支持國際化的標志,對中文Linux來說,支持中文Locale是最基本的要求。

1.1.1. Locale環境

Locale的命名規則:<語言>_<地區名>.<字符編碼名稱>

對於zh_CN.GB2312而言,zh表示中文,CN表示大陸地區,GB2312表示使用的字符集為GB2312。

Locale使用一組分類,用戶可以獨立的操縱每一組分類。用戶既能用設置環境變量的方法,也能使用setlocale設置它們。這些分類都保存在/usr/share/locale下。它們包含了:

LC_COLLATE

用於比較和排序。

LC_CTYPE

用於字符分類和字符串處理,控制所有字符的處理方式,包括字符編碼,字符是單字節還是多字節,如何打印等。

LC_MONETORY

用於格式化貨幣單位。

LC_NUMERIC

用於格式化非貨幣的數字顯示。

LC_TIME

用於格式化時間和日期。

LC_MESSAGES

用於控制程序輸出時所使用的語言,主要是提示信息,錯誤信息,狀態信息, 標題,標簽, 按鈕和菜單等。

LC_ALL

它不是環境變量,只是一個宏,可使用setlocale設置所有的LC_*環境變量。這個變量設置之後,可以廢除LC_*和LANG的設置值,使得這些變量的設置值與LC_ALL的值一致。

LANG

它的值用於指定上面環境變量沒有設置的所有變量值。如果指定了上面任何一個變量的值,則會廢除對應的LANG值的缺省設置。

還可以包括其他的環境變量LC_ADDRESS,LC_IDENTIFICATION,LC_PAPER,LC_NAME,LC_TELEPHONE,LC_MEASUREMENT。

標准Locale:

"C"

這是標准的C Locale。它所指定的屬性和行為由ISO C標准所指定。它是程序啟動時缺省使用Locale。

"POSIX"

這是標准的POSIX Locale。它是標准的C Locale的別名。

""

空名字是讓程序選擇當前環境設置值。

設置一個中文環境需要正確的設置上述Locale變量,舉例來說,在使用zh_CN.GB2312環境時,使用locale命令,所見到的系統環境為:

LANG="zh_CN.GB2312"

LC_CTYPE="zh_CN.GB2312"

LC_NUMERIC="zh_CN.GB2312"

LC_TIME="zh_CN.GB2312"

LC_COLLATE="zh_CN.GB2312"

LC_MONETARY="zh_CN.GB2312"

LC_MESSAGES="zh_CN.GB2312"

LC_PAPER="zh_CN.GB2312"

LC_NAME="zh_CN.GB2312"

LC_ADDRESS="zh_CN.GB2312"

LC_TELEPHONE="zh_CN.GB2312"

LC_MEASUREMENT="zh_CN.GB2312"

LC_IDENTIFICATION="zh_CN.GB2312"

LC_ALL=

1.1.2. 創建Locale環境

為了建立locale環境,我們必須具備下面的描述文件:

locale-data

這個文件定義了Locale環境(LC_*)的所有細節,包括字符的分類與轉換,字符排序,區域顯示時間,貨幣顯示格式等等。通常是保存在系統的/usr/share/i18n/locales目錄下。

charmap

這個文件定義了Locale中所有字符與內碼的對應關系。通常是保存在系統的/usr/share/i18n/charmaps目錄下。

這兩個文件都是純文本文件,可以使用文本編輯器直接察看和修改。通過這兩個文件就可以生成對應的locale環境。缺省條件下,生成的locale環境是以二進制的形式保存在/usr/share/locale目錄下。把這兩個文本文件生成locale環境的工作是由localedef程序實現的。舉例來說,生成zh_CN.GB2312的locale環境:

mkdir /home/usr/share/locale/zh_CN.gb2312

localedef -I zh_CN -f GB2312 zh_CN.GB2312 --prefix=/home

cd /home/usr/share/locale/

mv zh_CN.gb2312 zh_CN.GB2312

這幾條命令在/home目錄下,生成Locale環境zh_CN.GB2312。因為按照POSIX標准,一個Locale的編碼名稱是大小寫無關的。雖然我們指定的是大寫的GB2312,但是glibc為了統一起見,它會生成一個小寫的編碼名稱。但是由於很多程序依賴於zh_CN.GB2312,因此對這個文件進行了改名。

除了Locale環境之外,您還需要gconv文件。這一組文件是用來定義glibc的gconv系統在遇到GB2312編碼的字符時,應使用哪一個模塊來處理。gconv-modules文件描述了字符編碼和處理模塊文件對應關系。例如,在/usr/lib/gconv/gonv-modules文件中,需要包含下列行:

alias GB2312// EUC-CN//

1.1.3. X Window系統的多語言環境

X Window系統的多語言環境是在系統底層libc的Locale架構的基礎上建立起來的。X函數庫需要利用libc提供的函數來進行字符之間的轉換。因此,為了使X Window應用程序的Locale正確工作,您必須首先設置一個正確的libc Locale環境,同時正確設置LC_CTYPE這個類別。

指定了編碼方式並且將字符的辨識和轉換用libc的函數處理之後,X Window系統的多語言處理的主要問題就變為圖形顯示和輸入了。在X系統下,多語言環境必須能做到多語言字符圖形化輸出和字符輸入。字符的圖形化輸出還要處理字型,這又與字型的設定方式有關。

與libc一樣,在X Window系統下也有關於Locale的設置部分,稱為X-Locale。XFree86系統都把它保留在 /usr/X11R6/lib/X11/locale目錄下。在這個目錄下的每個Locale都有一個目錄,存放各自的X-locale,一般這個文件的名字是XLC_LOCALE。這個文件裡面包含了跟該區域編碼相關的設定,而文件中以#字號開頭的是注釋。以安裝程序上簡體中文XLC_LOCALE的內容為例:

XLC_FONTSET

# fs0 class (7 bit ASCII)

fs0 {

charset {

name ISO8859-1:GL

}

font {

primary ISO8859-1:GL

vertical_rotate all

}

}

# fs1 class

fs1 {

charset {

name GB2312.1980-0:GL

}

font {

primary GB2312.1980-0:GL

}

}

END XLC_FONTSET

以上內容定義的是顯示Locale時使用的字符集。在多語言環境中,為了同時顯示中英文,系統往往需要多種字體。例如,上例中表示:在顯示簡體中文時要使用兩種不同編碼的字體,其中一個是使用了GB2312編碼的中文字體,其字體名稱以GB2312.1980-0結束,另一個是ISO8859-1編碼的英文字體,其字體名稱以ISO8859-1結束。

XLC_LOCALE的下一部分定義了Locale中的字體在X系統中的處理方式:

XLC_XLOCALE

encoding_name zh.euc

mb_cur_max 2

state_depend_encoding False

wc_encoding_mask x30000000

wc_shift_bits 7

cs0 {

side GL:Default

length 1

wc_encoding x00000000

ct_encoding ISO8859-1:GL

}

cs1 {

side GR:Default

length 2

wc_encoding x30000000

ct_encoding GB2312.1980-0:GL; GB2312.1980-0:GR

}

END XLC_XLOCALE

cs0定義的部分為iso8859-1編碼的英文字符,每個字符占用一個字節。cs1定義的部分為GB2312編碼的中文字符,每個字符占用兩個字節,這兩個字節都必須用GB2312.1980-0的字體來表示。注意,對於上面的X設置,GB2312.1980-1類型的字體是無法正常顯示的,除非用戶修改X Locale。

除此之外,/usr/X11R6/lib/X11/locale還使用locale.dir和locale.alias文件定義可用X-Locale的名稱和位置。其中,locale.dir定義了每個X-Locale文件的位置以及實際的Locale名稱。locale.alias文件則定義了每個 Locale可能的別名。

X Window 的字體存放在/usr/X11R6/lib/X11/fonts目錄下,一般使用PCF的字體。在將新的字體文件拷貝到此目錄之後,運行

mkfontdir

由這條命令更新改目錄下的fonts.dir的內容。例如,

fzs14.pcf.Z fzs14

helvR12_iso01.pcf.gz -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1

上面兩行的信息是從字體文件中抽取出來的,比如,helvR12_iso01.pcf.gz文件中就包含iso8859-1編碼的文件。但是,字體文件 fzs14.pcf.Z就不包含類似的字體說明信息,因此我們還需要使用fonts.alias文件建立字體別名。

-hlc-song-medium-r-normal--14-140-75-75-c-140-gb2312.1980-0 fzs14

這樣在安裝程序使用下面的資源時,X Window系統就知道要加載fzs14字體了。

style "font" {

fontset="-*-helvetica-*-r-normal-*-14-*-*-*-*-*-iso8859-1, -*-medium-*-14-*-*-*-*-*-*-gb2312.1980-0"

}

1.2. 安裝程序的國際化實現

自動生成po文件

在安裝程序中,定義了兩個函數_()和__(),前者是對傳入的串進行翻譯,後者是直接返回傳入的串,凡是要進行多語言支持的串必須使用這兩個函數。它們兩者在安裝程序中的用法是不同的。前者是用於一些可以進行重建的界面控件,並且它們的值一般作為局部變量出現;而後者一般用於全局變量,為了讓這個串顯示多種語言,需要使用translate()函數進行處理。使用這兩個函數的主要目的是可以很方便的使用xgettext程序自動生成po文件。

xgettext只對c語言的源程序文件生效,因此在使用它之前必須先將perl源程序轉換為c程序,然後再運行xgettext自動提出需要進行多語言處理的文本串。下面的程序段是po目錄下Makefile文件的一部分,它可以自動生成空的po文件。

PMSFILES = $(wildcard *.pm)

PMSCFILES = $(PMSFILES:%=%_.c)

POFILES = $(shell ls *.po)

all: $(PMSCFILES) DrakX.pot

clean:

rm -f empty.po messages $(POFILES:%=%t) $(PMSCFILES)

verif:

perl -ne '/^s*#/ or $$i += my @l = /b__?(/g; END { print "$$in" }' $(PMSFILES)

perl -ne '$$i += my @l = /.c:/g; END { print "$$in" }' DrakX.pot

DrakX.pot: $(PMSFILES)

xgettext -F -n --keyword=_ --keyword=__ -o $@ $(PMSCFILES)

rm $(PMSCFILES)

$(PMSCFILES): %_.c: %

perl -pe 's|^(__?()| $$1|; s|#([^+].*)|/*1*/|; s|$$|\n\|' $< > $@

Copyright © Linux教程網 All Rights Reserved