#!/bin/bash

set -e
if [ -n "$MULTISEATDEBUG" ]; then
  set -x
fi

if [ ! -e /etc/multiseat.conf ]; then
  exit 0
fi

# source debconf library
. /usr/share/debconf/confmodule

## stolen from xserver-xorg.config.in

validate_numeric_db_input () {
  # Syntax: validate_numeric_db_input priority template
  #
  # validate numeric input; must have only digits, can be null
  if [ $# -ne 2 ]; then
    echo "internal error: validate_numeric_db_input() called with wrong number of arguments: $*" >&2
    exit 1
  fi
  PRIORITY=$1
  TEMPLATE=$2
  db_get "$TEMPLATE"
  SAFE="$RET"
  set +e
  while :; do
    db_input "$PRIORITY" "$TEMPLATE"
    # is the question going to be asked?
    if [ $? -eq 30 ]; then
      break # no; bail out of validation loop
    fi
    db_go
    db_get "$TEMPLATE"
    if [ -z "$RET" ] || expr "$RET" : "[0-9]\+$" > /dev/null 2>&1; then
      break # valid input
    fi
    # we only get to this point if the input was invalid; restore the known
    # good value in case we are interrupted before the user provides a valid
    # one
    db_set "$TEMPLATE" "$SAFE"
    db_fset "$TEMPLATE" seen false
    # now show the user the error message
    db_fset xserver-xorg/config/nonnumeric_string_error seen false
    db_input critical xserver-xorg/config/nonnumeric_string_error
    db_go
  done
  set -e
}

## stolen from nvidia-glx-config

manage_kernel_driver() {
  tmpfile=$(tempfile)
  chmod 644 $tmpfile
  driver="nvidia"
  modprobe nvidia > /dev/null 2>&1
  if [ -z "$(cat /proc/modules | awk '{print $1}' | grep ^nvidia$)" ]; then
    driver="nv"
  fi
  if ! grep -Eq '^nvidia$' /etc/modules && ! grep -Eq '^# nvidia$' /etc/modules; then
    echo nvidia >> /etc/modules
  elif grep -Eq '^# nvidia$' /etc/modules; then
    cat /etc/modules | sed -e 's/^# nvidia$/nvidia/g' > $tmpfile
    mv $tmpfile /etc/modules
  fi
  rm -f $tmpfile
  echo "$driver"
}

## stolen from dexconf

list_convert () {
  echo $(IFS=", "; set -- $RET; while [ $# -gt 0 ]; do echo \"$1\"; shift; done)
}

# generate X config file
generate_x_config () {
# get the video driver information first to enable/disable nvidia.
db_get xserver-xorg/config/device/driver
driver="$RET"
if [ "$driver" = "nv" ] || [ "$driver" = "nvidia" ]; then
  driver="$(manage_kernel_driver)"
fi

tmpfile=$(tempfile)
heads=$(lspci -nX | grep " 0300" |sed -e 's/ 0300.*//g')
j=0
agpbusid=""
for i in $(seq 0 $numheads); do
  realpci=$(expr $i + 1)
  busid="$(echo "$heads" | grep -n PCI | grep ^$realpci | sed -e 's/^'$realpci:'//g')"
  # special-case primary card -- it must come last.  guess based on the bus
  # type right now.
  PCIBUSTYPE="$(/usr/lib/multiseat/pcibustype "$busid" || true)"
  if [ "$PCIBUSTYPE" = "agp" ] || [ "$PCIBUSTYPE" = "pcie" ]; then
    agpbusid="$busid"
    agpkb="${keyboard[$i]}"
    agpmouse="${mouse[$i]}"
  else
    pcibusid[$j]="$busid"
    realkeyboard[$j]="${keyboard[$i]}"
    realmouse[$j]="${mouse[$i]}"
    j=$(expr $j + 1)
  fi
done

if [ -n "$agpbusid" ]; then
  pcibusid[$j]="$agpbusid"
  realkeyboard[$j]="$agpkb"
  realmouse[$j]="$agpmouse"
fi

cat > "$tmpfile" <<EOF
# /etc/X11/xorg.conf (xorg X Window System server configuration file)
#
# Edit this file with caution, and see the /etc/X11/xorg.conf manual page.
# (Type "man /etc/X11/xorg.conf" at the shell prompt.)
#
# Use dpkg-reconfigure multiseat to regenerate this file.

Section "Files"
	FontPath	"unix/:7100"			# local font server
	# if the local font server has problems, we can fall back on these
	FontPath	"/usr/lib/X11/fonts/misc"
	FontPath	"/usr/lib/X11/fonts/cyrillic"
	FontPath	"/usr/lib/X11/fonts/100dpi/:unscaled"
	FontPath	"/usr/lib/X11/fonts/75dpi/:unscaled"
	FontPath	"/usr/lib/X11/fonts/Type1"
	FontPath	"/usr/lib/X11/fonts/CID"
	FontPath	"/usr/lib/X11/fonts/Speedo"
	FontPath	"/usr/lib/X11/fonts/100dpi"
	FontPath	"/usr/lib/X11/fonts/75dpi"
        # paths to defoma fonts
	FontPath	"/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
	FontPath	"/var/lib/defoma/x-ttcidfont-conf.d/dirs/CID"
EndSection

EOF

# The module list is permitted to be null.
db_get xserver-xorg/config/modules || true
if [ -n "$RET" ]; then
  MODULES=$(list_convert "$RET")
  printf "Section \"Module\"\n" >> "$tmpfile"
  for MODULE in $MODULES; do
    printf "\tLoad\t$MODULE\n" >> "$tmpfile"
  done
  printf "EndSection\n\n" >> "$tmpfile"
fi

db_get xserver-xorg/config/inputdevice/keyboard/rules
XKB_RULES="$RET"
db_get xserver-xorg/config/inputdevice/keyboard/model
XKB_MODEL="$RET"
db_get xserver-xorg/config/inputdevice/keyboard/layout
XKB_LAYOUT="$RET"
# XkbVariant and XkbOptions are permitted to be null.
db_get xserver-xorg/config/inputdevice/keyboard/variant
XKB_VARIANT="$RET"
db_get xserver-xorg/config/inputdevice/keyboard/options
XKB_OPTIONS="$RET"
db_get xserver-xorg/config/inputdevice/mouse/protocol

MOUSE_PROTOCOL="$RET"

db_get xserver-xorg/config/inputdevice/mouse/emulate3buttons
if [ "$RET" = "true" ]; then
  DO_EMULATE3BUTTONS=true
fi

# totally broken with evdev -daniels, 20050222
DO_EMULATE3BUTTONS=false

db_get xserver-xorg/config/inputdevice/mouse/zaxismapping
if [ "$RET" = "true" ]; then
  DO_ZAXISMAPPING=true
fi

db_get xserver-xorg/config/device/identifier
DEVICE_IDENTIFIER="$RET"

db_get xserver-xorg/config/monitor/identifier
MONITOR_IDENTIFIER="$RET"
db_get xserver-xorg/config/monitor/horiz-sync
MONITOR_HORIZ_SYNC="$RET"
db_get xserver-xorg/config/monitor/vert-refresh
MONITOR_VERT_REFRESH="$RET"

db_get xserver-xorg/config/display/modes
DISPLAY_MODES=$(list_convert "$RET")

db_get xserver-xorg/config/display/default_depth
DISPLAY_DEFAULT_DEPTH="$RET"

for i in $(seq 0 $numheads); do
cat >> "$tmpfile" <<EOF
### WORKSTATION $i ###

Section "InputDevice"
	Identifier	"Generic Keyboard $i"
	Driver		"kbd"
	Option		"CoreKeyboard"
	Option		"Protocol"	"evdev"
	Option		"Dev Phys"	"${realkeyboard[$i]}"
	Option		"XkbRules"	"$XKB_RULES"
	Option		"XkbModel"	"$XKB_MODEL"
	Option		"XkbLayout"	"$XKB_LAYOUT"
EOF

if [ -n "$XKB_VARIANT" ]; then
  printf "\tOption\t\t\"XkbVariant\"\t\"$XKB_VARIANT\"\n" >> "$tmpfile"
fi
if [ -n "$XKB_OPTIONS" ]; then
  printf "\tOption\t\t\"XkbOptions\"\t\"$XKB_OPTIONS\"\n" >> "$tmpfile"
fi
printf "EndSection\n" >> "$tmpfile"

cat >> "$tmpfile" <<EOF

Section "InputDevice"
	Identifier	"Configured Mouse $i"
	Driver		"mouse"
	Option		"CorePointer"
	Option		"Dev Phys"		"${realmouse[$i]}"
	Option		"Protocol"		"evdev"
EOF
if [ -n "$DO_EMULATE3BUTTONS" ] && ! [ "$DO_EMULATE3BUTTONS" = "false" ]; then
  printf "\tOption\t\t\"Emulate3Buttons\"\t\"true\"\n" >> "$tmpfile"
fi
if [ -n "$DO_ZAXISMAPPING" ]; then
  printf "\tOption\t\t\"ZAxisMapping\"\t\t\"4 5\"\n" >> "$tmpfile"
fi
printf "EndSection\n" >> "$tmpfile"

cat >> "$tmpfile" <<EOF

Section "Device"
	Identifier	"$DEVICE_IDENTIFIER $i"
	Driver		"$driver"
	BusID		"${pcibusid[$i]}"
	Screen		0
EndSection

Section "Monitor"
	Identifier	"$MONITOR_IDENTIFIER $i"
	HorizSync	$MONITOR_HORIZ_SYNC
	VertRefresh	$MONITOR_VERT_REFRESH
	Option		"DPMS"
EndSection

Section "Screen"
	Identifier	"Default Screen $i"
	Device		"$DEVICE_IDENTIFIER $i"
	Monitor		"$MONITOR_IDENTIFIER $i"
	DefaultDepth	$DISPLAY_DEFAULT_DEPTH
	SubSection "Display"
		Depth		$DISPLAY_DEFAULT_DEPTH
EOF
if [ -n "$DISPLAY_MODES" ]; then
  printf "\t\tModes\t\t$DISPLAY_MODES\n" >> "$tmpfile"
fi
cat >> "$tmpfile" <<EOF
	EndSubSection
EndSection

Section "ServerLayout"
	Identifier	"Layout$i"
	Screen		"Default Screen $i"
	InputDevice	"Generic Keyboard $i"
	InputDevice	"Configured Mouse $i"
EndSection

EOF
done

db_get xserver-xorg/config/write_dri_section
if [ "$RET" = "true" ]; then
cat >> "$tmpfile" <<EOF
Section "DRI"
	Mode	0666
EndSection
EOF
fi

cp "$tmpfile" /etc/X11/xorg.conf

rm -f "$tmpfile"
# end generate X config
}

# local functions

backup_config_files () {
  mkdir -p /var/backups/multiseat
  data=$(LC_ALL=C date +%F-%H:%M:%S)
  cp /etc/X11/xorg.conf /var/backups/multiseat/xorg.conf.$data || true
  cp /etc/gdm/gdm.conf /var/backups/multiseat/gdm.conf.$data || true
  cp /etc/multiseat.conf /var/backups/multiseat/multiseat.conf.$data || true
}

generate_gdm_config () {
  tmpfile=$(tempfile)
  servers=""
  for i in $(seq 0 $numheads); do
    servers="$servers\n$i=Layout$i"
  done
  cat /usr/share/multiseat/gdm.conf.in | sed -e 's/@SERVERS@/'$servers'\n/g' > "$tmpfile"
  startvt=7
  for i in $(seq 0 $numheads); do
    if [ "$i" -lt "$numheads" ]; then
      serveropts="-sharevts"
    else
      serveropts=""
    fi
    vt=$(expr $startvt + $i)
    printf "\n" >> "$tmpfile"
    cat >> "$tmpfile" << EOF
[server-Layout$i]
name=Server Layout $i
command=/usr/X11R6/bin/X -br -audit 0 -layout Layout$i :$i vt$vt $serveropts
flexible=true
EOF
  done
  cat "$tmpfile" | sed -e 's/^XKeepsCrashing.*/NoXKeepsCrashing=true/g' > /etc/gdm/gdm.conf
  rm -f "$tmpfile"
}

restart_hotplug () {
  invoke-rc.d hotplug restart
}

# main

db_version 2.0

. /etc/multiseat.conf
if [ $configuredws -lt "2" ]; then
 numheads=0
else
 numheads="$(expr $configuredws - 1)"
fi

backup_config_files
generate_x_config
generate_gdm_config
restart_hotplug

exit 0

# vim:set ai et sts=2 sw=2 tw=0:
