nixpkgs/upstart-jobs/xserver.nix

417 lines
11 KiB
Nix

{ stdenv, writeText, lib, xorg, mesa, xterm, slim, gnome
, compiz, feh
, kdelibs, kdebase
, xkeyboard_config
, openssh, x11_ssh_askpass
, nvidiaDrivers, libX11, libXext
, synaptics
, config
, # Virtual console for the X server.
tty ? 7
, # X display number.
display ? 0
, # List of font directories.
fontDirectories
, # Is Clone mode on?
isClone ? "on"
, # Do we want it to run or just to prepare everything?
autorun ? true
, # Create unneeded links in /etc?
exportConfiguration ? false
}:
let
cfg = config.services.xserver;
optional = condition: x: if condition then [x] else [];
# Get a bunch of user settings.
videoDriver = cfg.videoDriver;
resolutions = map (res: "\"${toString res.x}x${toString res.y}\"") (cfg.resolutions);
sessionType = cfg.sessionType;
sessionStarter = cfg.sessionStarter;
renderingFlag = cfg.renderingFlag;
sessionCmd =
if sessionType == "" then sessionStarter else
if sessionType == "xterm" then "${xterm}/bin/xterm -ls" else
if sessionType == "gnome" then "${gnome.gnometerminal}/bin/gnome-terminal -ls" else
abort ("unknown session type "+ sessionType);
windowManager =
let wm = cfg.windowManager; in
if wm != "" then wm else
if sessionType == "gnome" then "metacity" else
if sessionType == "kde" then "none" /* started by startkde */ else
"twm";
modules =
optional (videoDriver == "nvidia") nvidiaDrivers ++ #make sure it first loads the nvidia libs
[
xorg.xorgserver
xorg.xf86inputkeyboard
xorg.xf86inputmouse
]
++ optional (videoDriver == "vesa") xorg.xf86videovesa
++ optional (videoDriver == "vga") xorg.xf86videovga
++ optional (videoDriver == "sis") xorg.xf86videosis
++ optional (videoDriver == "i810") xorg.xf86videoi810
++ optional (videoDriver == "intel") xorg.xf86videointel
++ optional (videoDriver == "nv") xorg.xf86videonv
++ optional (videoDriver == "ati") xorg.xf86videoati
++ (optional (cfg.isSynaptics) [(synaptics+"/"+xorg.xorgserver) /*xorg.xf86inputevdev*/]);
configFile = stdenv.mkDerivation {
name = "xserver.conf";
src = ./xserver.conf;
inherit fontDirectories videoDriver resolutions isClone;
synapticsInputDevice = (if cfg.isSynaptics then "
Section \"InputDevice\"
Identifier \"Touchpad[0]\"
Driver \"synaptics\"
Option \"Device\" \"${cfg.devSynaptics}\"
Option \"Protocol\" \"PS/2\"
Option \"LeftEdge\" \"1700\"
Option \"RightEdge\" \"5300\"
Option \"TopEdge\" \"1700\"
Option \"BottomEdge\" \"4200\"
Option \"FingerLow\" \"25\"
Option \"FingerHigh\" \"30\"
Option \"MaxTapTime\" \"180\"
Option \"MaxTapMove\" \"220\"
Option \"VertScrollDelta\" \"100\"
Option \"MinSpeed\" \"0.06\"
Option \"MaxSpeed\" \"0.12\"
Option \"AccelFactor\" \"0.0010\"
Option \"SHMConfig\" \"on\"
Option \"Repeater\" \"/dev/input/mice\"
Option \"TapButton1\" \"1\"
Option \"TapButton2\" \"2\"
Option \"TapButton3\" \"3\"
EndSection " else "");
xkbOptions = if (cfg.xkbOptions) == "" then "" else
" Option \"XkbOptions\" \"${cfg.xkbOptions}\"";
layout = cfg.layout;
corePointer = if cfg.isSynaptics then "Touchpad[0]" else "Mouse[0]";
internalAGPGART =
if (cfg.useInternalAGPGART) == "yes" then
" Option \"UseInternalAGPGART\" \"yes\""
else if (cfg.useInternalAGPGART) == "no" then
" Option \"UseInternalAGPGART\" \"no\""
else " ";
extraDeviceConfig = cfg.extraDeviceConfig;
extraMonitorSettings = cfg.extraMonitorSettings;
extraModules = cfg.extraModules;
serverLayoutOptions = cfg.serverLayoutOptions;
defaultDepth = cfg.defaultDepth;
xfs = (if cfg.useXFS == false then "" else
"FontPath \"${toString cfg.useXFS}\"");
buildCommand = "
buildCommand= # urgh, don't substitute this
export fontPaths=
for i in $fontDirectories; do
if test \"\${i:0:\${#NIX_STORE}}\" == \"$NIX_STORE\"; then
for j in $(find $i -name fonts.dir); do
fontPaths=\"\${fontPaths}FontPath \\\"$(dirname $j)\\\"\n\"
done
fi
done
export modulePaths=
for i in $(find ${toString modules} -type d); do
if ls $i/*.so 2> /dev/null; then
modulePaths=\"\${modulePaths}ModulePath \\\"$i\\\"\n\"
fi
done
#if only my gf were this dirty
if test \"${toString videoDriver}\" == \"nvidia\"; then
export moduleSection='
Load \"glx\"
SubSection \"extmod\"
Option \"omit xfree86-dga\"
EndSubSection
'
export screen='
Option \"AddARGBGLXVisuals\" \"true\"
Option \"DisableGLXRootClipping\" \"true\"
'
export device='
Option \"RenderAccel\" \"true\"
Option \"AllowGLXWithComposite\" \"true\"
Option \"AddARGBGLXVisuals\" \"true\"
'
export extensions='
Option \"Composite\" \"Enable\"
'
else
export moduleSection='
Load \"glx\"
Load \"dri\"
'
export screen=
export device=
export extensions=
fi
if [ \"${toString videoDriver}\" = i810 ]; then
extensions='
Option \"Composite\" \"Enable\"
';
fi;
substituteAll $src $out
";
};
clientScript = writeText "xclient" "
source /etc/profile
exec > $HOME/.Xerrors 2>&1
### Load X defaults.
if test -e ~/.Xdefaults; then
${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
fi
${if cfg.startSSHAgent then "
### Start the SSH agent.
export SSH_ASKPASS=${x11_ssh_askpass}/libexec/x11-ssh-askpass
eval $(${openssh}/bin/ssh-agent)
" else ""}
### Allow user to override system-wide configuration
if test -f ~/.xsession; then
source ~/.xsession;
fi
### Start a window manager.
${if windowManager == "twm" then "
${xorg.twm}/bin/twm &
"
else if windowManager == "metacity" then "
env LD_LIBRARY_PATH=${libX11}/lib:${libXext}/lib:/usr/lib/
# !!! Hack: load the schemas for Metacity.
GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \\
--makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas
${gnome.metacity}/bin/metacity &
"
else if windowManager == "kwm" then "
${kdebase}/bin/kwin &
"
else if windowManager == "compiz" then "
# !!! Hack: load the schemas for Compiz.
GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \\
--makefile-install-rule ${compiz}/etc/gconf/schemas/*.schemas
# !!! Hack: turn on most Compiz modules.
${gnome.GConf}/bin/gconftool-2 -t list --list-type=string \\
--set /apps/compiz/general/allscreens/options/active_plugins \\
[gconf,png,decoration,wobbly,fade,minimize,move,resize,cube,switcher,rotate,place,scale,water]
# Start Compiz and the GTK-style window decorator.
env LD_LIBRARY_PATH=${libX11}/lib:${libXext}/lib:/usr/lib/
${compiz}/bin/compiz gconf ${renderingFlag}&
${compiz}/bin/gtk-window-decorator --sync &
"
else if windowManager == "none" then "
# The session starter will start the window manager.
"
else abort ("unknown window manager " + windowManager)}
### Show a background image.
# (but not if we're starting a full desktop environment that does it for us)
${if sessionType != "kde" then "
if test -e $HOME/.background-image; then
${feh}/bin/feh --bg-scale $HOME/.background-image
fi
" else ""}
### Start the session.
${if sessionType == "kde" then "
# Start KDE.
export KDEDIRS=$HOME/.nix-profile:/nix/var/nix/profiles/default:${kdebase}:${kdelibs}
export XDG_CONFIG_DIRS=${kdebase}/etc/xdg:${kdelibs}/etc/xdg
export XDG_DATA_DIRS=${kdebase}/share
exec ${kdebase}/bin/startkde
" else "
# For all other session types, we currently just start a
# terminal of the kind indicated by sessionCmd.
# !!! yes, this means that you 'log out' by killing the X server.
while ${sessionCmd}; do
sleep 1
done
"}
"; # */ <- hack to fix syntax highlighting
xserverArgs = [
"-ac"
"-logverbose"
"-verbose"
"-terminate"
"-logfile" "/var/log/X.${toString display}.log"
"-config ${configFile}"
":${toString display}" "vt${toString tty}"
"-xkbdir" "${xkeyboard_config}/etc/X11/xkb"
] ++ (if ! config.services.xserver.tcpEnable
then ["-nolisten tcp"] else []);
# Note: lines must not be indented.
slimConfig = writeText "slim.cfg" "
xauth_path ${xorg.xauth}/bin/xauth
default_xserver ${xorg.xorgserver}/bin/X
xserver_arguments ${toString xserverArgs}
login_cmd exec ${stdenv.bash}/bin/sh ${clientScript}
";
# Unpack the SLiM theme, or use the default.
slimThemesDir =
let
unpackedTheme = stdenv.mkDerivation {
name = "slim-theme";
buildCommand = "
ensureDir $out
cd $out
unpackFile ${cfg.slim.theme}
ln -s * default
";
};
in if cfg.slim.theme == null then "${slim}/share/slim/themes" else unpackedTheme;
in
rec {
name = "xserver";
extraPath = [
xorg.xrandr
xorg.xrdb
xorg.setxkbmap
feh
]
++ optional (windowManager == "twm") [
xorg.twm
]
++ optional (windowManager == "metacity") [
gnome.metacity
]
++ optional (windowManager == "compiz") [
compiz
]
++ optional (sessionType == "xterm") [
xterm
]
++ optional (sessionType == "gnome") [
gnome.gnometerminal
gnome.GConf
gnome.gconfeditor
]
++ optional (sessionType == "kde") [
kdelibs
kdebase
xorg.iceauth # absolutely required by dcopserver
xorg.xset # used by startkde, non-essential
];
extraEtc =
optional (sessionType == "kde")
{ source = "${xkeyboard_config}/etc/X11/xkb";
target = "X11/xkb";
}
++
optional (exportConfiguration)
{
source = "${configFile}";
target = "X11/xorg.conf";
}
;
job = "
start on ${if autorun then "network-interfaces" else "never"}
start script
rm -f /var/run/opengl-driver
${if videoDriver == "nvidia"
then "ln -sf ${nvidiaDrivers} /var/run/opengl-driver"
else if cfg.driSupport
then "ln -sf ${mesa} /var/run/opengl-driver"
else ""
}
rm -f /var/log/slim.log
end script
env SLIM_CFGFILE=${slimConfig}
env SLIM_THEMESDIR=${slimThemesDir}
env FONTCONFIG_FILE=/etc/fonts/fonts.conf # !!! cleanup
env XKB_BINDIR=${xorg.xkbcomp}/bin # Needed for the Xkb extension.
env LD_LIBRARY_PATH=${libX11}/lib:${libXext}/lib:/usr/lib/ # related to xorg-sys-opengl - needed to load libglx for (AI)GLX support (for compiz)
${if videoDriver == "nvidia"
then "env XORG_DRI_DRIVER_PATH=${nvidiaDrivers}/X11R6/lib/modules/drivers/"
else if cfg.driSupport
then "env XORG_DRI_DRIVER_PATH=${mesa}/lib/modules/dri"
else ""
}
exec ${slim}/bin/slim
";
}