postplug/postplug.d/30xorg

550 lines
19 KiB
Bash

#!/bin/bash
# xorg - xorg plugin for postplug
# Copyright (c) 2004-2012 by Silvan Calarco <silvan.calarco@mambasoft.it>
# Copyright (c) 2004-2007 by Davide Madrisan <davide.madrisan@gmail.com>
if [ $UID != 0 ]; then
echo "$0: must be superuser." >&2
exit 1
fi
[ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
[ -r /etc/sysconfig/postplug ] && . /etc/sysconfig/postplug
[ -r /etc/sysconfig/machine ] && . /etc/sysconfig/machine
me="xorg"
. /etc/postplug/postplug.defs
XORGCONF=/etc/X11/xorg.conf
kernel_min=$(uname -r | sed -e 's,[^\.]*\.,,' -e 's,\..*,,')
# xorg_section_screen_config()
# write a new xorg configuration
# args:
# $1 : default color depth
# $2 : file with the video modes (one per line)
function xorg_section_screen_config() {
# fixme: this deletes from first subsection "Display" to the endsection
sed '/SubSection "Display"/,/EndSection/s/.*//p' $XORGCONF | \
grep -v "^\s*$" > $XORGCONF.new
for i in `seq 1 ${#COLORDEPTHS[@]}`; do
echo -n "\
SubSection \"Display\"
Modes " >> $XORGCONF.new
grep "${COLORDEPTHS[$i-1]} bpp" $2 | tac | \
while read mode skip; do
echo -n "\"${mode%,*}\" " >> $XORGCONF.new
done
echo "
Depth ${COLORDEPTHS[$i-1]}
EndSubSection" >> $XORGCONF.new
done
echo "EndSection" >> $XORGCONF.new
mv $XORGCONF $XORGCONF.save
mv $XORGCONF.new $XORGCONF
}
# xorg_set_alternatives()
# set alternatives and xorg configuration for specific video drivers
function xorg_set_alternatives() {
if [ "$VIDEODRIVER" = "nvidia" ]; then
grep -q '^[^#]*\"AllowGLXWithComposite\"' $XORGCONF ||
sed -i -e '/Driver\W*"nvidia"/a\
Option \"RenderAccel\" \"true\"\
Option \"AllowGLXWithComposite\" \"on\"\
Option \"NoLogo\" \"true\"' $XORGCONF
# detect and update alternatives for nvidia driver
nvidia-autoselect-driver
elif [ "$VIDEODRIVER" = "fglrx" -o "$VIDEODRIVER" = "avivo" ]; then
# update alternatives for fglrx driver
/usr/sbin/update-alternatives --auto libglx.so || true
[ -x /usr/sbin/update-alternatives-set-fglrx ] && /usr/sbin/update-alternatives-set-fglrx
else
# set default alternatives
[ -x /usr/sbin/update-alternatives-set-dri ] && /usr/sbin/update-alternatives-set-dri
fi
}
# xorg_configure_loginmanager()
# configure inittab for runlelve 5 init and kdm as loginmanager
function xorg_configure_loginmanager() {
# login_manager configuration
[ ! "`grep "^x:5:" /etc/inittab`" ] && {
cat >> /etc/inittab << _EOF
# run graphical login manager
x:5:respawn:login_manager
_EOF
# configure kdm as the default login_manager if none is set
/usr/sbin/alternatives --display login_manager >/dev/null ||
/usr/sbin/alternatives --install /usr/sbin/login_manager login_manager /opt/kde/bin/kdm 20
telinit q
}
}
function xorg_d_configure_input() {
# Keyboard configuration (Xorg >= 1.8 uses /etc/X11/xorg.conf.d)
[ ! -e /etc/X11/xorg.conf.d/10-keyboard.conf -o \
/etc/sysconfig/keyboard -nt /etc/X11/xorg.conf.d/10-keyboard.conf ] && {
if [ ! "$XKB_MODEL" -o ! "$XKB_LAYOUT" ]; then
case "${LANG:0:2}" in
it)
# XKB_MODEL="pc105"
XKB_LAYOUT="it" ;;
de)
# XKB_MODEL="pc105"
XKB_LAYOUT="de" ;;
es)
# XKB_MODEL="pc105"
XKB_LAYOUT="es" ;;
fr)
# XKB_MODEL="pc105"
XKB_LAYOUT="fr" ;;
*)
# XKB_MODEL="pc104"
XKB_LAYOUT="us" ;;
esac
fi
cat > /etc/X11/xorg.conf.d/10-keyboard.conf << __EOF
Section "InputClass"
Identifier "Keyboard Defaults"
MatchIsKeyboard "on"
Driver "evdev"
Option "XkbLayout" "$XKB_LAYOUT"
__EOF
[ "$XKB_MODEL" ] && echo " Option \"XkbModel\" \"$XKB_MODEL\"" >>/etc/X11/xorg.conf.d/10-keyboard.conf
[ "$XKB_VARIANT" ] && echo " Option \"XkbVariant\" \"$XKB_VARIANT\"" >>/etc/X11/xorg.conf.d/10-keyboard.conf
[ "$XKB_OPTIONS" ] && echo " Option \"XkbOptions\" \"$XKB_OPTIONS\"" >>/etc/X11/xorg.conf.d/10-keyboard.conf
echo "EndSection" >>/etc/X11/xorg.conf.d/10-keyboard.conf
}
# configure keyboard options for Apple computers
if [ "${SYSTEM_MANUFACTURER:0:5}" = "Apple" ]; then
cat > /etc/X11/xorg.conf.d/15-keyboard-apple.conf << __EOF
Section "InputClass"
Identifier "Keyboard mac"
Driver "evdev"
Option "XkbOptions" ",lv3:rwin_switch" # Mac only
MatchIsKeyboard "on"
EndSection
__EOF
elif [ -e /etc/X11/xorg.conf.d/15-keyboard-apple.conf ]; then
rm -f /etc/X11/xorg.conf.d/15-keyboard-apple.conf
fi
[ ! -e /etc/X11/xorg.conf.d/20-synaptics.conf ] && {
cat > /etc/X11/xorg.conf.d/20-touchpad.conf << __EOF
Section "InputClass"
Identifier "touchpad defaults"
Driver "synaptics"
Option "RTCornerButton" "2"
Option "HorizEdgeScroll" "true"
Option "TapButton1" "1"
Option "TapButton2" "2"
Option "TapButton3" "3"
Option "HorizScrollDelta" "0"
MatchIsTouchpad "on"
EndSection
__EOF
}
}
# (re)create the '/tmp/.ICE-unix' directory with the right permissions
rm -fr /tmp/.ICE-unix
install -m 1777 -o root -g root -d /tmp/.ICE-unix
# video hardware change detection
if [ -e /dev/nvhost-ctrl ]; then
VIDEO_DEV="NVIDIA TEGRA"
else
VIDEO_DEV="`lspci -n 2>/dev/null | grep " 03[0-9][0-9]: "`"
fi
if [ -e $XORGCONF -a -e $postpluglibdir/xorg.cache ]; then
VIDEO_DEV_CACHED="`cat $postpluglibdir/xorg.cache`"
[ "$VIDEO_DEV" = "$VIDEO_DEV_CACHED" ] || {
logmsg "$me" "warning: video device appears to have changed; re-probing"
mv $XORGCONF $XORGCONF.postplug.save
}
fi
if [ -e $XORGCONF ]; then
VIDEODRIVERS=(`sed -n "/Section[ \t]\"Device\"/,/EndSection/{s/^[ \t]*Driver[ \t]*\"\(.*\)\"/\1/p}" $XORGCONF`)
# assume first driver as default videodriver
VIDEODRIVER=${VIDEODRIVERS[0]}
[ -e /sys/module/nouveau/parameters/modeset ] && NOUVEAU_MODESET=`cat /sys/module/nouveau/parameters/modeset`
[ -e /sys/module/radeon/parameters/modeset ] && RADEON_MODESET=`cat /sys/module/radeon/parameters/modeset`
if [ "$VIDEODRIVER" = "nvidia" -a "$NOUVEAU_MODESET" = "1" ]; then
# replace nvidia with nouveau
mv $XORGCONF $XORGCONF.postplug.nvidia.save
rmmod nvidia
echo "blacklist nvidia" > /etc/modprobe.d/postplug-nouveau.conf
elif [ "$VIDEODRIVER" = "nouveau" -a "$NOUVEAU_MODESET" != "1" ]; then
# replace nouveau with nvidia
mv $XORGCONF $XORGCONF.postplug.nouveau.save
rmmod nouveau
rm -f /etc/modprobe.d/postplug-nouveau.conf
elif [ "$VIDEODRIVER" = "fglrx" -a "$RADEON_MODESET" = "1" ]; then
# replace fglrx with radeon
mv $XORGCONF $XORGCONF.postplug.fglrx.save
rmmod fglrx
echo "blacklist fglrx" > /etc/modprobe.d/postplug-radeon.conf
elif [ "$VIDEODRIVER" = "radeon" -a "$RADEON_MODESET" != "1" ]; then
# replace radeon with fglrx
mv $XORGCONF $XORGCONF.postplug.radeon.save
rmmod radeon
rm -f /etc/modprobe.d/postplug-radeon.conf
fi
fi
if [ ! -e $XORGCONF ]; then
#
# Create a new Xorg configuration file
#
if [ -e /dev/nvhost-ctrl -a -e $XORGCONF.tegra ]; then
# use default xorg.conf for Tegra
cp $XORGCONF.tegra $XORGCONF
else
# fix set dri alternatives
xorg_set_alternatives
# ATI fglrx driver test workaround (Xorg -configure crashes with it)
# Note: assuming that fglrx loads if the video card is supported
let "ATI_DRV = 0"
[ "`/sbin/lsmod 2>/dev/null | grep ^fglrx `" ] && let "ATI_DRV = 1"
[ "$ATI_DRV" = "1" ] && VIDEODRIVER=ati
# remove any nvidia driver loaded as they don't load according to PCIID
[ "`/sbin/lsmod 2>/dev/null | grep ^nvidia `" ] && rmmod nvidia
# detect and configure nvidia driver
[ "$freevideo" ] || nvidia-autoselect-driver
# sync to avoid filesystem corruption in case of system hang on probe
sync
rm -f /tmp/xorg.conf.new
HOME=/tmp Xorg :5 -configure 2>>$logfile
RET=$?
if [ $RET -ne 0 -o ! -e /tmp/xorg.conf.new ]; then
logmsg "$me" "warning: xorg autoprobed configuration failed; using xorg autoconfig"
VIDEO_DEV="autoprobe"
echo "# Dummy empty xorg.conf file created by postplug" > $XORGCONF
xorg_configure_loginmanager
xorg_d_configure_input
exit 1
else
mv /tmp/xorg.conf.new $XORGCONF
sed -i "s|#DisplaySize|DisplaySize|" $XORGCONF
# disable autoconfigured multiple screens
sed -i "s|^\([[:space:]]*Screen[[:space:]]*[1-9].*\)|#\1|" $XORGCONF
fi
fi
let "CONFCREATED = 1"
fi
DISPLAYSIZE="`sed -n "/Section[ \t]\"Monitor\"/,/EndSection/{s/[ \t]*DisplaySize[ \t]*\(.*\)/\1/p}" $XORGCONF`"
VIDEODRIVERS=(`sed -n "/Section[ \t]\"Device\"/,/EndSection/{s/^[ \t]*Driver[ \t]*\"\(.*\)\"/\1/p}" $XORGCONF`)
# assume first driver as default videodriver
VIDEODRIVER=${VIDEODRIVERS[0]}
if [ "$CONFCREATED" = "1" ]; then
[ "`grep nomodeset /proc/cmdline`" ] && nomodeset=1
if [ "$nomodeset" = "1" -a "$VIDEODRIVER" = "nouveau" ]; then
sed -i "s|Driver\W*\"nouveau\"|Driver \"nvidia\"|" $XORGCONF
VIDEODRIVER=nvidia
xorg_set_alternatives
rmmod nouveau nvidia
fi
if [ "$ATI_DRV" = 1 -a ! "$freevideo" ]; then
sed -i -e '/Load\W*\"extmod\"/a\
SubSection "extmod"\
Option "omit xfree86-dga"\
EndSubSection' $XORGCONF
sed -i '/Load\W*\"extmod\"/d' $XORGCONF
sed -i "s|Driver\W*\"vesa\"|Driver \"fglrx\"|" $XORGCONF
sed -i "s|Driver\W*\"ati\"|Driver \"fglrx\"|" $XORGCONF
sed -i "s|Driver\W*\"avivo\"|Driver \"fglrx\"|" $XORGCONF
sed -i "s|Driver\W*\"radeon\"|Driver \"fglrx\"|" $XORGCONF
sed -i "s|Driver\W*\"radeonhd\"|Driver \"fglrx\"|" $XORGCONF
VIDEODRIVER=fglrx
xorg_set_alternatives
fi
# Setting video modes...
# get DCC values detected by xorg and verify that they have reasonable ranges
#HORIZSYNCMIN=(`grep "^# HorizSync.*" $XORGCONF | awk '{ print $3 }'`)
#HORIZSYNCMAX=(`grep "^# HorizSync.*" $XORGCONF | awk '{ print $5 }'`)
#unset reasonable
#for currsync in `seq 0 ${#HORIZSYNCMIN[@]}`; do
# if [ `expr "${HORIZSYNCMIN[$currsync]}" \> 15` = 1 -a \
# `expr "${HORIZSYNCMIN[$currsync]}" \< 100` = 0 -a \
# `expr "${HORIZSYNCMAX[$currsync]}" \> 30` = 1 -a \
# `expr "${HORIZSYNCMAX[$currsync]}" \< 201` = 0 -a \
# `expr "${HORIZSYNCMAX[$currsync]}" \>= "${HORIZSYNCMIN[$currsync]}"` = 1 ]; then
# reasonable=$currsync
# break
# fi
#done
#if [ "$reasonable" ]; then
# sed -i -e "/Section\W*\"Monitor\"/a\
# HorizSync ${HORIZSYNCMIN[$reasonable]}-${HORIZSYNCMAX[$reasonable]}" \
# $XORGCONF
#else
#if [ ! "$DISPLAYSIZE" ]; then
# sed -i -e '/Section\W*"Monitor"/a\
# DisplaySize 320 240' $XORGCONF
#fi
case "$VIDEODRIVER" in
vesa|vga) sed -i -e '/Section "Screen"/a\
#DefaultColorDepth 24' $XORGCONF ;;
*) sed -i -e '/Section "Screen"/a\
DefaultColorDepth 24' $XORGCONF ;;
esac
# NVIDIA Compiz/3d configuration options
if [ "$VIDEODRIVER" == "nvidia" ]; then
sed -i -e '/Section "Screen"/a\
Option "AddARGBGLXVisuals" "true"\
Option "DisableGLXRootClipping" "true"' $XORGCONF
fi
# Nouveau configuration options
if [ "$VIDEODRIVER" == "nouveau" ]; then
sed -i -e '/Driver.*"nouveau"/a\
Option "GLXVBlank" "true"' $XORGCONF
fi
# configure VirtualBox mouse driver
if [ "$VIDEODRIVER" = "vboxvideo" ]; then
sed -i "s|\"mouse\"|\"vboxmouse\"|" $XORGCONF
fi
# Configure fonts
sed -i '/fonts\/Type1/d;s@\(.*X11/fonts.*\)/@\1:unscaled@' $XORGCONF
fc-cache
# Configure keyboard
# NOTE:
# see: /etc/X11/xkb/README.config
# /usr/lib/X11/doc/README.XKB-Config
# The X Keyboard Extension: Protocol Specification
# <URL:http://www.x-docs.org/XKB/XKBproto.pdf>
# xkb configuration
# <URL:http://www.tsu.ru/~pascal/en/xkb>
#
# /etc/X11/xkb/rules/xfree86.lst (commonest file of rules)
#
# The parameters are:
# XkbRules - files of rules to be used for keyboard mapping composition
# XkbModel - name of model of your keyboard type
# XkbLayout - layout(s) you intend to use
# XkbVariant - variant(s) of layout you intend to use
# XkbOptions - extra xkb configuration options
#
# XkbVariant has been left out: that means the default variant named basic is loaded.
if [ ! "$XKB_MODEL" -o ! "$XKB_LAYOUT" ]; then
case "${LANG:0:2}" in
it)
XKB_MODEL="pc105"
XKB_LAYOUT="it" ;;
de)
XKB_MODEL="pc105"
XKB_LAYOUT="de" ;;
es)
XKB_MODEL="pc105"
XKB_LAYOUT="es" ;;
fr)
XKB_MODEL="pc105"
XKB_LAYOUT="fr" ;;
*)
XKB_MODEL="pc104"
XKB_LAYOUT="us" ;;
esac
fi
if [ -n "XKbOptions" ]; then
sed -i -e "/Identifier\W*\"Keyboard.*\"/a\\
Option \"XkbModel\" \"$XKB_MODEL\"\\
Option \"XkbLayout\" \"$XKB_LAYOUT\"\\
Option \"XKbOptions\" \"$XKB_OPTIONS\"" $XORGCONF
else
sed -i -e "/Identifier\W*\"Keyboard.*\"/a\\
Option \"XkbModel\" \"$XKB_MODEL\"\\
Option \"XkbLayout\" \"$XKB_LAYOUT\"" $XORGCONF
fi
# global mouse modifications to default configuration
sed -i -e '/"CorePointer"/i \
Option "AllowMouseOpenFail"' $XORGCONF
# echo "$XORGCONF" > $postplugnew_file
xorg_set_alternatives
# Final probe
[ -f /var/log/Xorg.5.log ] && rm -f /var/log/Xorg.5.log
# sync to avoid filesystem corruption in case of system hang on probe
sync
xinit /bin/true -- :5 2>>$logfile
if [ -r /var/log/Xorg.5.log ]; then
if [ "`grep '\[KMS\] Kernel modesetting enabled' /var/log/Xorg.5.log`" ]; then
logmsg "$me" "info: "$"KMS enabled: assuming autodetect works for PANEL_SIZE and HSYNC_RANGE"
PANEL_SIZE_DETECTED="true"
HSYNC_RANGE_NOT_DETECTED=""
else
if [ "`grep 'hsync range of 28.00-33.00 kHz' /var/log/Xorg.5.log`" -o \
"`grep 'The EDID read for display device CRT-0 is invalid' /var/log/Xorg.5.log`" ]; then
# no values could be autodetected by DDC, so use a failsafe low value (30-49)
HSYNC_RANGE_NOT_DETECTED="true"
fi
[ "`grep 'Printing DDC gathered Modelines' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'EDID vendor \"' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'Adding EDID-provided mode' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep -i 'Panel size from' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep -i 'Panel size is' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep -i 'Panel Size ' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'VESA VBE DDC read successfully' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'LCD on internal LVDS' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'LCD on internal LVDS' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "`grep 'LVDS.* using initial mode' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
# nvidia driver: CRT-. EDID not got?
if [ "`grep 'Unable to read EDID for display device CRT-.' /var/log/Xorg.5.log`" -o \
"`grep 'Unable to get display device CRT-..s EDID' /var/log/Xorg.5.log`" ]; then
# nvidia driver: disable CRT-x from being used by default if DFP-0 is present
[ "`grep 'DFP-0' /var/log/Xorg.5.log`" ] && {
sed -i -e '/Section "Screen"/a\
Option "ConnectedMonitor" "DFP"' $XORGCONF
} || {
HSYNC_RANGE_NOT_DETECTED="true"
unset PANEL_SIZE_DETECTED
}
else
# nvidia driver: we trust in nvidia-auto-select
[ "`grep 'nvidia-auto-select' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
fi
# fglrx driver
[ "`grep 'EDID Version:' /var/log/Xorg.5.log`" ] && PANEL_SIZE_DETECTED="true"
[ "$autoresvideo" ] && PANEL_SIZE_DETECTED="true"
fi
[ "$XORG_DETECT_SCREEN_SIZE" = off -o "$lowresvideo" ] && unset PANEL_SIZE_DETECTED
[ "$HSYNC_RANGE_NOT_DETECTED" ] && {
logmsg "$me" "\
warning: DDC hsync range cannot be detected, setting default of 30-49 kHz"
sed -i -e '/Section\W*"Monitor"/a\
HorizSync 30-49' $XORGCONF
}
[ "$PANEL_SIZE_DETECTED" ] ||
sed -i -e '/SubSection "Display"/a\
Modes "1024x768" "800x600" "640x480"' $XORGCONF
else
logmsg "$me" "warning: "$"Xorg probe failed!"
fi
fi
####################################
#
# Xorg dynamic configuration section
#
####################################
[ -e $XORGCONF ] || {
logmsg "$me" "error: "$"missing Xorg configuration file; aborting"
exit 1
}
# configure inittab for login manager
xorg_configure_loginmanager
# add missing brackets to Xorg.conf device entries
sed -i "s|^[ \t]*Driver[ \t]*\([A-Za-z0-9]*\)[ \t]*$| Driver \"\1\"|g" $XORGCONF
# add 'Section "DRI"' if not present...
if [ "$XORG_ENABLE_DRI" = "on" ]; then
grep -q 'Section "DRI"' $XORGCONF
[ $? -eq 1 ] && echo "
Section \"DRI\"
Mode 0666
EndSection" >> $XORGCONF
fi
# enable 'Composite' extensions if not present...
if [[ "$XORG_ENABLE_COMPOSITE_EXT" = "on" ]]; then
grep -q 'Section "Extensions"' $XORGCONF
[ $? -eq 1 ] && echo "
Section \"Extensions\"
Option \"Composite\" \"true\"
EndSection" >> $XORGCONF
fi
# set alternative configuration for different video drivers
xorg_set_alternatives
# Configure Mice...
# remove wrong configuration for USBMouse (duplicating PS2MOUSE)
sed -i "/[\W]*InputDevice[\W]*"USBMouse".*/d" $XORGCONF
# remove obsolete input pointers configuration (since xorg-server 1.7)
sed -i "/[[:space:]]*InputDevice[[:space:]]*.*PS2Mouse.*/d; \
/[[:space:]]*InputDevice[[:space:]]*.*Synaptics.*/d; \
/[[:space:]]*InputDevice[[:space:]]*.*Alps.*/d" $XORGCONF
# remove all devices set
sed -i "/\W*Option \"Device\".*/d" $XORGCONF
# remove obsoleted XAANoOffscreenPixmaps
sed -i '/^[[:space:]]*Option[[:space:]]*"XAANoOffscreenPixmaps" "true"/d' $XORGCONF
# Configure keyboard
xorg_d_configure_input
# disable keyboard configuration for Xorg >= 1.4
sed -i "s|^\([[:space:]]*InputDevice\W*\"Keyboard0\".*\)|#\1|" $XORGCONF
# FIXME: delete empty lines
sed -i '/./,$!d' $XORGCONF
[ "$CONFCREATED" = "1" -o ! -e $postpluglibdir/xorg.cache ] && \
echo "$VIDEO_DEV" > $postpluglibdir/xorg.cache
exit 0