[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: stopping laptop sound on suspend?



Tony Godshall <togo@of.net> writes:

> Any tips or tricks or ideas or RT(specific)FMs greatly 
> appreciated.

Take this, and make it happy on Debian.  8^)  Buried in it's RH
innards is the gunk that they use to kill sound on suspend, and
restart it on resume.  (Even kills programs and restarts them.)  I've
never gotten around to ripping out the sound parts and making them
work on Debian, but you're welcome to.

-- 
Alan Shutko <ats@acm.org> - In a variety of flavors!
Sex is a natural bodily process, like a stroke.
#!/bin/bash
# DO NOT EDIT THIS SCRIPT, CREATE AND EDIT APMCONTINUE IN THIS DIRECTORY; you
# can put your stuff into apmcontinue for every link you create to apmscript;
# for a start and definitely enough for most laptops we have two links and
# according subroutines defined here: suspend and resume; all other links
# will be redirected directly to apmcontinue which you can create; also
# suspend and resume call apmscript, so you can also do other things (like
# reinitialising some PCMCIA-Card) there; apmcontinue will get the name
# as which it was called as $1; for debugging see the logfiles
#
# This script can be controlled by editing /etc/sysconfig/apmd.

PROG="$1"
LOCKFILE=/var/lock/subsys/resume
[ -e /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
[ -e /etc/sysconfig/apmd ] && . /etc/sysconfig/apmd
[ -e /etc/sysconfig/clock ] && . /etc/sysconfig/clock
[ -z "$UTC" ] && UTC="no"
[ -z "$CHANGEVT" ] && CHANGEVT="0"
[ -z "$CLOCK_SYNC" ] && CLOCK_SYNC="no"

CLOCK=""
[ "$UTC" = "yes" -o "$UTC" = "true" -o "$UTC" = 1 ] && CLOCK="-u"

case "$PROG" in
    suspend|standby)
	# Remove sound progs and modules if requested
	if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
		# Find all programs using sound and kill them...
		logger removing sound programs
		rm -rf /var/run/apm-soundprogs
		if [ -c /dev/sndstat ]; then
			for n in `cat /dev/sndstat 2>/dev/null|grep Open\ by|awk {'print $3'}|uniq`; do
				SOUNDPROG=`echo $n|awk -F / {'print $2'}`
				SOUNDPID=`echo $n|awk -F / {'print $1'}`
				SOUNDUSER=`ls -ld /proc/$SOUNDPID |awk {'print $3'}`
				SOUNDDISPLAY=`perl -e 's/\000/\n/g;' -p /proc/$SOUNDPID/environ|grep ^DISPLAY=|cut -d= -f2-`

				# Make sure nobody is playing foul tricks on us
				SOUNDPROG=`echo $SOUNDPROG |sed -e "s/|.*//`

				kill $SOUNDPID
				ps "$SOUNDPID" &>/dev/null && kill -9 $SOUNDPID
				echo "$SOUNDPROG|$SOUNDPID|$SOUNDUSER|$SOUNDDISPLAY" >>/var/run/apm-soundprogs
				logger "apmscript: Program $SOUNDPROG ($SOUNDPID) of user $SOUNDUSER on display $SOUNDDISPLAY terminated."
			done
		fi
		for n in `lsof |grep /dev|grep ' 14,'|sed -e 's/ \+/|/g'|cut '-d|' -f1-3`; do
			SOUNDPROG=`echo $n |cut '-d|' -f1`
			SOUNDPID=`echo $n |cut '-d|' -f2`
			SOUNDUSER=`echo $n |cut '-d|' -f3`
			SOUNDDISPLAY=`perl -e 's/\000/\n/g;' -p /proc/$SOUNDPID/environ|grep ^DISPLAY=|cut -d= -f2-`

			# Make sure nobody is playing foul tricks on us
			SOUNDPROG=`echo $SOUNDPROG |sed -e "s/|.*//`

			kill $SOUNDPID
			ps "$SOUNDPID" &>/dev/null && kill -9 $SOUNDPID
			echo "$SOUNDPROG|$SOUNDPID|$SOUNDUSER|$SOUNDDISPLAY" >>/var/run/apm-soundprogs
			logger "apmscript: Program $SOUNDPROG ($SOUNDPID) of user $SOUNDUSER on display $SOUNDDISPLAY terminated."
		done
		# We unload the modules later to give the driver some time
		# to spin down.
	fi
	logger Before disks
	# Some broken disks won't return from a suspend to disk
	# unless they're set to 100% failsafe settings with hdparm.
	# Typically, notebooks with SystemSoft MobilePRO BIOS are
	# affected by this.
	if test "x$HDPARM_AT_SUSPEND" != "x"; then
		for i in /proc/ide/hd*; do
			DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
			if test "x`cat $i/media`" = "xdisk"; then
				hdparm $HDPARM_AT_SUSPEND $DRIVE
			fi
		done
	fi
	sync
	logger Before network stop
	[ "$NETFS_RESTART" = "yes" ] && /etc/rc.d/init.d/netfs stop
	[ "$NET_RESTART" = "yes" ] && /etc/rc.d/init.d/network stop
	logger After network stop
	[ "$PCMCIARESTART" = "yes" ] && {
		if [ "$PCMCIABIOSBUG" = "yes" ]; then
			/sbin/cardctl eject
		else
			/sbin/cardctl suspend
		fi
	}
	if [ "$PCMCIAWAIT" = "yes" ]; then
		until [ `grep "Socket .: empty" /var/run/stab|wc -l` = `grep "Socket" /var/run/stab|wc -l` ]; do
			logger "Waiting for pcmcia-device to be removed..."
			sleep 10
		done
	fi

	while [ -f "$LOCKFILE" ]; do
		RESUMEPID=`cat "$LOCKFILE"`
		logger "Waiting for resume to be finished ($LOCKFILE gives PID $RESUMEPID)..."
		sleep 10
	done

	# Don't try to restore the terminal or lock X if X isn't running...
	[ "x`pidof X`" != x ] && {
		[ "$CHANGEVT" != "0" ] && chvt 1
		[ "x$LOCK_X" = "xyes" -o "x$LOCK_X" = "x1" ] && {
			# Lock X, based on patch from Hannu Martikka
			# <Hannu.Martikka@nokia.com>
			w |tail +3 |awk '{print $1, $3}'|grep -v '-'|grep : | \
			sort -u | \
			while read line; do
				Usern=`echo $line |awk '{print $1}'`
				XDisp=`echo $line |awk '{print $2}'`
				if [ "x$Usern" = "xroot" ]; then
					xlock -display $XDisp &>/dev/null &
				else
					su $Usern -c "xscreensaver-command -display $XDisp -lock || (xscreensaver -display $XDisp -no-splash &sleep 1; xscreensaver-command -display $XDisp -lock) || (xlock -display $XDisp &)" &>/dev/null
				fi
			done
		}
	}

	# Unload sound modules if necessary
	if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
		# soundoff is from the commercial OSS drivers, don't worry
		# if you don't have it. (Nobody sane does ;) ).
		[ -x /usr/bin/soundoff ] && /usr/bin/soundoff
		[ -x /usr/sbin/soundoff ] && /usr/sbin/soundoff
		[ -x /usr/local/bin/soundoff ] && /usr/local/bin/soundoff
		[ -x /usr/local/sbin/soundoff ] && /usr/local/sbin/soundoff
		rm -rf /var/run/apm-soundmodules
		for m in $SOUNDMODULES; do
			if lsmod |grep -q "^$m " &>/dev/null; then
				rmmod $m
				echo $m >>/var/run/apm-soundmodules
			fi
		done
	fi
	sync

	[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue "$PROG"

	sync
	;;

    resume)
	# If HDPARM_AT_RESUME is set, the user has a broken disk.
	# We'd better wake it up manually. :/
	if test "x$HDPARM_AT_RESUME" != "x"; then
		for i in /proc/ide/hd*; do
			DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
			if test "x`cat $i/media`" = "xdisk"; then
				hdparm -q -S0 $DRIVE
			fi
		done
	fi
	# as some displays don't like being waked up from power-off
	# state directly into graphics mode, we can switch to console
	# 1 during suspend and back to console n (where we assume X11
	# is running) after a resume; also the setting of the console
	# beep and the whole sound system can be confused; see
	# /etc/sysconfig/apm for a detailed description of the
	# variables used here.

	echo $$ >> "$LOCKFILE"
	if [ "$TERMINALBEEP" != "" ]; then
		# first we set the beep-length
		for t in 1 2 3 4 5 6 7 8 9; do
			setterm -blength $BEEPLENGTH >/dev/tty$t
		done
	fi
	if [ "$RESTORESOUND" = "yes" -o "$RESTORESOUNDPROGS" = "yes" ]; then
		# Get the sound modules back up...
		# soundon is from the commercial OSS drivers, don't worry
		# if you don't have it.
		[ -x /usr/bin/soundon ] && /usr/bin/soundon
		[ -x /usr/sbin/soundon ] && /usr/sbin/soundon
		[ -x /usr/local/bin/soundon ] && /usr/local/bin/soundon
		[ -x /usr/local/sbin/soundon ] && /usr/local/sbin/soundon
		for m in `cat /var/run/apm-soundmodules`; do
			modprobe $m
		done
		rm -f /var/run/apm-soundmodules
	fi
	if [ "$RESTORESOUNDPROGS" = "yes" ]; then
		# at least we can restart the programs using sound on
		# the right display
		# If you're using the trial version of OSS, you want to add
		#sleep 5
		# here to wait for the trial text
		for n in `cat /var/run/apm-soundprogs`; do
			SOUNDPROG=`echo $n|cut '-d|' -f1`
			SOUNDPID=`echo $n|cut '-d|' -f2`
			SOUNDUSER=`echo $n|cut '-d|' -f3`
			SOUNDDISPLAY=`echo $n|cut '-d|' -f4`
			su --shell="/bin/bash" - "$SOUNDUSER" -c "source /etc/profile;[ -f ~/.bashrc ] && source ~/.bashrc;[ -f ~/.bash_profile ] && source ~/.bash_profile;export DISPLAY="$SOUNDDISPLAY";$SOUNDPROG &"
			logger "apmscript: Program $SOUNDPROG started as user $SOUNDUSER on display $SOUNDDISPLAY."
		done
		rm -f /var/run/apm-soundprogs
	fi

	# restore X if necessary
	[ "$CHANGEVT" != "0" ] && [ "x`pidof X`" != x ] && chvt "$CHANGEVT"

	if [ "$PCMCIARESTART" = "yes" ] ; then
		if [ "$PCMCIABIOSBUG" = "yes" ]; then
			/sbin/cardctl insert
		else
			/sbin/cardctl resume
		fi
	fi
	[ "$NET_RESTART" = "yes" ] && /etc/rc.d/init.d/network start
	[ "$NETFS_RESTART" = "yes" ] && /etc/rc.d/init.d/netfs start
	sync

	[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue "$PROG"

	# Read the hardware clock
	if test $CLOCK_SYNC != "no"; then
		hwclock $CLOCK --hctosys
	fi

	# Finally, run anacron to catch up cron stuff we missed...
	# If anacron is installed and we're on AC power or we want
	# to run it even in battery mode.
	if [ -x /usr/sbin/anacron ]; then
		if apm |grep on-line &>/dev/null; then
			/usr/sbin/anacron
		elif test "x$ANACRON_ON_BATTERY" = "xyes"; then
			/usr/sbin/anacron
		fi
	fi
		  
	if test "x$HDPARM_AT_RESUME" != "x"; then
		for i in /proc/ide/hd*; do
			DRIVE=/dev/`echo $i |sed -e "s,.*/,,g"`
			if test "x`cat $i/media`" = "xdisk"; then
				hdparm $HDPARM_AT_RESUME $DRIVE
			fi
		done
	fi

	rm -f "$LOCKFILE"
	;;
    change)
	case $2 in
	power)
		# Change from battery power to AC power or vice versa.
		# You might want to stop/restart any unnecessary CPU intensive
		# tasks (seti@home, distributed.net clients, etc) here.
		;;
	battery)
		# Battery low. If you want to be on the safe side, maybe put
		# the harddisk into extreme powersaving, or "apm -s" here.
		;;
	esac
        if [ -f /etc/sysconfig/apm-scripts/apmcontinue ]; then
		. /etc/sysconfig/apm-scripts/apmcontinue $@
        fi
        ;;
    start)
	# This occurs at system startup - you usually don't need to do
	# anything here.
	[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue $@
	;;
    stop)
	# This occurs at system shutdown - you usually don't need to do
	# anything here.
	[ -f /etc/sysconfig/apm-scripts/apmcontinue ] && . /etc/sysconfig/apm-scripts/apmcontinue $@
	;;
    *)
	if [ -f /etc/sysconfig/apm-scripts/apmcontinue ]; then
		. /etc/sysconfig/apm-scripts/apmcontinue "$PROG"
	else
		logger "FAIL: Wrong parameter \"$PROG\" in apmscript!"
		exit 1
	fi
	;;
esac
exit 0

Reply to: