Chinaunix首页 | 论坛 | 博客
  • 博客访问: 599465
  • 博文数量: 95
  • 博客积分: 1573
  • 博客等级: 上尉
  • 技术积分: 1030
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-23 10:46
个人简介

hello world!

文章分类

全部博文(95)

文章存档

2014年(1)

2013年(44)

2012年(50)

分类:

2012-03-15 15:28:05

原文地址:gnome启动分析 作者:sjj0412

-----------------------------------------------------------
本文系本站原创,欢迎转载!

转载请注明出处: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这个文件,它们都包含了以下几个系统文件以及主文件夹下的配置文件(没有设置的话都为空)

Xserver,单一,而Xsessionclient,复杂多样,比如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 _ without . and .@EURO

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脚本(这个脚本)前配置了XIMinput.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是说scimdaemon(守护进程)方式运行。

 

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.sopython.so两种输入法。

我们可以做一个实验,就是我们把pinyin.so删除,然后再点scim设置,在输入法一栏,我们将看不到pinyin输入法。

 

从上面可以看出:

     scim是一种输入法架构,是核心,其他的具体输入法,如scim-pinyin,scim-python都是利用scim架构分别实现IMEEngine等模块并以.so动态库的形式放到指定目录提供。

 

      

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