当前位置:操作系统 > Unix/Linux >>

解读startx

总览:

  startx 只是xinit的一个前端工具,它所做的只是设置好一些变量,资源。然后再用xinit 启动X window.

  xinit的命令格式:

  xinit [ [client] clientargs] [-- [server] [display] serverargs]

  startx所做的工作:

  一.获取命令行参数

  1.client段

  clientargs:

  完全从命令行中获取,无默认值

  client:

  如果没有指定,但是已经指定clientargs,则使用/usr/X11R6/bin/xterm

  如果没有指定,且没有指定clientargs,则使用./defaultclientargs,即按以下顺序取值:

  $HOME/.xinitrc -> /usr/X11R6/lib/X11/xinit/xinitrc

  /usr/X11R6/lib/X11/xinit/xinitrc其实就是执行/etc/X11/Xsessions这个脚本

  而/etc/X11/Xsession又会检查$HOME/.xsession,如果存在则把它作为client.

  所以如果$HOME/.xinitrc不存在时,它可以使用$HOME/.xsession;而当$HOME/.xinitrc存在

  时,它并不会使用$HOME/.xsession

  2.server段

  跟client类似

  增加一个display的设置,默认为":0"

  二.设置标志认证

  三.通过xinit启动X

  四.关闭X时,进行一些收尾工作。

  对xinit来说,如果没有指定client,则使用$HOME/.xinitrc,如果这个也不存在则使用xterm;如果没有指定server,则使用$HOME/.xserverc,如果这这个不存在的话则使用X :0。

  所以当由startx启动X时

  client的顺序是: 命令行 -> $HOME/.xinitrc -> $HOME/.xsession -> /usr/X11R6/lib/X11/xinit/xinitrc

  server的顺序是: 命令行 -> $HOME/.xserverrc -> /usr/X11R6/lib/X11/xinit/xserverrc

  以上"->"表示:当前一个不存在时,则取下面一个,直到存在。

  源码:

  #!/bin/sh

  # $Xorg: startx.cpp,v 1.3 2000/08/17 19:54:29 cpqbld Exp $

  #

  # This is just a sample implementation of a slightly less primitive

  # interface than xinit. It looks for user .xinitrc and .xserverrc

  # files, then system xinitrc and xserverrc files, else lets xinit choose

  # its default. The system xinitrc should probably do things like check

  # for .Xresources files and merge them in, startup up a window manager,

  # and pop a clock and serveral xterms.

  #

  # Site administrators are STRONGLY urged to write nicer versions.

  #

  # $XFree86: xc/programs/xinit/startx.cpp,v 3.12.2.2 2002/01/28 18:27:34 tsi Exp $

  #注意:xinit 的参数格式:

  #xinit $client $clientargs -- $server $display $serverargs

  #各个参数的特点:

  #client必须是以"/"或者"./"开头。因为client其实就是一个程序,所以他是由路径来指出

  的

  #第一个clientargs不能是以"/"或者"./"开头的。

  #对于server跟serverargs的区别也是类似的。

  #而display跟serverargs的区别

  #display是第一个以":??"(??代表两个数字)开头的字符串。

  userclientrc=$HOME/.xinitrc

  userserverrc=$HOME/.xserverrc

  sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc

  sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc

  defaultclient=/usr/X11R6/bin/xterm

  defaultserver=/usr/X11R6/bin/X

  defaultclientargs=""

  defaultserverargs=""

  clientargs=""

  serverargs=""

  #===================参数配置文件================

  if [ -f $userclientrc ]; then

  defaultclientargs=$userclientrc

  elif [ -f $sysclientrc ]; then

  defaultclientargs=$sysclientrc

  fi

  if [ -f $userserverrc ]; then

  defaultserverargs=$userserverrc

  elif [ -f $sysserverrc ]; then

  defaultserverargs=$sysserverrc

  fi

  #接收命令行参数

  whoseargs="client"

  #谁的参数--之前是client的参数,--之后是server的参数。

  while [ x"$1" != x ]; do

  case "$1" in

  # '' required to prevent cpp from treating "/*" as a C comment.

  /''*|\./''*)

  #这个参数是以"/"或者"./"开头

  if [ "$whoseargs" = "client" ]; then

  if [ x"$clientargs" = x ]; then

  # 如果clientargs为空,说明这个参数是从命令行传入的第一个参数

  # 故它应该是client

  client="$1"

  else

  clientargs="$clientargs $1"

  fi

  else

  if [ x"$serverargs" = x ]; then

  #为什么这里不用display是否为空来判断呢?

  #因为display可以省略,这时则不能正确判断了。

  server="$1"

  else

  serverargs="$serverargs $1"

  fi

  fi

  ;;

  --)

  whoseargs="server"

  ;;

  *)

  if [ "$whoseargs" = "client" ]; then

  clientargs="$clientargs $1"

  else

  # display must be the FIRST server argument

  if [ x"$serverargs" = x ] && expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then

  #如果serverargs为空,并且$1是以":"跟数字组成,即为display参数。

  display="$1"

  else

  serverargs="$serverargs $1"

  fi

  fi

  ;;

  esac

  shift

  done

  #命令行参数接收完毕。

  # process client arguments

  if [ x"$client" = x ]; then

  # if no client arguments either, use rc file instead

  if [ x"$clientargs" = x ]; then

  client="$defaultclientargs"

  else

  client=$defaultclient

  fi

  fi

  # process server arguments

  if [ x"$server" = x ]; then

  # if no server arguments or display either, use rc file instead

  if [ x"$serverargs" = x -a x"$display" = x ]; then

  server="$defaultserverargs"

  else

  server=$defaultserver

  fi

  fi

  if [ x"$XAUTHORITY" = x ]; then

  XAUTHORITY=$HOME/.Xauthority

  export XAUTHORITY

  fi

  removelist=

  # set up default Xauth info for this machine

  # check for GNU hostname

  if hostname --version > /dev/null 2>&1; then

  if [ -z "`hostname --version 2>&1 | grep GNU`" ]; then

  hostname=`hostname -f`

  #long hostname

  fi

  fi

  if [ -z "$hostname" ]; then

  hostname=`hostname`

  fi

  #以上是设置hostname

  #添加X标记认证。

  authdisplay=${display:-:0}

  #设置要验证的显示,如果display已经设置则取display的值;

  #如果display没有设置,则取:0

  mcookie=`mcookie`

  for displayname in $authdisplay $hostname$authdisplay; do

  if ! xauth list "$displayname" | grep "$displayname " >/dev/null 2>&1; then

  #没有xauth认证,需要添加。

  xauth add $displayname . $mcookie

  removelist="$displayname $removelist"

  fi

  done

  #启动X window

  xinit $client $clientargs -- $server $display $serverargs

  #关闭X window时

  if [ x"$removelist" != x ]; then

  #删除标记认证

  xauth remove $removelist

  fi

  #释放不用的虚拟终端所占用的资源

  if command -v deallocvt > /dev/null 2>&1; then

  deallocvt

  fi

  由于本人对X机制也不是很了解
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,