3. Running X

Starting an X session is typically done in one of two ways: the X
session is started via a display manager (like xdm), and the user
logs in at a GUI screen. Or, the user starts X manually after
logging in to a text console. The latter is typically done with the
startx command, which is a simple shell script wrapper for xinit. X
runs with root privileges in either case, since it needs raw access
to hardware devices.

Typically, which method is used, is determined by the system
"runlevel". The default runlevel to launch at boot is generally set
in /etc/inittab on Linux:

# Run xdm in runlevel 5
x:5:respawn:/etc/X11/xdm -nodaemon



That would start xdm, and thus X, at runlevel 5. It will "respawn",
if it dies or is stopped for any reason. You can also use the "init"
command to change runlevels without rebooting (see man page).

Let's look briefly at both approaches, and then some additional
configuration to set up the user's working environment.  3.1. startx

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:

X :0



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).
3.1.1. xserverrc

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.  3.1.2. xinitrc

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.  3.1.3. Xclients

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.  3.2. Display
Managers

The other, more common, approach is the "GUI log-in", where X is
running before log-in. This is done with the help of a "display
manager", of which there are various implementations. XFree86
includes xdm (X Display Manager) for this purpose, though your
distribution may use one of the others such as gdm (GNOME) or kdm
(KDE).

Display managers really do much more than enable GUI style log-ins.
They are also used to manage local as well as remote "displays" on a
network. We won't get into details on this here, but it is nicely
covered in the Remote X Apps Mini HOWTO and the XDMCP HOWTO (see the
links section). For our purposes here, they provide similar services
to getty and login, which allow users to log into a system and start
their default shell, but in a GUI environment.

Here is an example of a more advanced usage of what else a display
manager might be used for, from Diego Zamboni:

   I have two X sessions running with different resolutions. I
   switch between them depending on whether my laptop is connected
   to an external monitor or using its own LCD display.

   Here's my /usr/lib/X11/xdm/Xservers file that initiates both displays:

    :1 local /usr/X11R6/bin/X :1 -layout 1024x768
    :0 local /usr/X11R6/bin/X :0 -layout 1600x1200



   Then I have "1024x768" and "1600x1200" defined as "server layouts" in my
   /etc/X11/XF86Config-4, as follows:

    Section "ServerLayout"
            Identifier     "1600x1200"
            Screen         "Screen0" 0 0
            InputDevice    "Mouse0" "CorePointer"
            InputDevice    "Keyboard0" "CoreKeyboard"
    EndSection

    Section "ServerLayout"
            Identifier     "1024x768"
            Screen         "Screen1" 0 0
            InputDevice    "Mouse0" "CorePointer"
            InputDevice    "Keyboard0" "CoreKeyboard"
    EndSection

    ## snip ...

    Section "Screen"
            Identifier   "Screen0"
            Device       "S3 Savage/MX"
            Monitor      "Monitor0"
            DefaultDepth 16

            Subsection "Display"
                    Depth  16
                    Modes  "1600x1200" "1280x1024" "1024x768"
            EndSubsection
    EndSection

    Section "Screen"
            Identifier   "Screen1"
            Device       "S3 Savage/MX"
            Monitor      "Monitor0"
            DefaultDepth 16

            Subsection "Display"
                    Depth  16
                    Modes  "1024x768" "800x600"
            EndSubsection
    EndSection



Note the use of "Identifiers" here. Diego is starting two separate
"displays" here. Then he can choose which one he wants when he logs
in.

Most display managers are derived from XFree86's venerable xdm, and
add their own enhancements. Let's look at the most popular ones
briefly.  3.2.1. xdm

xdm can be configured with configuration files located in
/etc/X11/xdm/, /usr/X11R6/lib/X11/xdm, or similar locations
depending on your system. These are system wide files. The file
xdm-config is the main configuration file, and mostly describes
where to find secondary configuration files:

! $XConsortium: xdm-conf.cpp /main/3 1996/01/15 15:17:26 gildea $
DisplayManager.errorLogFile:   /var/log/xdm-errors
DisplayManager.servers:                /etc/X11/xdm/Xservers
DisplayManager.accessFile:     /etc/X11/xdm/Xaccess
! All displays should use authorization, but we cannot be sure
! X terminals will be configured that way, so by default
! use authorization only for local displays :0, :1, etc.
DisplayManager._0.authorize:   true
DisplayManager._1.authorize:   true
! The following three resources set up display :0 as the console.
DisplayManager._0.setup:       /etc/X11/xdm/Xsetup_0
DisplayManager._0.startup:     /etc/X11/xdm/GiveConsole
DisplayManager._0.reset:       /etc/X11/xdm/TakeConsole
!
DisplayManager*resources:      /etc/X11/xdm/Xresources
DisplayManager*session:                /etc/X11/xdm/Xsession
!
! SECURITY: do not listen for XDMCP or Chooser requests
! Comment out this line if you want to manage X terminals with xdm
DisplayManager.requestPort:    0



The "!" denotes comments. The command that starts the X server is in
/etc/X11/xdm/Xservers in this particular example as defined by
"DisplayManager.servers", and is the equivalent to xserverrc that
was used for startx X server start up commands, but the syntax is
slightly different here. The contents of /etc/X11/xdm/Xservers on my
system are simply:

:0 local /usr/X11R6/bin/X



This starts X on the first local display (designated by 0). Any
special command line arguments that you want to add go here at the
end.

Below is a sample /etc/X11/xdm/Xsetup_0 which is used to configure
the log-in screen only. Notice that we're using a shell script here,
and it's calling xv (a graphics display program) to set the
background to a nice image (instead of the boring black and white
background pattern), and if that fails, xsetroot is then invoked to
at least try to set the background to a nicer blue color. This does
not configure the login widget itself -- just other things that
might be wanted on the screen during login.


#!/bin/sh
xconsole -geometry 480x100-0-0 -daemon -notify -verbose -fn \
  '-schumacher-clean-medium-r-*-*-10-*-*-*-*-*-*-*' -exitOnFail  &

/usr/X11R6/bin/xv -quit -root /usr/share/pixmaps/Backgrounds/InDreams.jpg \
  || xsetroot -solid darkblue



/etc/X11/xdm/Xresources controls the X "resources" used during log
in. In this context, "resources" are user preferences for such items
as fonts and colors (described in more detail below). Below is a
snippet that sets up fonts for the log-in widget:

#if WIDTH > 800
xlogin*greetFont: -adobe-helvetica-bold-o-normal--24-240-75-75-p-138-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--18-180-75-75-p-103-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
#else
xlogin*greetFont: -adobe-helvetica-bold-o-normal--17-120-100-100-p-92-iso8859-1
xlogin*font: -adobe-helvetica-medium-r-normal--12-120-75-75-p-69-iso8859-1
xlogin*promptFont: -adobe-helvetica-bold-r-normal--12-120-75-75-p-69-iso8859-1
xlogin*failFont: -adobe-helvetica-bold-o-normal--14-140-75-75-p-82-iso8859-1
#endif



As you can see this is using helvetica as the preferred font, with
different point sizes and dots per inch depending on the screen
size. This is customizable to suit individual needs. (See below for
more on understanding X font naming conventions.) Various other
aspects can similarly be configured.

/etc/X11/xdm/Xsession is the rough equivalent to xinitrc for startx.
It will similarly set up a default environment for keyboard, etc.
And can also start either KDE or GNOME, and other X client programs.
This is the system wide configuration file. It should also check the
user's home directory for ~/.xsession, and possibly ~/.Xclients,
which would contain the user's preferred environment and start up
programs, just as ~/.xinitrc did with startx. Again, the files in a
user's home directory may be created or modified by the user any
time and must be executable shell scripts.

We won't include an ~/.xsession example here, since it would be very
similar to the ~/.xinitrc and ~/.Xclients examples above.

We've looked only briefly at the main xdm configuration files. Be
sure to read the man page, and look at what is installed locally,
for more information. Let's look now at gdm and kdm. We'll just
highlight significant differences, since they essentially provide
the same functionality.
3.2.2. gdm

gdm is the default display manager for GNOME. gdm was written from
scratch, but functions similarly to xdm. The main configuration file
is gdm.conf, typically located as /etc/X11/gdm/gdm.conf. This is
quite different looking than xdm-config. Comments are denoted with a
"#", and the file has sections, with section headers enclosed in
square brackets. The command to start X is in the "[servers]"
section:

[servers]
0=/usr/bin/X11/X
#1=/usr/bin/X11/X



Notice this has potentially two displays set up, but the second one
is commented out. Add any additional X startup options here, e.g.
"-dpi 100". The log-in screen and log-in widget are configured in
the "[greeter]" section.

Start up clients and programs are determined by the "SessionDir"
statement in the "[daemon]" section. On my installation, this points
to /etc/X11/gdm/Sessions/, which contains several short scripts. If
I look at my Default script, it actually executes
/etc/X11/xdm/Xsession, which in turn would execute ~/.xsession, if
present. So at this final stage, gdm acts very much like xdm.

GNOME includes the gdmconfig utility to control many aspects of gdm
behavior.
3.2.3. kdm

kdm is the display manager from KDE. The main configuration file for
kdm is kdmrc and is typically installed as /etc/kde/kdm/kdmrc. As is
the case with gdm.conf, kdmrc uses "#" for comments, and has
sections with section headers in similar square brackets. kdm
configuration can also be edited with the kcontrol utility.

The visible desktop is configured in the "[Desktop*]" section(s),
and by the "Setup" directive which should point to a file like
/usr/share/config/kdm/Xsetup or /etc/X11/xdm/Xsetup_0. This will
accomplish the same thing as xdm's Xsetup_0 does: namely running any
programs the user might want such as xconsole.

The command to launch the X server is the "Xservers" directive in
the "[General]". Again, this should point to a file such as
/etc/X11/xdm/Xservers, and uses the same syntax as xdm:

:0 local /usr/X11R6/bin/X



Any command line options for the X server, go here.

The login widget itself is configured in the "[X-*-Greeter]"
section(s). Compiled in defaults are used if the user does not
specify any.

KDE includes the kdmdesktop utility to control some aspects of kdm
behavior, mostly just the login background.