Let's look briefly at both approaches, and then some additional configuration
to set up the user's working environment.
startx will start X by first
invoking xinit. By itself, this would put you at a blank,
fuzzy looking, bare-bones desktop with no Window Manager loaded.
xinit basically takes two sets of command line
arguments: client specifications (programs to run, etc), and server
specifications (X server options), separated by "--". If no
client program is specified on the command line, xinit
will look for a .xinitrc file in the user's home
directory, to run as a shell script. If found, this then would in turn run
whatever user specified commands to set up the environment, or launch
programs that the file contained. If this file does not exist,
xinit will use the following initial command:
xterm -geometry +1+1 -n login -display :0
|
If no .xserverrc is found in the user's home directory,
X itself will be started with the following command:
As you see, this is not overly helpful as it just launches one
xterm. The startx
shell wrapper provides additional functionality and flexibility to
xinit. startx will invoke
xinit for us, and provide some simple configuration
options as well. You can also issue commands such as the following, for
instance:
startx -- -dpi 100 -depth 16 #force X to 100 dots per inch
#and colordepth of 16 (X v4 syntax)
|
Anything after the double dashes are passed as arguments directly to the X
server via xinit. In this example, you can force
X to the resolution of your preference, and still
have it use the configuration files we will cover later in this document. See
the Xserver man page for more command line options.
Instead of issuing the same command line every time, it is easier to use the
configuration files to store this type of information for us.
If you take a look at the startx script
(/usr/X11R6/bin/startx on my system), you see it uses
two default configuration files to help set up the
X environment: xinitrc and
xserverrc. It looks first in
/etc/X11/xinit/, for the system wide files. It then
checks the user's home directory for similar files, which will take
precedence if found. Note that the latter are Unix style "dot" files
(e.g. ~/.xinitrc), and are executable shell scripts.
You normally would not want to edit the system wide files, but you can freely
copy these to your home directory as a starting point, or just start from
scratch. As you can tell by the names, one helps set up the X server, and one
sets up xinit by executing commands, preparing the
environment and possibly starting client programs like
xterm or a Window Manager (yes, it's a client too).
As with all XFree86 configuration files, this is a plain text file, and is
usually a simple, one line statement to start the X server. It can include
any valid command line options supported by your X
installation. If you always start X with your own
options, this should be easier than typing the options each time. One
possible ~/.xserverrc:
exec X :0 -dpi 100 -nolisten tcp
|
This will start X on display :0, the first
"display", at a dots-per-inch resolution of 100, and disables
TCP connections. See the Xserver man page for other valid options. This is
just an example.
xinitrc is used to set up a suitable
X environment, and to launch other programs, a.k.a
"clients" that we may want available as soon as
X is started. You likely have a system wide
xinitrc to start a predefined set off programs. To
customize this, create your own in your home directory. Name it
.xinitrc, make sure it is an executable script, and
chmod +x. An example (slightly modified from the original
on my system):
#!/bin/sh
# $XConsortium: xinitrc.cpp,v 1.4 91/08/22 11:41:34 rws Exp $
userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
# merge in defaults and keymaps
if [ -f $userresources ]; then
xrdb -merge $userresources
fi
if [ -f $usermodmap ]; then
xmodmap $usermodmap
fi
if [ -z "$BROWSER" ] ; then
# we need to find a browser on this system
BROWSER=`which netscape`
if [ -z "$BROWSER" ] || [ ! -e "$BROWSER" ] ; then
# not found yet
BROWSER=
fi
fi
if [ -z "$BROWSER" ] ; then
# we need to find a browser on this system
BROWSER=`which lynx`
if [ -z "$BROWSER" ] || [ ! -e "$BROWSER" ] ; then
# not found yet
BROWSER=
else
BROWSER="xterm -font 9x15 -e lynx"
fi
fi
export BROWSER
# start some nice programs
if [ -f $HOME/.Xclients ]; then
exec $HOME/.Xclients
else
xclock -geometry 50x50-1+1 &
xterm -geometry 80x50+494+51 &
if [ -f /usr/X11R6/bin/fvwm ]; then
exec fvwm
else
exec twm
fi
fi
#eof
|
Briefly, what this script does, is set up our working environment, with
xmodmap (keyboard) and xrdb
(application resource settings). More on these below. Then the shell variable
$BROWSER is set for a GUI environment (Netscape in this
example) so that any applications that might expect this, have a reasonable
choice available. Then the presence of the file Xclients
is checked, both as a system wide file and in the user's home directory. In
this particular example, this is where any client applications are to be
started, including a Window Manager (see below). These could just have as
easily been started here if we had wanted to. If an
Xclients file can't be found, then a Window Manager is
started for us. Either fvwm, if available, or XFree86's
minimalist twm if not. If for some reason, neither of
these can be started, the script would exit, and X
would fail to start.
Everything up to this point has followed pretty much a standard and
predictable sequence of events. To summarize, we have invoked
startx, which in turn invoked xinit,
which has parsed xinitrc for initial settings. Most
Linuxes should follow this same sequence, though the various values and
settings may differ.
We now are at the last link in the chain where the user normally would
specify his or her preferences, including the Window Manager and/or
desktop environment to be used. The system will provide sane, though possibly
uninteresting, defaults if the user has not done so. Presumably, this is why
you are here ;-)
The Window Manager, or desktop environment, is typically the last application
started. If you want other programs (like xterm) started,
they should be started before the Window Manager and
"backgrounded" with an "&". This can all be
done in the user's ~/.xinitrc. Or as in the above
example, the actual applications are started from yet another script. Let's
look at one short, hypothetical such script, .Xclients:
#!/bin/bash
# ~/.Xclients, start my programs.
xset s off s noblank
xset m 30/10 4
xset r rate 200 40
xscreensaver &
rxvt -geometry 80x50-50+150 &
echo Starting Window Manager...
if [ -x /usr/X11R6/bin/wmaker ]; then
echo `date`: Trying /usr/X11R6/bin/wmaker... |tee -a ~/.wm-errors 2>&1
exec /usr/X11R6/bin/wmaker >> ~/.wm-errors 2>&1
fi
echo `date`: Failed, trying fvwm... |tee -a ~/.wm-errors 2>&1
# let's try regular fvwm (AnotherLevel doesn't work with fvwm1).
if [ -n "$(type -path fvwm)" ]; then
# if this works, we stop here
exec fvwm >> ~/.wm-errors 2>&1
fi
echo `date`: Failed, trying twm... |tee -a ~/.wm-errors 2>&1
# wow, fvwm isn't here either ...
# use twm as a last resort.
exec twm >> ~/.wm-errors 2>&1
# Dead in the water here, X will exit as well, sigh...
echo `date`: Unable to start a Window Manager ... |tee -a ~/.wm-errors 2>&1
# eof
|
This really isn't so different than what xinitrc was
doing at all. We added a few wrinkles, including starting a screen saver, a
different terminal emulator that this user prefers (rxvt),
with even more setting up of the environment (monitor, mouse and keyboard) using
xset this time, and a different Window Manager than was
available with the system defaults. This is in the user's home directory, so
it won't be overwritten during upgrades too.
Actually, X has already started at this point, and
we are just putting the finishing touches on the configuration. Notice the
Window Managers are not "backgrounded" with "&"
here. This is important! Something has to run in the foreground, or
X will exit. We didn't start a desktop environment
in this example, like KDE or
GNOME, but if we did, this final application
would have to be gnome-session or
startkde instead. Since we are rolling our own here, if we
wanted to change Window Managers, all we have to do is edit this file, and
restart X. Vendor supplied configurations may be
more complex than this, but the same principles apply.
As an afterword, do not think that any initial client applications
must be started as we've done here. This is how it has
been traditionally done, and some may prefer this approach. Most window
managers have their own built-in ways to start initial programs, as do
KDE and GNOME. See
the respective documentation.