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.
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).
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 will not 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.
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 shall not 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.
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 shall not 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.
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.
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.