#!/bin/bash

RUN_DIR="/var/run/nvidia-sleep"
XORG_VT_FILE="${RUN_DIR}"/Xorg.vt_number

case "$1" in
    suspend|hibernate)
        chvt="false"
        #
        # Determine if Xorg is running and, if so, which VT it is
        # running on, making the assumption that X is using the
        # NVIDIA X driver.  If successful, record the VT number in
        # a file in /var/run for use at resume time.
        #
        XORG_PID=$(/bin/pidof Xorg)
        if [[ -n "${XORG_PID}" ]]; then
            XORG_LOG=""
            for fd in /proc/${XORG_PID}/fd/*; do
                link_target=$(/bin/readlink -fn ${fd})
                if [[ "${link_target}" =~ ^/var/log/Xorg\.[0-9]+\.log$ ]]; then
                    XORG_LOG="${link_target}"
                    break
                fi
            done
            if [[ -n "${XORG_LOG}" ]]; then
                XORG_VT=$(sed -e 's/.*using VT number \([0-9]\+\)$/\1/;t;d' "${XORG_LOG}")
                if [[ -n "${XORG_VT}" ]]; then
                    /bin/mkdir -p "${RUN_DIR}"
                    /bin/echo -n "${XORG_VT}" > "${XORG_VT_FILE}"
                    chvt="true"
                fi
            fi
        fi
        #
        # If Xorg was running and its VT number was successfully
        # determined and recorded, switch to an unused VT ahead of
        # the suspend operation (63 is typically unused).
        #
        if [[ "$chvt" == "true" ]]; then
            /bin/chvt 63
            if [[ $? -ne 0 ]]; then
                exit $?
            fi
        fi
        /bin/echo "$1" > /proc/driver/nvidia/suspend
        exit $?
        ;;
    resume)
        /bin/echo "$1" > /proc/driver/nvidia/suspend 
        #
        # Check if Xorg was determined to be running at the time
        # of suspend, and whether its VT was recorded.  If so,
        # attempt to switch back to this VT.
        #
        if [[ -f "${XORG_VT_FILE}" ]]; then
            XORG_PID=$(cat "${XORG_VT_FILE}")
            /bin/rm "${XORG_VT_FILE}"
            /bin/chvt "${XORG_PID}"
        fi
        exit 0
        ;;
    *)
        exit 1
esac
