Chinaunix首页 | 论坛 | 博客
  • 博客访问: 101900323
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: LINUX

2008-04-22 22:39:32

出处:ChinaITLab 
 
处理po文件
在安装程序中po文件并不进行编译。因为perl语言处理文本文件的能力非常强,所以它直接作为文本文件形式存在。在调入po文件时,perl根据msgid和msgstr的内容生成一个hash结构,然后由此结构进行文本串的处理。
#- 此函数加载指定语言的po文件
sub load_po {
my ($lang) = @_;
my ($s, $from, $to, $state, $fuzzy);
#- 将$s中的内容作为一个perl文件存在,在这个文件中生成一个巨大的hash结构
#- 当进行多语言处理时,根据这个hash结构获得翻译的文本串。
$s .= "package po::I18N;\n";
$s .= "no strict;\n";
$s .= "\%{'$lang'} = (";
$f = "po/$lang.po";
local *F;
my $pid;
unless ($f && -e $f) {
… …
#- 如果文件不存在,则从压缩包中取出此文件,并打开
}
local $_;
while () {
/^msgstr/ and $state = 1;
/^msgid/ && !$fuzzy and $state = 2;
s/@/\\@/g;
if (/^(#|$)/ && $state != 3) {
$state = 3;
if (my @l = $to =~ /%(\d+)\$/g) {
$to =~ s/%(\d+)\$/%/g;
$to = qq([ "$to", ] . join(",", map { $_ - 1 } @l) . " ),";
} else {
$to = qq("$to");
}
#- 形成hash结构,msgid的内容保存在$from中,msgstr的内容保存在$to中
$s .= qq("$from" => $to,\n) if $from;
$from = $to = '';
}
$to .= (/"(.*)"/)[0] if $state == 1;
$from .= (/"(.*)"/)[0] if $state == 2;
$fuzzy = /^#, fuzzy/;
}
$s .= ");";
no strict "vars";
eval $s;
$pid and waitpid $pid, 0;
!$@;
}
文本串翻译
#- 文本串的翻译过程主要是访问读入po文件所形成的hash结构,由它的值返回翻译后的文本串。
sub translate {
my ($s) = @_;
#- 如果Locale环境未设置,则设置环境为英语
my ($lang) = $ENV{LANGUAGE} || $ENV{LC_MESSAGES} || $ENV{LC_ALL} || $ENV{LANG} || 'en';
require lang;
foreach (split ':', $lang) {
#- 如果hash结构未定义,则调入语言对应的po文件
lang::load_po($_) unless defined $po::I18N::{$_};
#- 如果未能正确加载po文件或者待翻译的串不存在,则返回源串$s。
if (%{$po::I18N::{$_}}) {
return if $s eq '_I18N_';
return ${$po::I18N::{$_}}{$s} || $s
}
}
$s;
}
l 设置Locale环境
设置Locale环境主要就是设置Locale变量的值。
#- [ 'English|United States', 'iso-8859-1', 'en', 'en_US:en' ]这个数组表示
#- 第一个元素是语言环境的文本描述。
#- 通过第二个元素的值查询%charset结构,可以获得对应的字体。
#- 第三个元素是LANG变量的设置值。
#- 第四个元素是LANGUAGE变量的设置值。
my %languages = (
'en_US' => [ 'English|United States', 'iso-8859-1', 'en', 'en_US:en' ],
'zh_CN.GB2312' => [ 'Chinese|Simplified', 'gb2312', 'zh_CN.GB2312', 'zh_CN.GB2312:zh_CN.gb2312:zh_CN:zh' ]
);
my %charsets = (
"iso-8859-1" => [ "lat0-sun16", undef, "iso15",
"iso8859-1", "850", sub { std("iso8859-1", @_) } ],
"gb2312" => [ undef, undef, undef,
"gb2312", "936", "-*-*-*-*-*-*-*-*-*-*-*-*-gb2312.1980-1" ],
);
unless (-e "$ENV{SHARE_PATH}/locale/$languages{$lang}[2]") {
@ENV{qw(LANG LC_ALL LANGUAGE LINGUAS)} = ();
eval { commands::rm("-r", "$ENV{SHARE_PATH}/locale") };
eval {
#- 取出Locale环境
require packdrake;
my $packer = new packdrake("$ENV{SHARE_PATH}/locale.cz2");
$packer->extract_archive("$ENV{SHARE_PATH}/locale", "UTF-8", $languages{$lang}[2]);
};
}
#- 明确设置Locale的环境变量
$ENV{LC_NUMERIC} = "C";
$ENV{LC_TIME} = "C";
$ENV{LC_COLLATE} = "C";
$ENV{LC_MONETARY} = "C";
$ENV{LC_MESSAGES} = "C";
$ENV{LC_PAPER} = "C";
$ENV{LC_NAME} = "C";
$ENV{LC_ADDRESS} = "C";
$ENV{LC_TELEPHONE} = "C";
$ENV{LC_MEASUREMENT} = "C";
$ENV{LC_IDENTIFICATION} = "C";
$ENV{LC_CTYPE} = $lang;
$ENV{LANG} = $languages{$lang}[2];
$ENV{LANGUAGE} = $languages{$lang}[3];
设置Locale变量之后,调用Gtk::Rc->parse_string()装入所需要的字体资源,然后调用Gtk->set_locale()使Locale设置生效就可以了。
2. 启动图形环境
启动图形环境,实际上就是在系统中运行X服务程序。为了使一个X服务器正常运行,必须生成正确的XFree86配置文件。在安装程序的 install_gtk.pm的createXconf函数中创建XFree86配置文件。关于XFree86的详细配置过程您也可以参看《如何在Linux下实现设备的配置》。
#- 这是安装程序的createXconf函数,它的主要功能是生成XFree86的配置文件。为了使下面
#- 的代码段更清晰,删除了一些根据芯片类型和鼠标类型进行配置的代码。因此,下面的代码和真
#- 实的安装程序代码略有不同而且只支持x86体系结构下的配置文件。
#- 建立真实鼠标设备的别名链接文件/dev/mouse。
symlinkf($mouse_dev, "/dev/mouse");
#- 建立imlib库配置文件和调色板文件的链接文件
symlink("/tmp/stage2/etc/imrc", "/etc/imrc");
symlink("/tmp/stage2/etc/im_palette.pal", "etc/im_palette.pal");
#- 生成XFree86配置文件$file
local *F;
open F, ">$file" or die "can't create X configuration file $file";
print F <
#- 下面的文本行,实际上是XFree86的配置文件。这个配置文件包含字体路径设置、键盘设置、
#- 鼠标设备设置、监视器设置和屏幕设置部分。
Section "Files"
FontPath "/usr/X11R6/lib/X11/fonts:unscaled"
EndSection
#- 键盘设置部分,设置当前键盘为标准键盘。
Section "Keyboard"
Protocol "Standard"
AutoRepeat 0 0
LeftAlt Meta
RightAlt Meta
ScrollLock Compose
RightCtl Control
XkbDisable
END
EndSection
#- 设置鼠标配置,包括设置鼠标的通讯协议类型以及鼠标设备对应的设备文件。
Section "Pointer"
Protocol "$mouse_type"
Device "/dev/mouse"
ZAxisMapping 4 5
EndSection
#- 设置监视器配置。由于在定制安装环境时,只使用了3.3.6的X服务器XF86_VGA16和
#- XF86_FBDev,这两种服务器的X配置文件都是无法指定显示分辨率的。对于XF86_VGA16,
#- 它只能支持640x480的16色显示方式。对于XF86_FBDev,它支持的显示方式是由当时内核
#- Framebuffer的工作模式决定的。比如,内核以0x311方式启动,那么对应的分辨率是
#- 640x480的16位色,那么在使用XF86_FBDev作为X服务器时,X的对应配置也必须与此完#- 全一致。
Section "Monitor"
Identifier "My Monitor"
VendorName "Unknown"
ModelName "Unknown"
HorizSync 31.5-35.5
VertRefresh 50-70
Modeline "640x480" 25.175 640 664 760 800 480 491 493 525
Modeline "640x480" 28.3 640 664 760 800 480 491 493 525
ModeLine "800x600" 36 800 824 896 1024 600 601 603 625
EndSection
#- 使用XF86_VGA16作为X服务器时,对应的X配置节。
Section "Screen"
Driver "vga16"
Device "Generic VGA"
Monitor "My Monitor"
Subsection "Display"
Modes "640x480"
ViewPort 0 0
EndSubsection
EndSection
#- 使用XF86_FBDev作为X服务器时,对应的X配置节。设置Modes为"default",表示选择
#- 的模式与内核启动时设置的模式相同。
Section "Screen"
Driver "fbdev"
Device "Generic VGA"
Monitor "My Monitor"
Subsection "Display"
Depth 16
Modes "default"
ViewPort 0 0
EndSubsection
EndSection
END
将上述程序段运行之后,X配置脚本就生成了,这时就可以使用这个配置脚本文件启动X服务程序了。下面这段启动X的程序是来自于文件install_steps_gtk.pm。
devices::make("/dev/kbd");
local (*T1, *T2);
open T1, ">/dev/tty5";
open T2, ">/dev/tty6";
#- 执行X服务器程序,返回1表示运行成功。
my $launchX = sub {
my $ok = 1;
#- 接管信号SIGCHLD的处理程序
#- 在进程终止时,SIGCHLD信号被发送给它的父进程。此程序在子进程结束时调用。
local $SIG{CHLD} = sub { $ok = 0 if waitpid(-1, c::WNOHANG()) > 0 };
#- 子进程执行
#- XF86_FBDev -kb -dpms -s 240 -allowMouseOpenFail -xf86config $f
#- allowMouseOpenFail允许鼠标打开失败
unless (fork) {
exec $_[0], "-kb", "-dpms","-s" ,"240",
"-allowMouseOpenFail", "-xf86config", $f or exit 1;
}
#- 测试X服务器是否成功激活
foreach (1..60) {
sleep 1;
log::l("Server died"), return 0 if !$ok;
return 1 if c::Xtest($ENV{DISPLAY});
}
log::l("Timeout!!");
0;
};
#- 准备测试的X服务器
my @servers = qw(FBDev VGA16);
foreach (@servers) {
log::l("Trying with server $_");
my $dir = "/usr/X11R6/bin";
my $prog = "XF86_$_";
#- 如果X服务程序不可执行
unless (-x "$dir/$prog") {
#- 删除/usr/X11R6/bin/下的所有X服务程序
unlink $_ foreach glob_("$dir/X*");
#- 从安装盘上拷贝对应的X服务程序
install_any::getAndSaveFile("HappyLinux/happyinst$dir/$prog", "$dir/$prog") or die "failed to get server $prog: $!";
chmod 0755, "$dir/$prog";
}
#- 根据/proc/fb文件的内容检测内核是否启动了Framebuffer方式。
if (/FB/) {
!$o->{vga16} && $o->{allowFB} or next;
$o->{allowFB} = &$launchX($prog) and goto OK;
} else {
$o->{vga16} = 1 if /VGA16/;
&$launchX($prog) and goto OK;
}
}
注: (我们在此专题中介绍的是HappyLinux 3.0的安装程序,它的安装程序源码您可以在安装盘的/HappyLinux/happyinst/usr/bin/perl-install目录下找到。安装程序的源码是由Perl编制的,使用PerlGtk绘制图形化用户接口。)

阅读(663) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~