#!/bin/sh
#
# This is /usr/sbin/xserver-configure; it may be called on its own or from
# xserver-*.postinst.
#
# Copyright 1998, 1999 Branden Robinson.
# Licensed under the GNU General Public License, version 2.  See the file
# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
# Acknowlegements to Stephen Early and Mark Eichin.

set -e

checkconfig () {
# replace this with a decent config checker when we get one
  [ -e /etc/X11/XF86Config ];
}

parseans () {
  if [ -z "$1" ]; then
    echo $default
  else
    echo $1 | cut -c1 | tr '[A-Z]' '[a-z]'
  fi;
}

cleanup () {
  if [ $(echo /etc/X11/XF86Config.debian.$$.*) != "/etc/X11/XF86Config.debian.$$.*" ]; then
    rm /etc/X11/XF86Config.debian.$$.*
  fi;
}

trap "echo ;\
      echo 'Received signal.  Aborting.' ;\
      echo -n 'Cleaning up...' ;\
      cleanup ;\
      echo 'done.' ;\
      echo ;\
      exit 1" 1 2 3 15

# Rules:
# if the selected X server exists then
#   make sure /etc/X11/XF86Config exists; create if it doesn't

# Arguments:
# if '--remove' is supplied as $1 then never prompt the user [not implemented]
# if '--force' is supplied as $1 then perform configuration even if things look
#   all right

# Variables
#  boolean (null = false, non-null = true)
#    canconfig       archictecture has XF86Config generation tools
#    copyconfig      architecture has XF86Config.FBDev which is copied to
#                    /etc/X11/XF86Config (for fbdev-only arches: m68k, PowerPC, ... ?)
#    docopy          copy example XF86Config to /etc/X11/XF86Config
#    localfonts      local fonts are available
#    makedevmouse    remove and recreate /dev/mouse symlink on some arches
#    manglemouse     /dev/mouse is eligible for mangling
#    preserveconf    preserve existing XF86Config
#    realxserver     xserver is not "XF86_NONE"
#    sourced         are we being sourced by another script?
#    testconfig      user wants to test configuration file
#    usesetup        use XF86Setup program
#    xconfig         we should configure the X server
#    xconfigok       the configuration file is okay
#    xserverpresent  we have an executable X server
#  integer
#    count           loop counter for XF86Config configuration
#    xserverpid      process ID of X server being tested
#  string
#    answer          user response to prompts
#    arch            machine architecture
#    condecho        conditional echo; output formatting hack
#    fontdir         name of X font directory (for XF86Setup)
#    fontfile        name of X font alias or dir file (for XF86Setup)
#    machinemodel    model of machine (used for m68k and PowerPC mouse device detection)
#    oldpath         saved value of $PATH
#    serverpath      full path name of selected X server
#    servername      basename of serverpath

# condecho, count, amd command line args may be set from calling script

arch=$(dpkg --print-installation-architecture)

case "$arch" in
  alpha)
    canconfig=yes
    manglemouse=
    ;;
  arm)
    canconfig=
    manglemouse=
    ;;
  i386)
    canconfig=yes
    manglemouse=
    ;;
  m68k)
    canconfig=
    copyconfig=yes
    manglemouse=yes
    ;;
  powerpc)
    canconfig=
    copyconfig=yes
    manglemouse=yes
    ;;
  sparc)
    canconfig=
    manglemouse=
    ;;
  *)
    echo "Warning: xserver-configure encountered unknown architecture $arch."
    canconfig= ;;
esac

sourced=
if [ $(basename $0) != xserver-configure ]; then
  sourced=yes
fi

# set a sane $PATH and save the old one
oldpath=$PATH
PATH=/usr/sbin:/sbin:/usr/bin:/bin:/usr/bin/X11

xconfig=

# parse options
if [ "$1" ]; then
  case "$1" in
    --force) xconfig=yes ;;
  esac
fi

# do we have an X server?
if [ -f /etc/X11/Xserver ]; then
  serverpath=$(head -1 /etc/X11/Xserver)
else
  serverpath=/usr/bin/X11/XF86_NONE
fi

# migrate from older versions
if [ "$serverpath" = "/usr/X11R6/bin/XF86_NONE" ]; then
  serverpath=/usr/bin/X11/XF86_NONE
fi

realxserver=
if [ "$serverpath" != "/usr/bin/X11/XF86_NONE" ]; then
  realxserver=yes
fi

# $xserverpresent will be set if $realxserver is set, unless some yahoo
# made a /usr/bin/X11/XF86_NONE binary
xserverpresent=
if [ "$serverpath" ]; then
  if command -v "$serverpath" > /dev/null 2>&1; then
    xserverpresent=yes
  fi
fi

xconfigok=
servername=$(basename $serverpath)
if echo $servername | grep -q Xsun; then
  if [ "$xconfig" ]; then
    echo "The Xsun, XsunMono, and Xsun24 servers do not require configuration."
    xconfig=
  fi
else
  if checkconfig; then
    # if $xconfig is set then we're forcing a configuration run
    if [ -z "$xconfig" ]; then
      xconfigok=yes
    fi
  else
    xconfig=yes
  fi
fi

# /etc/X11/Xserver must be sane
if [ -z "$realxserver" ]; then
  ${condecho:=:}
  echo "The current X server is set to \"$serverpath\","
  echo "which means that no X server package has been installed.  Please install an X"
  echo "server package unless you do not intend to run any X sessions locally.  Most"
  echo "people will want an X server installed.  If you wish to run an X server for"
  echo "which there is no Debian package, edit the first line of /etc/X11/Xserver to"
  echo "contain the full pathname of the desired X server binary."
  condecho=echo
elif [ -z "$xserverpresent" ]; then
  $condecho
  echo "The desired X server, \"$serverpath\", was not found."
  echo "Please install an X server package unless you do not intend to run any X"
  echo "sessions locally.  Most people will want an X server installed.  If you wish"
  echo "to run an X server for which there is no Debian package, edit the first line"
  echo "of /etc/X11/Xserver to contain the full pathname of the desired X server"
  echo "binary."
  condecho=echo
fi

# if we have an X server, make sure it's configured

# XF86Config for arches that need an example file
if [ "$copyconfig" ]; then
  docopy=
  if [ -f /etc/X11/XF86Config ]; then
    echo "You already have an /etc/X11/XF86config file installed on your system."
    echo "This file may have been installed by a previous version of the X server,"
    echo -n "or generated by xf86config.  Do you want to replace it with a new copy? "
    default=n
    echo -n "(y|n) [$default] "
    condecho=echo
    read answer
    answer=$(parseans $answer)
    case "$answer" in
      y)
        docopy=yes
        echo -n "Saving current XF86Config in "
        echo "/etc/X11/XF86Config.debian.$$."
        condecho=echo
        mv /etc/X11/XF86Config /etc/X11/XF86Config.debian.$$.0
        ;;
      n) ;;
      *)
        echo "\"$answer\" not understood.  Using default of \"$default\"."
        ;;
    esac
  else
    docopy=yes
  fi
  if [ "$docopy" ]; then
    echo "Copying /usr/share/doc/xserver-fbdev/examples/XF86Config.FBDev to"
    echo "/etc/X11/XF86Config.  You will need to edit /etc/X11/XF86Config to verify that"
    echo "the mouse settings are correct, enable an appropriate XKB configuration for your"
    echo "machine (in the keyboard section), as well as change the default color depth (in"
    echo "the screen section) if you will not be using a 256-color display mode."
    cp /usr/share/doc/xserver-fbdev/examples/XF86Config.FBDev /etc/X11/XF86Config
  fi
fi

# mouse mangling
if [ "$manglemouse" ]; then
  # do we need to set a symlink for /dev/mouse?
  makedevmouse=
  if [ -e /dev/mouse ]; then
    echo "Mouse device /dev/mouse exists.  If your mouse does not work under X, you may"
    echo "remove it, and an attempt to auto-detect the proper device will be made."
    echo "Do you wish to remove the /dev/mouse device and re-create it based on your"
    echo -n "hardware? (y|n)"
    default=n
    echo -n " [$default] "
    condecho=echo
    read answer
    answer=$(parseans $answer)
    case "$answer" in
      y) makedevmouse=yes ;;
      n) ;;
      *) echo "\"$answer\" not understood.  Using default of \"$default\"." ;;
    esac
  else
    makedevmouse=yes
  fi
  if [ "$makedevmouse" ]; then
    case "$arch" in
      m68k)
        # When I was young and my heart was an open book, I thought awk was not Essential...
        # machinemodel=$(cat /proc/hardware | ( read line; set -- $line; if [ "$1" = "Model:" ]; then echo $2 ; fi ))
        machinemodel=$(awk '/Model:/ { print $2 }' < /proc/hardware)
        case "$machinemodel" in
          Amiga) ln -sf amigamouse /dev/mouse ;;
          Atari) ln -sf atarimouse /dev/mouse ;;
          Macintosh) ln -sf adbmouse /dev/mouse ;;
          Motorola|BVME4000|BVME6000) echo "Warning: $machinemodel machines have no supported mouse type." ;;
          *)
            echo "Warning: cannot auto-detect mouse; unknown model of Motorola m68k machine."
            echo "Please send mail to <debian-68k@lists.debian.org> describing your hardware." ;;
        esac ;;
      powerpc)
        machinemodel=$(awk '/^machine/ { print $3 }' < /proc/cpuinfo)
        case "$machinemodel" in
          Apus) ln -sf amigamouse /dev/mouse ;;
          CHRP|PReP) ln -sf psaux /dev/mouse ;;
          PowerMac|iMac*|[Pp]ower[Bb]ook*|Power) ln -sf adbmouse /dev/mouse ;;
          *)
            echo "Warning: cannot auto-detect mouse; unknown model of PowerPC machine.  Please"
            echo "send mail to <debian-powerpc@lists.debian.org> describing your hardware." ;;
        esac
    esac
  fi # makedevmouse
fi # manglemouse

if [ -n "$canconfig" -a -n "$xserverpresent" -a -n "$xconfig" ]; then
  $condecho
  default=y
  echo -n "Do you want to create the XFree86 configuration file? (y/n) [$default] "
  condecho=echo
  read answer
  answer=$(parseans $answer)
  case "$answer" in
    y) ;;
    n)
      $condecho
      echo "The XFree86 configuration file will not be created.  To create it later, run"
      echo "/usr/sbin/xserver-configure as root. Also see the xserver-configure(8) manual"
      echo "page (\"man xserver-configure\")."
      # set $xconfigok to yes so the while below falls through
      xconfigok=yes
      ;;
    *)
      echo "\"$answer\" not understood.  Using default of \"$default\"."
      ;;
  esac

  # if count is not set, intialize it to zero
  : ${count:=0}

  while [ -z "$xconfigok" ]; do
    # is there already an /etc/X11/XF86Config?
    if [ -f /etc/X11/XF86Config ]; then
        $condecho
# commented out until we have a decent config checker
#         if [ $count -eq 0 ]; then
#           echo "Checking existing /etc/X11/XF86Config for problems (E = error, W = warning,"
#         else
#           echo "Checking /etc/X11/XF86Config for problems (E = error, W = warning,"
#         fi
#         echo "A = advisory)..."
# place config checker here
#         if [ $? -eq 0 ]; then
#           echo "No problems found with the XFree86 configuration file."
#         fi
#         echo "If this file contains information you would like to preserve (modelines, for"
#         echo "example), it can be backed up, or you can quit now and leave the file as is."
        echo "If /etc/X11/XF86Config contains information you would like to preserve"
        echo "(modelines, for example), it can be backed up, or you can quit now and leave the"
        echo "file as is."
        echo
        default=y
        preserveconf=yes
      if [ $count -eq 0 ]; then
        echo -n "Preserve existing /etc/X11/XF86Config (quit keeps file)? (y/n/q) [$default] "
      else
        echo -n "Preserve /etc/X11/XF86Config just created (quit keeps file)? (y/n/q) [$default] "
      fi
      condecho=echo
      read answer
      answer=$(parseans $answer)
      case "$answer" in
      y) ;;
      n) preserveconf= ;;
      q) break ;;
      *)
        echo "\"$answer\" not understood.  Using default of \"$default\"."
        ;;
      esac
      if [ "$preserveconf" ]; then
        $condecho
        echo "Saving current XF86Config in /etc/X11/XF86Config.debian.$$.$count."
        condecho=echo
        mv /etc/X11/XF86Config /etc/X11/XF86Config.debian.$$.$count
      fi
    fi

    usesetup=yes
    localfonts=yes

    # X server will die if it can't find certain fonts
    # first set up font dirs in case the font postinsts have not run
    for fontdir in 100dpi 75dpi misc; do
      if [ -d /usr/lib/X11/fonts/$fontdir ]; then
        if [ ! -e /usr/lib/X11/fonts/$fontdir/fonts.alias ]; then
          if command -v update-fonts-alias > /dev/null 2>&1; then
            update-fonts-alias $fontdir || true
          fi
        fi
        if [ ! -e /usr/lib/X11/fonts/$fontdir/fonts.dir ]; then
          if command -v mkfontdir > /dev/null 2>&1; then
            mkfontdir /usr/lib/X11/fonts/$fontdir || true
          fi
        fi
      fi
    done

    # now see if the font situation is sane
    for fontfile in fonts.alias fonts.dir; do
       if [ -e /usr/lib/X11/fonts/misc/$fontfile ]; then
         if [ ! -e /usr/lib/X11/fonts/100dpi/$fontfile -o ! -e /usr/lib/X11/fonts/75dpi/$fontfile ]; then
           usesetup=
           localfonts=
         fi
       else
         usesetup=
         localfonts=
       fi
    done

    if command -v XF86Setup > /dev/null 2>&1; then
      # if we are not already in X, we must have the XF86_VGA16 server
      if [ -z "$DISPLAY" ]; then
        if ! command -v XF86_VGA16 > /dev/null 2>&1; then
          # VGA16 server was not found
          usesetup=
        fi
      fi
    else
      # XF86Setup itself was not found
      usesetup=
    fi

    if [ "$usesetup" ]; then
      # XF86Config, if it exists, was already backed up; we get rid of it
      # so the subsequent test will be useful
      if [ -e /etc/X11/XF86Config ]; then
        rm /etc/X11/XF86Config
      fi
      set +e
      # we cannot know if xlib6g's postinst has already been run
      LD_LIBRARY_PATH=/usr/X11R6/lib XF86Setup
      set -e
      echo
      if [ -f /etc/X11/XF86Config ]; then
        $condecho
        echo "The /etc/X11/XF86Config file was created."
        condecho=echo
        # done
        if checkconfig; then
          xconfigok=yes
        fi
      else
        $condecho
        echo "The /etc/X11/XF86Config file was not created."
        condecho=echo
        xconfigok=
      fi
    else
      if [ -x /usr/bin/X11/xf86config ]; then
        if /usr/bin/X11/xf86config; then
          $condecho
          echo "The XFree86 configuration file has been created."
          if [ -z "$localfonts" ]; then
            echo "Warning: no basic local X fonts were found; unless you have specified a remote"
            echo "font server in the configuration file, the X server will fail to operate."
          fi
          echo
          default=y
          echo -n "Do you want to test the configuration? (y/n) [$default] "
          testconfig=yes
          condecho=echo
          read answer
          answer=$(parseans $answer)
          case "$answer" in
            y) ;;
            n) testconfig= ;;
            *)
              echo "\"$answer\" not understood.  Using default of \"$default\"."
              ;;
          esac
          if [ "$testconfig" ]; then
            $condecho
            echo "The X server will start in 10 seconds.  If the configuration file is correct,"
            echo "you should see a gray patterned screen with an X-shaped cursor in the middle."
            echo " The mouse should move the cursor."
            echo
            echo "If the virtual screen resolution is higher than the actual resolution, you may"
            echo "not be able to see the cursor immediately.  It should become visible when you"
            echo "move the mouse."
            echo
            echo "This display should disappear after another 10 seconds; you will then be asked"
            echo "if the test worked."
            echo
            echo -n "Waiting 10 seconds before starting X server..."
            for countdown in $(seq 10 -1 1); do
              echo -n "$countdown "
              sleep 1
            done
            echo
            echo "Starting X server..."
            /usr/X11R6/bin/X &
            xserverpid=$!
            sleep 10
            set +e
            kill $!
            set -e
            sleep 3
            echo
            default=n
            echo -n "Did the X server work properly? (y/n) [$default] "
            xconfig=
            condecho=echo
            read prompt
            prompt=$(parseans $prompt)
            case "$prompt" in
              y) xconfigok=yes ;;
              n) ;;
              *)
                echo "\"$answer\" not understood.  Using default of \"$default\"."
                ;;
            esac
          else
            # user didn't want to test X server; assume the file is ok
            xconfigok=yes
          fi
        fi # if xf86config exited ok
      else
        echo "xf86config program not found.  Unable to configure X server."
      fi # if exist xf86config
    fi # if exist XF86Setup and XF86_VGA16
  count=$(expr $count + 1)
  done
fi

# offer to clean up those crufty files
if [ $(echo /etc/X11/XF86Config.debian.$$.*) != "/etc/X11/XF86Config.debian.$$.*" ]; then
  $condecho
  echo "Remove preserved XF86Config files generated in this session (files"
  echo "matching /etc/X11/XF86Config.debian.$$.* -- this will not remove the"
  echo -n "actual X server configuration file, /etc/X11/XF86Config)? "
  default=n
  echo -n "(y|n) [$default] "
  condecho=echo
  read answer
  answer=$(parseans $answer)
  case "$answer" in
    y) cleanup ;;
    n) ;;
    *)
      echo "\"$answer\" not understood.  Using default of \"$default\"."
      ;;
  esac
fi

# restore saved $PATH
PATH=$oldpath

if [ "$sourced" ]; then
  exit
fi
