# -*- sh -*-
# vim:ft=sh:ts=8:sw=4:noet

AddConfigHandler USuspendConfigEnabler
AddOptionHandler USuspendOptionHandler

AddConfigHelp "USuspendMethod <disk|ram|both>" "Enables use of the uswsusp suspend method of newer kernels (>= 2.6.17rc1)"
AddConfigHelp "USuspendRamForce <boolean>" "Passes the -f flag to s2ram to force suspending even if the machine is not recognised"
AddConfigHelp "USuspendRamUnsureOk <boolean>" "Instructs s2ram to continue when it's unsure about the system type, thus not requiring -f to be passed"
AddConfigHelp "USuspendRamVbeSave <boolean>" "Passes the -s flag to s2ram to save VBE state before suspending and restore after resume"
AddConfigHelp "USuspendRamVbePost <boolean>" "Passes the -p flag to s2ram to VBE POST the graphics card after resume"
AddConfigHelp "USuspendRamVbeMode <boolean>" "Passes the -m flag to s2ram to get VBE mode before suspend and set it after resume"
AddConfigHelp "USuspendRamRadeontool <boolean>" "Passes the -r flag to s2ram to let radeontool turn of the backlight before suspending."
AddConfigHelp "USuspendRamAcpiSleep <number>" "Passes the -a flag to s2ram to set the acpi_sleep parameter before suspend: 1=s3_bios, 2=s3_mode, 3=both"
AddConfigHelp "USuspendRamPciSave <boolean>" "Passes the -v flag to s2ram to have the PCI config space of the VGA card before suspend, and restore it on resume"

AddShortOption "n"
AddLongOption "no-suspend"

USUSPEND_STATE_FILE=/sys/power/state
USUSPEND_DEVICE=/dev/snapshot
USUSPEND_PROG=s2disk
USUSPEND_RAM_FORCE=0
USUSPEND_RAM_UNSUREOK=0
USUSPEND_RAM_VBESAVE=0
USUSPEND_RAM_VBEPOST=0
USUSPEND_RAM_VBEMODE=0
USUSPEND_RAM_RADEONTOOL=0
USUSPEND_RAM_ACPISLEEP=0
USUSPEND_RAM_PCISAVE=0

USuspendConfigEnabler() {
    case "$1" in
	ususpendmethod)
	    case "$2" in
		disk|both) USUSPEND_PROG=s2$2;;
		ram)
		    USUSPEND_PROG=s2ram
		    ;;
		*)
		    vecho 1 "$EXE: Invalid value fo USuspendMethod."
		    return 2
		    ;;
	    esac

	    if [ -n "$NO_COMPLAIN_UNSUPPORTED" ] ; then
		# Just bail silently if we don't detect it.
		if ! test -f $USUSPEND_STATE_FILE || ! test -c $USUSPEND_DEVICE ||
		    ! command -v $USUSPEND_PROG > /dev/null 2>&1 ; then
		    return 0
		fi
	    fi
	    ;;

	ususpendramforce)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_FORCE=1 || return 0
	    ;;
	ususpendramunsureok)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_UNSUREOK=1 || return 0
	    ;;
	ususpendramvbesave)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_VBESAVE=1 || return 0
	    ;;
	ususpendramvbepost)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_VBEPOST=1 || return 0
	    ;;
	ususpendramvbemode)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_VBEMODE=1 || return 0
	    ;;
	ususpendramradeontool)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_RADEONTOOL=1 || return 0
	    ;;
	ususpendramacpisleep)
	    USUSPEND_RAM_ACPISLEEP="$2" || return 0
	    ;;
	ususpendrampcisave)
	    BoolIsOn "$1" "$2" && USUSPEND_RAM_PCISAVE=1 || return 0
	    ;;
	    
	*) return 1;;
    esac

    if [ -z "$USUSPEND_HOOKED" ]; then
	UsingSuspendMethod ususpend
	AddSuspendHook 10 EnsureUSuspendCapable
	AddSuspendHook 99 DoUSuspend
	USUSPEND_HOOKED=1
    fi
    return 0
}

USuspendOptionHandler() {
    [ -z "$USUSPEND_HOOKED" ] && return 1
    case $1 in
	-n|--no-suspend)
	    USUSPEND_NO_SUSPEND=1
	    ;;
	*)
	    return 1
    esac
    return 0
}

DoUSuspend() {
    if [ -z "$USUSPEND_NO_SUSPEND" ] ; then
	ARGS=
	if [ "$USUSPEND_PROG" = s2ram ]; then
	    [ $USUSPEND_RAM_FORCE -eq 1 ] && ARGS="$ARGS -f"
	    [ $USUSPEND_RAM_VBESAVE -eq 1 ] && ARGS="$ARGS -s"
	    [ $USUSPEND_RAM_VBEPOST -eq 1 ] && ARGS="$ARGS -p"
	    [ $USUSPEND_RAM_RADEONTOOL -eq 1 ] && ARGS="$ARGS -r"
	    [ $USUSPEND_RAM_VBEMODE -eq 1 ] && ARGS="$ARGS -m"
	    [ $USUSPEND_RAM_ACPISLEEP -ne 0 ] && ARGS="$ARGS -a $USUSPEND_RAM_ACPISLEEP"
	    [ $USUSPEND_RAM_PCISAVE -eq 1 ] && ARGS="$ARGS -v"
	fi
	vecho 1 "$EXE: Running $USUSPEND_PROG_PATH $ARGS..."
	$USUSPEND_PROG_PATH $ARGS 2>&1 | vcat 2 \
	    || vecho 0 "$EXE: $USUSPEND_PROG_PATH failed (return code $?)."
    else
	vecho 1 "$EXE: Not actually suspending (--no-suspend given)."
    fi
    return 0
}

EnsureUSuspendCapable() {
    if ! USUSPEND_PROG_PATH=$(command -v $USUSPEND_PROG) ; then
	vecho 0 "$USUSPEND_PROG not installed."
	return 2
    fi
    if [ "$USUSPEND_PROG" = s2ram ] && [ $USUSPEND_RAM_FORCE -eq 0 ]; then
	$USUSPEND_PROG -n >/dev/null
	ret=$?
	case "$ret/$USUSPEND_RAM_UNSUREOK" in
	    0/*) :;;
	    32/1) :;; # unsure, but USuspendRamUnsureOk passed
	    32/*)
		vecho 0 "$USUSPEND_PROG: unsure about your machine, see the USuspendRamUnsureOk option"
		return 2
		;;
	    *)
		vecho 0 "$USUSPEND_PROG: unknown machine, see s2ram(8) and the USuspendRamForce option"
		return 2
		;;
	esac
    fi
    if ! test -f $USUSPEND_STATE_FILE ; then
	vecho 0 "Your kernel does not have power management built in."
	return 2
    fi
    if ! test -c $USUSPEND_DEVICE ; then
	vecho 0 "$USUSPEND_DEVICE device not found."
	return 2
    fi

    return 0
}

# $Id: ususpend 1220 2009-04-01 02:06:57Z nigel $
