Ubuntu 12.04: Sound Toggle 1.3 – HDMI sound toggle/switch

So I did a few edits to my script that allows me to:

  • Enable/disable the lockscreen. That way, I can close my laptop without having the lockscreen coming up.
  • Restore the backlight level based off of set values.
  • Added notifications.

Script:
#!/bin/bash
# Sound Toggle
# By Charles Cruz
#
# The following script toggles the between laptop speakers and hdmi audio (if detected).
# This also disables/enables
# Version 1.3
 
########### Settings ###########
# Backlight Settings
BACKLIGHT_BATTERY=20
BACKLIGHT_AC=100
 
USERID="$(cat /var/run/ConsoleKit/database | grep -B 6 is_active=true | grep uid= | cut -f 2 -d '=')"
USER="$(grep $USERID /etc/passwd | cut -f 1 -d ':')"
HDMI_STATUS="$(cat /sys/class/drm/card0-HDMI-A-1/status)"
GNOME_SCREENSAVER_PROC=`ps xa | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
 
export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SCREENSAVER_PROC/environ`
export XAUTHORITY="/home/$USER/.Xauthority"
export DISPLAY="$(cat /var/run/ConsoleKit/database | grep x11_display= | cut -f 2 -d '=')"
 
# HDMI is connected
if [ "$HDMI_STATUS" = connected ]; then
# Send notification
sudo -u $USER notify-send -i display "HDMI connected"
 
# Set the sound card profile
sudo -u $USER pactl set-card-profile 0 output:hdmi-stereo+input:analog-stereo
 
# Disable the lockscreen if it's enabled so you can close the lockscreen
if [[ $(sudo -u $USER gsettings get org.gnome.desktop.screensaver lock-enabled) = true ]]; then
sudo -u $USER gsettings set org.gnome.desktop.screensaver lock-enabled false
fi
 
# HDMI is not connected
else
# Send notification
sudo -u $USER notify-send -i computer "HDMI disconnected"
 
# Set the sound card profile
sudo -u $USER pactl set-card-profile 0 output:analog-stereo+input:analog-stereo
 
# Restore the lock setting, if necessary
if [[ $(sudo -u $USER gsettings get org.gnome.desktop.screensaver lock-enabled) = false ]]; then
sudo -u $USER gsettings set org.gnome.desktop.screensaver lock-enabled true
fi
 
# Restore default battery/power brightness
cat /proc/acpi/ac_adapter/AC/state | grep "on-line"
if [ $? -eq 0 ]; then
xbacklight -set $BACKLIGHT_AC # Power cable is connected
else
xbacklight -set $BACKLIGHT_BATTERY # Power cable is not connected
fi
fi
 
exit 0

BTW, I renamed the script to “toggle-sound” so if you used a different name, be sure to change the name in the instructions below.

Instructions:

  1. In a terminal:
    sudo gedit /usr/local/bin/toggle-sound
  2. Copy and paste the script above into the document. Save and close it.
  3. In the terminal:
    sudo chmod 755 /usr/local/bin/toggle-sound
     
    echo 'KERNEL=="card0", SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/toggle-sound"' | sudo tee /etc/udev/rules.d/hdmi.rules
     
    sudo udevadm control --reload-rules

Ubuntu 12.04: SToggle – HDMI sound toggle/switch

I’m a newb when it comes to scripting and pretty much anything Linux related. But even so, I’m a bit proud of this script because now I can toggle hdmi audio on my laptop from either my main user account or guest account (that, and the fact that I spent 5 hours trying to find a way to get the script to work)! 😀

So, apparently my udev rules were working. The problem was the script. I learned that running scripts in a terminal, in the background, or by udev isn’t the same; environment variables are different and when you use ‘who’ or ‘w’ in a script that isn’t running in the terminal, it’ll display nothing. I guess in older versions of Ubuntu, when you used
USER="$(who | grep :0 | cut -f 1 -d ' ' | head -n 1)"
a line would show for the gnome-session (tty7)? But as far as I can tell, it wasn’t showing in Ubuntu 12.04 (and apparently 11.10 because in my Ubuntu 11.10 VM, it didn’t show up either). Technically, the script (MToggle) works if you had a terminal opened on TTY opened (probably why I thought it worked). But since I had a terminal opened at most times, I just assumed the script worked.

In 11.10 and 12.04, you could get around this by just putting your actual username for USER, but then it wouldn’t work if you had other users that used the same computer. But then again, the script was made for laptops in mind and I doubt it would work for desktops because it depends on the change of hdmi status… I’m not sure.

But what about guest accounts? What about changing usernames? I didn’t like the fact that I was just using my username in the script to get it to work. So I started searching the filesystem for anything that could tell me about the active user logged on. Eventually I found a file called “database” in “/var/run/ConsoleKit” which had info about “x11_display”, which one was active, and the UID of that corresponded to the displays. So the script:

#!/bin/bash
# Sound Toggle
# By Charles Cruz
#
# The following script toggles the between laptop speakers and hdmi audio (if detected).
# Version 1.0

USERID="$(cat /var/run/ConsoleKit/database | grep -B 6 is_active=true | grep uid= | cut -f 2 -d '=')"
USER="$(grep $USERID /etc/passwd | cut -f 1 -d ':')"
HDMI_STATUS="$(cat /sys/class/drm/card0-HDMI-A-1/status)"

if [ "${HDMI_STATUS}" = connected ]; then
sudo -u $USER pactl set-card-profile 0 output:hdmi-surround
else
sudo -u $USER pactl set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

exit 0

Steps:

  1. In a terminal:
    sudo gedit /etc/udev/rules.d/hdmi.rules
  2. Copy, paste, then save:
    SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/SToggle"
  3. In the terminal:
    sudo udevadm control --reload-rules
  4. In the terminal:
    sudo gedit /usr/local/bin/SToggle
  5. Copy and paste the script above and then save it.
  6. In the terminal:
    sudo chmod 755 /usr/local/bin/SToggle

And that should do it! Hope it works!