分类: LINUX
2009-09-09 09:46:16
-----------------------------------------------------------
本文系本站原创,欢迎转载!
转载请注明出处:http://sjj0412.cublog.cn/
-----------------------------------------------------------
环境:ubuntu9.04。在ubuntu下,如果你没有修改配置,运行方式默认是2.故会执行/etc/init.d/rc2.d文件夹下的各个脚本
jerry@jerry-laptop:~$ ls /etc/rc2.d/
README S20postfix S50saned S98usplash
S01policykit S24hal S50system-tools-backends S99acpi-support
S10acpid S25bluetooth S70bootlogs.sh S99laptop-mode
S10apmd S30gdm S70dns-clean S99ondemand
S10sysklogd S50avahi-daemon S70pppd-dns S99rc.local
S11klogd S50cups S89anacron S99rmnologin
S12dbus S50NetworkManager S89atd S99stop-readahead
S20apport S50pulseaudio S89cron
S20hotkey-setup S50rsync S90binfmt-support
上面和gnome有关是S30gdm.
S30gdm中:
case "$1" in
start)
if grep -wqs text
/proc/cmdline; then
log_warning_msg "Not starting GNOME Display Manager (gdm); found 'text' in kernel commandline."
这个说明如果在运行参数里于text就以为这不启动图形。
SSD_ARG="--exec $DAEMON"
DAEMON=/usr/sbin/gdm
start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --name gdm $SSD_ARG -- $CONFIG_FILE >/dev/null 2>&1 || log_end_msg 1
这个启动了gdm
上面的start-stip-daemon主要是让gdm只有一个实例。这个是通过pidfile实现的,当存在pidfile时就说明已经启动了。
下面看下gdm:
通过 man gdm 可以获得以下非常重要的信息:
GDM is
a replacement for XDM, the X
Display Manager. Unlike its com-
petitors (X3DM, KDM, WDM) GDM was written from scratch and does not
contain any original XDM / X Consortium code. GDM runs and manages the
X servers for both local and remote logins (using XDMCP). See
for more details.
gdm is main executable. gdmsetup is a graphical tool for easily chang-
ing the most commonly used options.
For full documentation see the GNOME help browser under the Applica-
tions / System Tools section.
gdm具体做些什么事情呢?
先看下这段英文:
When
managing a display, gdm attempts to execute /etc/gdm/Init/display,
or /etc/gdm/Init/Default if that does not exist. When a user logs in,
gdm first attempts /etc/gdm/PreSession/display (or /etc/gdm/PreSes-
sion/Default), and then one of the sessions in /etc/gdm/Sessions. When
the session has completed, gdm attempts to run /etc/gdm/PostSes-
sion/display, or /etc/gdm/PostSession/Default. Of all these files, only
the /etc/gdm/Sessions one is required to exist.
事实上,GDM管理的不只是X的启动,还有登录,注销,挂起等一系列操作。
它的配置文件:/etc/gdm/gdm.conf
LogDir=/var/log/gdm
# Note that a post login script is run before a PreSession script. It is run
# after the login is successful and before any setup is run on behalf of the
# user.
PostLoginScriptDir=/etc/gdm/PostLogin/
PreSessionScriptDir=/etc/gdm/PreSession/
PostSessionScriptDir=/etc/gdm/PostSession/
DisplayInitDir=/etc/gdm/Init
#
这个配置文件就设置上面英文中说到的。
GDM 使用/etc/gdm/gdm.conf --> X #启动X
--> /etc/gdm/Xsession #启动X会话
2,若你听过"startx"这个脚本的话,也可以用它来启动图形界面。将当前的会话转换到控制台下,这时X还在运行中,你可以用下面的命令还停止X,
sudo /etc/init.d/gdm stop
在控制台下输入"startx"又可以回到图形界面下,不过,它执行的是和GDM不一样的过程
分析"startx"脚本,可以看到调用xinit的过程,xinit用到的配置文件
/etc/X11/xinit/xserverrc --> X #启动X
/etc/X11/xinit/Xinitrc --> /etc/X11/Xsession #启动X会话
从上面看来,以上两种方法都实现了上面的两个部分,一就是启动X,另一个就是启动X会话,分析Xsession这个文件,它们都包含了以下几个系统文件以及主文件夹下的配置文件(没有设置的话都为空) 。
X是server,单一,而Xsession是client,复杂多样,比如gnome就是属于Xsession,当然kde也是。
Xsession做些什么事呢?
SYSSESSIONDIR=/etc/X11/Xsession.d
SESSIONFILES=$(run-parts --list $SYSSESSIONDIR)
if [ -n "$SESSIONFILES" ]; then
set +e
for SESSIONFILE in $SESSIONFILES; do
. $SESSIONFILE
done
set -e
fi
这个其实就是轮询/etc/X11/Xsession.d 下的脚本并执行。
jerry@jerry-laptop:/usr/lib/scim-1.0/1.4.0/IMEngine$ ls /etc/X11/Xsession.d
20x11-common_process-args 60xdg-user-dirs-update
30x11-common_xresources 70pulseaudio
40x11-common_xsessionrc 75dbus_dbus-launch
50x11-common_determine-startup 80im-switch
52libcanberra-gtk-module_add-to-gtk-modules 90consolekit
55gnome-session_gnomerc 90x11-common_ssh-agent
60seahorse-plugins 99x11-common_start
60x11-common_localhost
这里需要注意的有几个文件:
1.50x11-common_determine-startup文件,这个是选择窗体管理程序。里面有
代码:
if [ -z "$STARTUP" ]; then
if [ -x /usr/bin/x-session-manager ]; then
STARTUP=x-session-manager
elif [ -x /usr/bin/x-window-manager ]; then
STARTUP=x-window-manager
elif [ -x /usr/bin/x-terminal-emulator ]; then
STARTUP=x-terminal-emulator
fi
2. 80im-switch,这个是输入法相关的:
_XIM=$XIM
_XIM_PROGRAM=$XIM_PROGRAM
_XIM_ARGS=$XIM_ARGS
_XMODIFIERS=$XMODIFIERS
_GTK_IM_MODULE=$GTK_IM_MODULE
_QT_IM_MODULE=$QT_IM_MODULE
# $LNG is locale
LNG=${LC_ALL:-${LC_CTYPE:-${LANG}}}
//LNG=zh_CN.UTF-8
LNG=${LNG%@*}
//LNG=zh_CN.UTF-8
LNG=${LNG%.*}
//LNG=zh_CN
[ -z "$LNG" ] && LNG="all_ALL" || true
echo "Setting IM through im-switch for locale=$LNG."
# Source first found configuration under $LNG locale
//读取xinit/xinput.d文件夹下文件配置
for f in "$HOME/.xinput.d/${LNG}"
\
"$HOME/.xinput.d/all_ALL" \
"/etc/X11/xinit/xinput.d/${LNG}" \
"/etc/X11/xinit/xinput.d/all_ALL" \
"/etc/X11/xinit/xinput.d/default" ; do
if [ -f "$f" -a -r "$f" ]; then
echo "Start IM through $f linked to $(readlink -f $f)."
. "$f"
break
fi
done
上面的$HOME中的是通过im_switch配置时生成的。
由break可知$HOME里的配置优先级高。
unset LNG
# Revibe IM related environment if other values were set.
[ "$_XIM" ] &&
XIM=$_XIM || true
//如果在im-switch脚本(这个脚本)前配置了XIM则input.d中的XIM配置无效。
[ "$_XIM_PROGRAM" ] && XIM_PROGRAM=$_XIM_PROGRAM || true
[ "$_XIM_ARGS" ] && XIM_ARGS=$_XIM_ARGS || true
[ "$_XMODIFIERS" ] && XMODIFIERS=$_XMODIFIERS ||true
[ "$_GTK_IM_MODULE" ] && GTK_IM_MODULE=$_GTK_IM_MODULE || true
[ "$_QT_IM_MODULE" ] && QT_IM_MODULE=$_QT_IM_MODULE || true
[ -n "$GTK_IM_MODULE" ] && export GTK_IM_MODULE || true
[ -n "$QT_IM_MODULE" ] && export QT_IM_MODULE || true
# setup XMODIFIERS
[ -z "$XMODIFIERS" -a -n "$XIM" ] && XMODIFIERS="@im=$XIM" || true
[ -n "$XMODIFIERS" ] && export XMODIFIERS || true
# execute XIM_PROGRAM
if [ -n "$XIM_PROGRAM" -a -x "$XIM_PROGRAM" ]; then
if [ -z "$XIM_PROGRAM_SETS_ITSELF_AS_DAEMON" ]; then
eval "$XIM_PROGRAM $XIM_ARGS &" || true
else
eval "$XIM_PROGRAM $XIM_ARGS" || true
fi
fi
# execute XIM_PROGRAM_XTRA
上面的xargs一般=-d这个是就会相当于执行scim -d,
man scim可以看到-d的解释:
-d | --daemon
Run as a daemon. The program will exit and leave a daemon in
the background if invoked with this option.
这个-d是说scim以daemon(守护进程)方式运行。
3.99x11-common_start,里面只有一条命令:
exec $STARTUP
这个就是执行50x11-common_determine-startup中选择的窗口管理程序。
到此gnome启动起来了。
下面详细说下scim:
1.概述
SCIM 是Smart Common Input Method的简称,它是一个输入法框架,由苏哲领导开发的。作为新一代输入法框架,其架构设计精良,具有很好的扩充性和灵性性,代码质量也非常高,称得
上是国内经典的开源项目了。本文试图对SCIM的架构进行分析,了解它的架构,也许并不能帮助你更好的使用它,但对于添加新的输入法引擎,或者把它移植到
其它平台,会有一些帮助。不过,即使单从学习的角度出发,了解它的架构,对于提高设计能力也是有很大好处的。
SCIM具有如下特点:
1.完全面向对象的设计,并用C++实现。
2.高度模块化。
3.非常灵活的设计,支持动态加载不同的输入法,支持C/S模型运行。
4.简单的编程接口。
5.对UNICODE提供全面支持。
6.提供了一些非常好用的工具函数,可以大大加快开发进度。
7.提供了功能丰富的GUI panel。
8.提供了统一的配置框架。
9.很方便的集成现存的输入法。
10.不但支持传统的键盘输入法,也支持手写识别等新式输入法。
2.SCIM的组成部件
配置模块(Config)
输入法前端模块(FrontEnd)
输入法引擎模块(IMEngine)
进程间通信模块(IPC)
输入法Panel
输入法Helper
SCIM是高度模块化的,每个模块都非常独立。为了做到这一点,一方面需要从设计出发,让各个模块完成单一的功能,使模块本身是高内聚的。而另一方面,SCIM也采用了几种高级的技术:
针对接口编程。对于一些具有不同实现的模块,为了减少与调用者的耦合,提供一个抽象的接口是有必要的。配合下文所介绍的动态加载机制,模块的调用者根本不关心采用的哪种实现,接口与实现是分开的,它使用的是模块的抽象接口,模块的实现变化时,对模块的使用者几乎没有影响。
模块动态加载机制。SCIM的整个设计干净利落,框架就是框架,其它任何附加的功能都是通过插件来实现的,在运行时才动态的加载进来。不同的平台对于动态库的处理方式有些不一样,SCIM实现了一个module类,对操作系统的底层函数进行了封装,同时提供面向对象的接口,使用更加方便。
signal/slot 机制。多个不同的对象协作起来完成一项任务,是面向对象设计的特点之一。消息在这些对象之间来回传递,特别是对于异步调用、事件/状态触发等情况,底层模 块需要调用上层模块中的函数。这样,模块之间的层次关系不再像面向过程中那样明显。凡事有利必有弊,如果设计得不好,可能会造成上层与下层之间紧密的耦
合,层次关系混乱。为了避免这个问题,SCIM里采用了signal/slot机制,上层向下层注册signal的处理器(slot)。当某个 signal触发时,下层模块回调signal的处理器(slot)。
下面我们以scim-pinpin输入法的安装来说明这种架构:
sudo apt-get
install scim-pinyin
jerry@jerry-laptop:~$
dpkg -L scim-pinyin
/.
/usr
/usr/lib
/usr/lib/scim-1.0
/usr/lib/scim-1.0/1.4.0
/usr/lib/scim-1.0/1.4.0/IMEngine
/usr/lib/scim-1.0/1.4.0/IMEngine/pinyin.so
/usr/lib/scim-1.0/1.4.0/SetupUI
/usr/lib/scim-1.0/1.4.0/SetupUI/pinyin-imengine-setup.so
可以看到,一个输入法,要让scim识别,必须有IMEngine/pinyin.so ,/SetupUI/pinyin-imengine-setup.so,即在IMEEngine,和SetupUI 有相应的库。
jerry@jerry-laptop:/usr/lib/scim-1.0$ ls
1.4.0 scim-helper-manager scim-panel-gtk
scim-helper-launcher scim-launcher
jerry@jerry-laptop:/usr/lib/scim-1.0/1.4.0$ ls
Config Filter FrontEnd Helper IMEngine SetupUI
这个可以清楚的看清scim的架构,每个模块有一个文件夹对应,里面都是动态库,我们要添加一种输入法就要在各个文件夹里添加相应文件。
jerry@jerry-laptop:/usr/lib/scim-1.0/1.4.0/IMEngine$ ls
pinyin.so python.so rawcode.so socket.so
python.so -> ../../../python-support/python-scim/python2.5/scim-0.1/scim/_scim.so
从这里我们可以看出装了pinyin.so和python.so两种输入法。
我们可以做一个实验,就是我们把pinyin.so删除,然后再点scim设置,在输入法一栏,我们将看不到pinyin输入法。
从上面可以看出:
scim是一种输入法架构,是核心,其他的具体输入法,如scim-pinyin,scim-python都是利用scim架构分别实现IMEEngine等模块并以.so动态库的形式放到指定目录提供。