#!/bin/bash

PATH="/bin:/usr/bin:/sbin:/usr/sbin"; export PATH
umask 022

# [ "`id -u`" != "0" ] && echo "WARNING: $0 has to run as root to work properly." 1>&2

# ANSI COLORS
CRE="
[K"
NORMAL="[0;39m"
# RED: Failure or error message
RED="[1;31m"
# GREEN: Success message
GREEN="[1;32m"
# YELLOW: Descriptions
YELLOW="[1;33m"
# BLUE: System messages
BLUE="[1;34m"
# MAGENTA: Found devices or drivers
MAGENTA="[1;35m"
# CYAN: Questions
CYAN="[1;36m"
# BOLD WHITE: Hint
WHITE="[1;37m"

TMPFILE="/tmp/mkxf86config-$$"
MONITORTMP="$TMPFILE-monitor"

rm -f "$TMPFILE" "$MONITORTMP"

### Utility Function(s)
# Reread boot command line; echo last parameter's argument or return false.
CMDLINE="$(cat /proc/cmdline)"

getbootparam(){
case "$CMDLINE" in *$1=*) ;; *) return 1; ;; esac
result="${CMDLINE##*$1=}"
result="${result%%[     ]*}"
echo "$result"
return 0
}

checkbootparam(){
case "$CMDLINE" in *$1*) return 0;; esac
return 1
}

# Read in what hwsetup has found for X
[ -f /etc/sysconfig/xserver ] && . /etc/sysconfig/xserver

# Xserver, Xmodule, Xscreen, Xvrefresh, if specified by commandline
NEWXSERVER="$(getbootparam xserver 2>/dev/null)"
[ -z "$XSERVER" -a -z "$NEWXSERVER" ] && NEWXSERVER="XFree86"
[ -n "$NEWXSERVER" ] && { XSERVER="$NEWXSERVER" ; echo "XSERVER='$XSERVER'" >> /etc/sysconfig/knoppix ; echo "XSERVER='$XSERVER'" >> /etc/sysconfig/xserver; }
NEWXMODULE="$(getbootparam xmodule 2>/dev/null)"
[ -z "$XMODULE" -a -z "$NEWXMODULE" ] && NEWXMODULE="vesa"
[ -n "$NEWXMODULE" ] && { XMODULE="$NEWXMODULE" ; echo "XMODULE='$XMODULE'" >> /etc/sysconfig/knoppix ; echo "XMODULE='$XMODULE'" >> /etc/sysconfig/xserver; }
XSCREEN="$(getbootparam xscreen 2>/dev/null)"
[ -z "$XSCREEN" ] && XSCREEN="$(getbootparam screen 2>/dev/null)"
[ -n "$XSCREEN" ] && { echo "XSCREEN='$XSCREEN'" >> /etc/sysconfig/knoppix ; echo "XSCREEN='$XSCREEN'" >> /etc/sysconfig/xserver; }
XVREFRESH="$(getbootparam xvrefresh 2>/dev/null)"
[ -n "$XVREFRESH" ] || XVREFRESH="$(getbootparam vrefresh 2>/dev/null)"
[ -n "$XVREFRESH" ] || XVREFRESH="$(getbootparam xvsync 2>/dev/null)"
[ -n "$XVREFRESH" ] || XVREFRESH="$(getbootparam vsync 2>/dev/null)"
[ -n "$XVREFRESH" ] && { echo "XVREFRESH='$XVREFRESH'" >> /etc/sysconfig/knoppix ; echo "XVREFRESH='$XVREFRESH'" >> /etc/sysconfig/xserver; }
XDEPTH="$(getbootparam xdepth 2>/dev/null)"
[ -n "$XDEPTH" ] || XDEPTH="$(getbootparam depth 2>/dev/null)"
[ -n "$XDEPTH" ] && { echo "XDEPTH='$XDEPTH'" >> /etc/sysconfig/knoppix ; echo "XDEPTH='$XDEPTH'" >> /etc/sysconfig/xserver; }
# Wheel
WHEEL=""
checkbootparam "wheel" && WHEEL='s|"PS/2"|"IMPS/2"\
Option          "ZAxisMapping"          "4 5"|g;'

# Read in changes
[ -f /etc/sysconfig/knoppix ] && . /etc/sysconfig/knoppix

# Read default keyboard from config file.
# There seems to be no reliable autoprobe possible.
[ -f /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard

# Create mouse link and insert a mouse default type into XF86Config
# if not already done by hwsetup
[ -f /etc/sysconfig/mouse ] && . /etc/sysconfig/mouse
[ -e /dev/mouse ] || ln -sf /dev/ttyS0 /dev/mouse
# PROTO="${XMOUSETYPE:-Auto}"
PROTO="${XMOUSETYPE:-Microsoft}"
NOEMU=""
[ "${XEMU3}" = "no" ] && NOEMU='s|^.*Emulate3|# No 2 -> 3 Button emulation|g'
DEADKEYS=""
[ "$XKEYBOARD" = "de" ] || DEADKEYS='s|^.*nodeadkeys.*$||g;'
if [ -n "XMODULE" ]; then
# Check for Framebuffer X-Modules and initialize framebuffer module
case "$XMODULE" in
pvr2fb) modprobe "$XMODULE" >/dev/null 2>&1 ; XMODULE="fbdev"; ;;
esac
fi

# Try to get Monitor data via kudzu ddcxinfo


MONITOROK=""
MODEL="$(ddcprobe 2>/dev/null | awk 'BEGIN{m="Generic";i="Monitor"}/^Manufacturer:/{m=$2};/^ID:/{i=$2};END{print m " "i}')"
HREFRESH="$(ddcxinfo -hsync 2>/dev/null)"
VREFRESH="$(ddcxinfo -vsync 2>/dev/null)"
MODELINES="$(ddcxinfo -modelines 2>/dev/null)"
DEFAULTMODES='"1024x768" "800x600" "640x480"'
MODES="Modes $DEFAULTMODES"
MINHREFRESH=""
MAXHREFRESH=""
MINVREFRESH=""
MAXVREFRESH=""

# Check values
cat >"$MONITORTMP" <<EOF
$MODELINES
EOF
while read a b c; do
 case "$a" in ModeLine)   NEWMODES="$NEWMODES $b"; ;; esac
done < "$MONITORTMP"
rm -f "$MONITORTMP"
TFT=""
case "$MODEL" in *[Ll][Cc][Dd]*|*[Tt][Ff][Tt]*) TFT="true"; ;; esac
MINHREFRESH="${HREFRESH%%-*}"
MAXHREFRESH="${HREFRESH##*-}"
MINVREFRESH="${VREFRESH%%-*}"
MAXVREFRESH="${VREFRESH##*-}"
# Up to version 12-02-2002, settings like minhsync=maxhsync were allowed.
# This does not seem to work , the DDC probings are simply wrong.
# So, now -le has been changed to -lt
if [ -n "$NEWMODES" -a -n "$MINHREFRESH" -a -n "$MAXHREFRESH" -a \
     -n "$MINVREFRESH" -a -n "$MAXVREFRESH" -a \
     "$MINHREFRESH" -ge 25 -a "$MAXHREFRESH" -le 220 -a \
     "$MINHREFRESH" -lt "$MAXHREFRESH" -a \
     "$MINVREFRESH" -ge 35 -a "$MAXVREFRESH" -le 200 -a \
     "$MINVREFRESH" -lt "$MAXVREFRESH" ] 2>/dev/null ; then
  ADDMODES=""
  # These settigs are probably wrong.
  [ "$MINHREFRESH" -eq "$MAXHREFRESH" ] 2>/dev/null && MINHREFRESH="$(($MINHREFRESH - 5))"
  [ "$MINVREFRESH" -eq "$MAXVREFRESH" ] 2>/dev/null && MINVREFRESH="$(($MINVREFRESH - 5))"
  for i in $NEWMODES; do
   tmp="${i#*\"}"
   hmode="${tmp%%x*}"
   tmp="${tmp##*x}"
   vmode="${tmp%%\"*}"
   # Filter invalid modes like "1x1"
   [ -n "$hmode" -a -n "$vmode" -a "$hmode" -ge 320 -a "$vmode" -ge 200 ] 2>/dev/null || continue
   # For now, restrict "normal" monitors to a maximum of 1024x768
   [ -z "$TFT" -a "$hmode" -gt 1024 ] 2>/dev/null && continue
   ADDMODES="$ADDMODES $i"
   [ "$hmode" -gt 1800 ] 2>/dev/null && ADDMODES="$ADDMODES "'"1800x1440"' # Add additional fallback mode
   [ "$hmode" -gt 1600 ] 2>/dev/null && ADDMODES="$ADDMODES "'"1600x1200"' # Add additional fallback mode
   [ "$hmode" -gt 1280 ] 2>/dev/null && ADDMODES="$ADDMODES "'"1280x1024"' # Add additional fallback mode
   [ "$hmode" -gt 1152 ] 2>/dev/null && ADDMODES="$ADDMODES "'"1152x864"'  # Add additional fallback mode
   [ "$hmode" -gt 1024 ] 2>/dev/null && ADDMODES="$ADDMODES "'"1024x768"'  # Add additional fallback mode
  done

  if [ -n "$ADDMODES" ]; then
   # Sort modes
   ADDMODES=$(for i in $ADDMODES; do echo "$i"; done | sort -n +0.1 -r | uniq)
   MODES="Modes $(echo $ADDMODES)"
  else
   MODES="Modes $DEFAULTMODES"
  fi

  # Everything should be OK now.
  MONITOROK="yes"
 else
 HREFRESH=""
 VREFRESH=""
 fi

if [ -n "$MONITOROK" ]; then
cat >"$MONITORTMP" <<EOF
Section "Monitor"
	Identifier   "Monitor0"
	ModelName    "$MODEL"
# These are the DDC-probed settings and modelines
	HorizSync    $HREFRESH
	VertRefresh  $VREFRESH
$MODELINES
EndSection
EOF
else
cat >"$MONITORTMP" <<EOF
Section "Monitor"
	Identifier   "Monitor0"
# Wish we could use some probed settings here, too, but XFree4 cannot do this yet.
#	HorizSync    28.0 - 78.0 # Warning: This may fry very old Monitors
	HorizSync    28.0 - 96.0 # Warning: This may fry old Monitors
	VertRefresh  50.0 - 76.0 # Very conservative. May flicker.
# These are some Modelines that happen to work on many systems
# Especially the "1024x768" has been thoroughly tested, even on Laptops
	Modeline "640x480"     25.175 640  664  760  800   480  491  493  525 #60Hz
	Modeline "800x600"     40.12  800  848  968 1056   600  601  605  628 #60Hz
	Modeline "1024x768"    85    1024 1056 1152 1360   768  784  787  823
	Modeline "1152x864"    92    1152 1208 1368 1474   864  865  875  895
	Modeline "1152x864"   110    1152 1240 1324 1552   864  864  876  908
	Modeline "1152x864"   135    1152 1464 1592 1776   864  864  876  908
	Modeline "1152x864"   137.65 1152 1184 1312 1536   864  866  885  902 -HSync -VSync
	Modeline "1280x1024"   80    1280 1296 1512 1568  1024 1025 1037 1165 Interlace
	Modeline "1280x1024"  110    1280 1328 1512 1712  1024 1025 1028 1054
	Modeline "1280x1024"  126.5  1280 1312 1472 1696  1024 1032 1040 1068 -HSync -VSync
	Modeline "1280x1024"  135    1280 1312 1456 1712  1024 1027 1030 1064
	Modeline "1280x1024"  135    1280 1312 1416 1664  1024 1027 1030 1064
	Modeline "1280x1024"  157.5  1280 1344 1504 1728  1024 1025 1028 1072 +HSync +VSync
	Modeline "1280x1024"  181.75 1280 1312 1440 1696  1024 1031 1046 1072 -HSync -VSync
	Modeline "1600x1200"  162    1600 1664 1856 2160  1200 1201 1204 1250 +HSync +VSync
	Modeline "1600x1200"  189    1600 1664 1856 2160  1200 1201 1204 1250 -HSync -VSync
	Modeline "1600x1200"  202.5  1600 1664 1856 2160  1200 1201 1204 1250 +HSync +VSync
	Modeline "1600x1200"  220    1600 1616 1808 2080  1200 1204 1207 1244 +HSync +VSync
	ModeLine "1800x1440"  230    1800 1896 2088 2392  1440 1441 1444 1490 +HSync +VSync
	ModeLine "1800x1440"  250    1800 1896 2088 2392  1440 1441 1444 1490 +HSync +VSync
EndSection
EOF
MODES="Modes $DEFAULTMODES"
fi

# Use commandline modes if specified
[ -n "$XSCREEN" ] && MODES='Modes "'"$XSCREEN"'"'

# Use commandline vertical refresh rate if specified
if [ -n "$XVREFRESH" ]; then
sed 's|VertRefresh .*$|VertRefresh 49.0 - '"$XVREFRESH"'|g;' "$MONITORTMP" > "$TMPFILE"
mv -f "$TMPFILE" "$MONITORTMP"
fi

DEPTH=""
# Use commandline colordepth if specified
if [ -n "$XDEPTH" ]; then
DEPTH='s|DefaultColorDepth .*$|DefaultColorDepth '"$XDEPTH"'|g;'
fi

# We need to check this because serial mice have long timeouts
SERIALMOUSE="$(ls -l1 /dev/mouse* 2>/dev/null | awk '/ttyS/{print $NF ; exit 0}')"
if [ -n "$SERIALMOUSE" ]; then
SERIALMOUSE="s|/dev/ttyS0|$SERIALMOUSE|g;"
else
SERIALMOUSE='s|^.*InputDevice.*"Serial Mouse".*$|# Serial Mouse not detected|g;'
fi

# PS/2 bug: Some keyboards are incorrectly used as mice in XFree. :-(
PSMOUSE="$(ls -l1 /dev/mouse* 2>/dev/null | awk '/psaux/{print $NF ; exit 0}')"
if [ -n "$PSMOUSE" ]; then
PSMOUSE=""
else
PSMOUSE='s|^.*InputDevice.*"PS/2 Mouse".*$|# PS/2 Mouse not detected|g;'
fi

USBMOUSE="$(ls -l1 /dev/mouse* 2>/dev/null | awk '/input/{print $NF ; exit 0}')"
if [ -n "$USBMOUSE" ]; then
USBMOUSE=""
else
USBMOUSE='s|^.*InputDevice.*"USB Mouse".*$|# USB Mouse not detected|g;'
fi

# /etc/X11/XF86Config* is the "default" config.
if [ ! -f /etc/XF86Config -a ! -f /etc/X11/XF86Config ]; then
# Remove it, just in case it's a link to CD
rm -f /etc/XF86Config /etc/X11/XF86Config 2>/dev/null
sed -e 's|@@PROTOCOL@@|'"$PROTO"'|g;'"$NOEMU" \
    -e '/@@MONITOR@@/r '"$MONITORTMP" \
    -e 's|@@MONITOR@@||g' \
    -e 's|@@MODES@@|'"$MODES"'|g;'"$DEPTH" \
    -e 's|XkbLayout *"[^"]*"|XkbLayout "'"$XKEYBOARD"'"|g;'"$DEADKEYS" \
    /etc/X11/XF86Config.in > /etc/X11/XF86Config
fi

# K.Wonderboy :0.98
diff -q /etc/sysconfig/xserver /etc/sysconfig/xserver.kwb >/dev/null
if [ "$?" != "0" ]
then
cp -af /etc/sysconfig/xserver /etc/sysconfig/xserver.kwb
echo "  ${MAGENTA}Found New VGA Card. auto-configuration start...${NORMAL}"
rm -f /etc/XF86Config-4 /etc/X11/XF86Config-4 2>/dev/null
fi
# K.Wonderboy :0.98

if [ ! -f /etc/XF86Config-4 -a ! -f /etc/X11/XF86Config-4 ]; then 
rm -f /etc/XF86Config-4 /etc/X11/XF86Config-4 2>/dev/null

# VMWare special handling
VMWARE=""
if [ "$XMODULE" = "vmware" ]; then
VMWARE='s|^.*BusID.*PCI.*$|BusID "PCI:0:15:0"|g;'
DEPTH='s|DefaultColorDepth |# DefaultColorDepth |g;'
fi

# These drivers need the sw_cursor option
SWCURSOR=""
case "$XMODULE" in ati|radeon|trident) SWCURSOR='s|^.*#Option.*"sw_cursor".*$|Option "sw_cursor"|g;';; esac

sed -e 's|@@PROTOCOL@@|'"$PROTO"'|g;'"$NOEMU" \
    -e '/@@MONITOR@@/r '"$MONITORTMP" \
    -e 's|@@MONITOR@@||g' \
    -e 's|Identifier  *"Monitor0"|Identifier   "Monitor0"\
Option "DPMS"|g' \
    -e 's|@@XMODULE@@|'"$XMODULE"'|g;'"$VMWARE""$SERIALMOUSE""$USBMOUSE""$PSMOUSE""$SWCURSOR""$WHEEL" \
    -e 's|@@MODES@@|'"$MODES"'|g;'"$DEPTH" \
    -e 's|"XkbLayout" *"[^"]*"|"XkbLayout" "'"$XKEYBOARD"'"|g;'"$DEADKEYS" \
    /etc/X11/XF86Config-4.in > /etc/X11/XF86Config-4
fi

rm -f "$TMPFILE" "$MONITORTMP" 2>/dev/null

# Print info about selected X-Server
[ -n "$XDESC" ] || XDESC="(yet) unknown card"
echo -n " ${GREEN}Video is"
[ -n "$XDESC" ] && echo -n " ${YELLOW}$XDESC${GREEN},"
echo -n " using ${YELLOW}${XSERVER:-generic VESA}"
[ -n "$XMODULE" ] && echo -n "(${MAGENTA}$XMODULE${YELLOW})"
echo " Server${NORMAL}"
echo -n " ${GREEN}Monitor is ${YELLOW}${MODEL:-Generic Monitor}${NORMAL}"
[ -n "$HREFRESH" -a -n "$VREFRESH" ] && echo "${GREEN}, ${GREEN}H:${YELLOW}${HREFRESH}kHz${GREEN}, V:${YELLOW}${VREFRESH}Hz${NORMAL}" || echo ""
[ -n "$XVREFRESH" ] && echo " ${GREEN}Trying specified vrefresh rate of ${YELLOW}${XVREFRESH}Hz.${NORMAL}"
[ -n "$MODES" ] && echo " ${GREEN}Using Modes ${YELLOW}${MODES##Modes }${NORMAL}"
