#!/bin/bash 
# Thinkpad Display Script - Stuart Hopkins

PROFDIR="/etc/disper"

## Functions ##

function haveDFP() {
  # Test if the DFP is enabled
  dfpstat=`cat /proc/acpi/ibm/video | grep "^lcd" | awk '{ print($2) }'`
  if [ "$dfpstat" == "enabled" ]; then
    return 1
  elif [ "$dfpstat" == "disabled" ]; then
    return 0
  else
    echo "  Unknown status value for dfpstat: $dfpstat"
    exit 1
  fi
}

function haveCRT() {
  # Test if a CRT screen is connected and enabled
  crtstat=`cat /proc/acpi/ibm/video | grep "^crt" | awk '{ print($2) }'`
  if [ "$crtstat" == "enabled" ]; then
    return 1
  elif [ "$crtstat" == "disabled" ]; then
    return 0
  else
    echo "  Unknown status value for crtstat: $crtstat"
    exit 1
  fi
}

function haveDVI() {
  # Test if a DVI screen is connected and enabled
  dvistat=`cat /proc/acpi/ibm/video | grep "^dvi" | awk '{ print($2) }'`
  if [ "$dvistat" == "enabled" ]; then
    return 1
  elif [ "$dvistat" == "disabled" ]; then
    return 0
  else
    echo "  Unknown status value for dvistat: $dvistat"
    exit 1
  fi
}

function doSTARTUP() {
  # Called from our WM, change to external screen if we have one
  haveCRT
  crts=$?
  haveDVI
  dvis=$?
  # Workaround for xdisplay var
  if [ "$DISPLAY" == "" ]; then
    export DISPLAY=:0.0
  fi
  displog=`disper -l`
  connscrn=`echo "$displog" | grep -a '^display' | wc -l`
  echo "  Running in startup mode"
  if [ "$screens" == "1" ]; then
    # Single display connected, must be DFP
    echo "  Only the LCD was found to be connected, exiting"
    exit 0
  elif [ "$screens" == "2" ]; then
    # Two connected screens, see if we need to switch
    if [ $crts -eq 0 && $dvis -eq 0 ]; then
      # All external screens are disabled, enable it
      if [ "`echo $displog | grep -a 'CRT-0'`" != "" ]; then
        # CRT connected, switch to it
	disper -d CRT-0 -s >/var/log/disper.log 2>&1
      elif [ "`echo $displog | grep -a 'DVI-0'`" != "" ]; then
	# DVI connected, switch to it
	disper -d DVI-0 -s >/var/log/disper.log 2>&1
      else
	# Nothing appears to be connected, shouldnt happen here
	echo "  Went from connected devices to none, exiting"
	exit 1
      fi
    else
      # An external device is already enabled
      echo "  An external display is already active, exiting"
      exit 0
    fi
  else
    # More than two screens, unsupported
    echo "  More than two screens were found, this is unsupported"
    exit 1
  fi
}

function doACPI() {
  # Called via ACPID (Fn+F7), toggle through displays
  haveDFP
  dfps=$?
  haveCRT
  crts=$?
  haveDVI
  dvis=$?
  # Workaround for xdisplay var
  if [ "$DISPLAY" == "" ]; then
    export DISPLAY=:0.0
  fi
  displog=`disper -l`
  connscrn=`echo "$displog" | grep -a '^display' | wc -l`
  echo "  Running in Fn+F7 mode"
  echo "  DFP: $dfps  CRT: $crts  DVI: $dvis"
  # Act based on what screens are active
  if [ $dfps -eq 1 ]; then
    # DFP active
    echo "  - DFP found to be active"
    if [ $crts -eq 1 ]; then
      # CRT active as well as DFP, switch to CRT only
      echo "  - CRT found to be active, switching to CRT only"
      disper -v -d CRT-0 -s >/var/log/disper.log 2>&1
      return $?
    elif [ $dvis -eq 1 ]; then
      # DVI active as well as DFP, switch to DVI only
      echo "  - DVI found to be active, switching to DVI only"
      disper -v -d DVI-0 -s >/var/log/disper.log 2>&1
      return $?
    else
      # Just the DFP active, switch to external device
      if [ "$connscrn" == "1" ]; then
        # No external screen connected, do nothing
	echo "  No external screen detected, nothing to do"
	return 0
      elif [ "$connscrn" == "2" ]; then
	# One external screen found, switch to extended
	echo "  Unused external screen found, switching to extended mode"
	if [ "`echo $displog | grep 'CRT-0'`" != "" ]; then
	  # DFP and CRT
	  disper -v -d DFP-0,CRT-0 -e >/var/log/disper.log 2>&1
	  return $?
	elif [ "`echo $displog | grep 'DVI-0'`" != "" ]; then
	  # DFP and DVI
	  disper -v -d DFP-0,DVI-0 -e >/var/log/disper.log 2>&1
	  return $?
	else
	  # Shouldnt happen
	  echo "  Unused external disappeared in-process, exiting"
	  return 1
        fi
      else
	# More than two screens connected
	echo "  More than two screens is not currently supported"
	return 1
      fi
    fi
  else
    # DFP disabled
    echo "  - DFP found to be disabled"
    if [ $crts -eq 1 ]; then
      # CRT active, switch back to DFP
      echo "  - CRT found to be active, switching to DFP only"
      disper -v -d DFP-0 -s >/var/log/disper.log 2>&1
      return $?
    elif [ $dvis -eq 1 ]; then
      # DVI active, switch back to DFP
      echo "  - DVI found to be active, switching to DFP only"
      disper -v -d DFP-0 -s >/var/log/disper.log 2>&1
      return $?
    else
      # No screens active?
      echo "  No screens appear to be active, switching to DFP"
      disper -v -d DFP-0 -s >/var/log/disper.log 2>&1
      return $?
    fi
  fi 
}

## Main Code ##

# Check we were passed a profile/mode
if [ ! $1 ]; then
  echo "Thinkpad Display Script - Stuart Hopkins"
  echo "  You must provide a display profile or mode"
  exit 1
fi
PROF=$1

# Welcome message
echo "Thinkpad Display Script - Stuart Hopkins"
echo "Running as user: `whoami` on `date`"

# Check for missing DISPLAY/XAUTHORITY VARS (ACPID doesnt have these)
if [ "$DISPLAY" == "" ]; then
  # X variable not found
  # TODO: This needs to be rewritten
  echo "  X display variable not found, working around"
  if [ -S "/tmp/.X11-unix/X0" ]; then
    export DISPLAY=":0.0"
  else
    echo "  Failed to find the X server"
    exit 1
  fi
else
  echo "X Display: $DISPLAY"
fi
if [ "$XAUTHORITY" == "" ]; then
  # Xauthority not found
  echo "  Xauthority variable not found, working around"
  if [ -S "/tmp/.X11-unix/X0" ]; then
    curuser=`finger | grep -m1 ":0" | awk '{ print($1) }'`
    curhome=`getent passwd $curuser | cut -d: -f6`
    export XAUTHORITY=$curhome/.Xauthority
  fi
else
  echo "Xauthority: $XAUTHORITY"
fi

# Check for required programs
if [ ! -f "/usr/bin/disper" ]; then
  echo "  The program disper is missing, please install it"
  exit 1
fi
if [ ! -f "/proc/acpi/ibm/video" ]; then
  echo "  The IBM ACPI module must be loaded to work"
  exit 1
fi
if [ ! -d "$PROFDIR" ]; then
  echo "  The profile directory is missing, create it"
  exit 1
fi

# Check if we were called by ACPID
if [ "$PROF" == "fnf7" ]; then
  doACPI
  if [ $? -eq 0 ]; then
    echo "Mode set successfully, exiting"
    exit 0
  else
    echo "Mode set failed with exit code $?, check log for more info"
    exit 1
  fi
fi

# Check if we were called as a startup script
if [ "$PROF" == "startup" ]; then
  doSTARTUP
  exit 0
fi

# Check if our ARG is a profile
if [ -f "$PROFDIR/$PROF" ]; then
  # It's a profile, load it
  echo "  Running in profile mode: $PROF"
  disper -v -i <$PROFDIR/$PROF >/var/log/disper.log 2>&1
  if [ $? -ne 0 ]; then
    echo "  Disper failed with the following output:"
    cat /var/log/disper.log
    exit 1
  fi
  exit 0
else
  # Invalid profile name
  echo "  Invalid profile specified, not doing anything"
  exit 1
fi

# All done
exit 0
