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

XSTATUS_SUSPEND_TEXT="Preparing to suspend..."
XSTATUS_RESUME_TEXT="Resuming from suspend..."
XOSD_SETTINGS="--font '-misc-fixed-medium-r-semicondensed--*-120-*-*-c-*-*-*' --colour=Green --shadow 1 --pos bottom --align center --offset 50"

AddConfigHandler XStatusOptions
AddConfigHelp "XStatus <gnome|kde|x>" "Enables progress display and error reporting for the given environment."
AddConfigHelp "XmessageDisable <boolean>" "Disable display of xmessage dialogs if XStatus is set to \"x\"."
AddConfigHelp "XSuspendText <message>" "Text to display on screen whilst preparing to suspend. (default: \"$XSTATUS_SUSPEND_TEXT\")"
AddConfigHelp "XResumeText <message>" "Text to display on screen whilst coming back from suspend. (default: \"$XSTATUS_RESUME_TEXT\")"
AddConfigHelp "XosdSettings <options>" "Options to pass to osd_cat, see 'man osd_cat' (default: \"$XOSD_SETTINGS\")"

### KDE bits:

XStatusProgressStart_kde() {
    KDEPB_DCOPREF=

    # Set $PATH for distros that aren't quite standard.
    for i in /opt/kde*/bin /usr/kde/*/bin ; do
	[ -d "$i" ] && PATH=${PATH}:${i} && export PATH
    done

    if ! DCOP_BIN=`command -v dcop 2>/dev/null` ; then
	vecho 0 'Cannot connect to kdialog. `dcop` program not found.'
	return 0
    elif ! KSTART_BIN=`command -v kstart 2>/dev/null` ; then
	vecho 0 'Cannot connect to kdialog. `kstart` program not found.'
	return 0
    elif ! KDIALOG_BIN=`command -v kdialog 2>/dev/null` ; then
	vecho 0 'Cannot connect to kdialog. `kdialog` program not found.'
	return 0
    fi

    KDEPB_DCOPREF="`su $XUSER -c \"$KSTART_BIN --windowclass KDialog --alldesktops $KDIALOG_BIN --title Hibernating --progressbar \\\"$1\\\" 100\"`"
    su $XUSER -c "$DCOP_BIN \"$KDEPB_DCOPREF\" showCancelButton 1"
}

XStatusProgressCheckCancel_kde() {
    [ -z "$KDEPB_DCOPREF" ] && return 0

    local was_cancelled
    was_cancelled=`su $XUSER -c "$DCOP_BIN \"$KDEPB_DCOPREF\" wasCancelled"`
    [ x"$was_cancelled" = "xtrue" ] && SUSPEND_ABORT=1
}

XStatusProgressUpdate_kde() {
    [ -z "$KDEPB_DCOPREF" ] && return 0

    su $XUSER -c "$DCOP_BIN \"$KDEPB_DCOPREF\" setProgress $XSTATUS_PROGRESS"
    XStatusProgressCheckCancel_kde
}

XStatusProgressKill_kde() {
    [ -z "$KDEPB_DCOPREF" ] && return 0

    XStatusProgressCheckCancel_kde
    su $XUSER -c "$DCOP_BIN \"$KDEPB_DCOPREF\" close"
}

XStatusReportErrors_kde() {
    $KSTART_BIN --windowclass KDialog --alldesktops $KDIALOG_BIN --title Hibernating --error "$1" > /dev/null 2>&1
}

### Gnome bits:

XStatusProgressPIPEhandler_gnome() {
    ZENITY_OPEN=
    XStatusProgressKill_gnome
}

XStatusProgressStart_gnomeZenityHelper() {
    zenity_hup_handler() {
	[ -n "$pid_to_kill" ] && kill -INT $pid_to_kill
    }
    trap zenity_hup_handler HUP
    zenity --progress --auto-close --title="Hibernate" --text="$1" || kill -INT $pid_to_kill
    exit 0
}

XStatusProgressStart_gnome() {
    trap XStatusProgressPIPEhandler_gnome PIPE
    pid_to_kill=`/bin/sh -c 'echo $PPID'`
    if [ -n "$NEED_POSIX" ] ; then
	[ -p $ZENITY_FIFO ] && rm -f $ZENITY_FIFO
	ZENITY_FIFO=`mktemp /tmp/tmp.hibernate.XXXXXX`
	rm -f $ZENITY_FIFO
	mknod $ZENITY_FIFO p
	XStatusProgressStart_gnomeZenityHelper "$1" < $ZENITY_FIFO &
	ZENITY_PID=$!
	exec 8>$ZENITY_FIFO
    else
	eval "exec 8> >(XStatusProgressStart_gnomeZenityHelper \"$1\")" || return
    fi
    echo $XSTATUS_PROGRESS >&8
    ZENITY_OPEN=1
}

XStatusProgressUpdate_gnome() {
    [ -n "$ZENITY_OPEN" ] && echo $XSTATUS_PROGRESS >&8
    [ x"$XSTATUS_PROGRESS" = "x100" ] && ZENITY_OPEN=
}

XStatusProgressKill_gnome() {
    [ -n "$ZENITY_OPEN" ] && echo 100 >&8
    exec 8>&-
    [ -p "$ZENITY_FIFO" ] && rm -f $ZENITY_FIFO && ZENITY_FIFO=
    [ -n "$ZENITY_PID" ] && sleep 0.2 && kill $ZENITY_PID > /dev/null 2>&1
    ZENITY_OPEN=
}

XStatusReportErrors_gnome() {
    ( zenity --error --title "Hibernate" --text "$1" < /dev/null > /dev/null 2>&1 & )
}

### X bits:

XStatusProgressStart_xXmessageHelper() {
    xmessage_exit_handler() {
	kill -TERM $xmessage_pid
	exit 0
    }
    trap xmessage_exit_handler HUP QUIT INT TERM
    su $XUSER -c "xmessage -buttons 'Cancel:44' -default 'Cancel' -center -title Hibernate \"$1\"" < /dev/null > /dev/null 2>&1 &
    xmessage_pid=$!
    wait $xmessage_pid
    [ $? -eq 44 ] && kill -INT $pid_to_kill > /dev/null 2>&1
    exit 0
}

XStatusProgressStart_x() {
    local new_pid
    if [ -z "$NO_XOSD" ] ; then
	XOSD_TEXT=$1

	new_pid=`( su $XUSER -c "osd_cat $XOSD_SETTINGS --barmode=percentage --percentage=$XSTATUS_PROGRESS --text \"$XOSD_TEXT\"" < /dev/null > /dev/null 2>&1 & echo $! )`
	XOSD_PIDS="$XOSD_PIDS $new_pid"
    fi

    if [ -z "$XMESSAGE_DISABLE" ] ; then
	pid_to_kill=`/bin/sh -c 'echo $PPID'`
	XStatusProgressStart_xXmessageHelper "$1" &
	XMESSAGE_PIDS="$XMESSAGE_PIDS $!"
    fi
}

XStatusProgressUpdate_x() {
    [ -n "$NO_XOSD" ] && return 0

    local new_pid

    new_pid=`( su $XUSER -c "osd_cat $XOSD_SETTINGS --barmode=percentage --percentage=$XSTATUS_PROGRESS --text \"$XOSD_TEXT\"" < /dev/null > /dev/null 2>&1 & echo $! )`
    XOSD_PIDS="$new_pid $XOSD_PIDS"
}

XStatusProgressKill_x() {
    [ -n "$XOSD_PIDS" ] && kill $XOSD_PIDS > /dev/null 2>&1
    [ -n "$XMESSAGE_PIDS" ] && kill $XMESSAGE_PIDS > /dev/null 2>&1
    XOSD_PIDS=
    XMESSAGE_PIDS=
}

XStatusReportErrors_x() {
    ( /bin/echo -ne "$1" | su $XUSER -c "xmessage -buttons 'Ok:0' -default 'Ok' -center -title 'Hibernate' -file - > /dev/null 2>&1" & )
}

### Wrapper routines:

XStatusSuspendBegin() {
    [ -z $XSTATUS ] && return 0

    XSTATUS_PROGRESS=10
    XStatusProgressStart_$XSTATUS "$XSTATUS_SUSPEND_TEXT"

    return 0
}

XStatusResumeBegin() {
    [ -z $XSTATUS ] && return 0

    XSTATUS_PROGRESS=10
    XStatusProgressStart_$XSTATUS "$XSTATUS_RESUME_TEXT"

    return 0
}

XStatusProgress() {
    [ -z $XSTATUS ] && return 0

    XSTATUS_PROGRESS=$(($XSTATUS_PROGRESS+10))
    XStatusProgressUpdate_$XSTATUS

    return 0
}

XStatusProgressKill() {
    [ -z $XSTATUS ] && return 0

    XSTATUS_PROGRESS=$(($XSTATUS_PROGRESS+10))
    XStatusProgressKill_$XSTATUS

    return 0
}

XStatusReportErrors() {
    [ -z "$XSTATUS" ] && return 0
    [ -z "$ERROR_TEXT" ] && return 0

    XStatusReportErrors_$XSTATUS "$ERROR_TEXT"

    return 0
}

### Hook us in:

XStatusOptions() {
    local foo
    case $1 in
	xstatus)
	    foo=`echo $2|tr '[A-Z]' '[a-z]'`
	    case $foo in
		gnome|kde|x)
		    XSTATUS=$foo
		    ;;
		*)
		    vecho 0 "$EXE: Invalid value for $1 option."
		    exit 1
		    ;;
	    esac
	    ;;
	xmessagedisable)
	    BoolIsOn "$1" "$2" && XMESSAGE_DISABLE=1 && return 0
	    ;;
	xsuspendtext)
	    shift
	    XSTATUS_SUSPEND_TEXT="$*"
	    ;;
	xresumetext)
	    shift
	    XSTATUS_RESUME_TEXT="$*"
	    ;;
	xosdsettings)
	    shift
	    XOSD_SETTINGS="$*"
	    ;;
	*)
	    return 1
    esac

    if [ x"$XSTATUS" = "xx" ] && ! command -v osd_cat > /dev/null 2>&1 ; then
	NO_XOSD=1
    fi
    XOSD_PIDS=
    XMESSAGE_PIDS=

    if FindXServer && [ -z "$XSTATUS_HOOKED" ] ; then
	# We can do a pretty progress bar!
	AddSuspendHook 05 XStatusSuspendBegin
	AddSuspendHook 20 XStatusProgress
	AddSuspendHook 30 XStatusProgress
	AddSuspendHook 40 XStatusProgress
	AddSuspendHook 50 XStatusProgress
	AddSuspendHook 60 XStatusProgress
	AddSuspendHook 70 XStatusProgress
	AddSuspendHook 80 XStatusProgress
	AddSuspendHook 90 XStatusProgress
	AddSuspendHook 95 XStatusProgress
	AddSuspendHook 98 XStatusProgressKill
	AddResumeHook 95 XStatusResumeBegin
	AddResumeHook 90 XStatusProgress
	AddResumeHook 80 XStatusProgress
	AddResumeHook 70 XStatusProgress
	AddResumeHook 60 XStatusProgress
	AddResumeHook 50 XStatusProgress
	AddResumeHook 40 XStatusProgress
	AddResumeHook 30 XStatusProgress
	AddResumeHook 20 XStatusProgress
	AddResumeHook 15 XStatusProgress
	AddResumeHook 05 XStatusProgressKill
	AddResumeHook 01 XStatusReportErrors
	XSTATUS_HOOKED=1
    fi

    return 0
}

# $Id: xstatus 1196 2008-05-01 11:58:52Z nigel $
