Here is the TCL (8.5) script to control master volume:


----- Begin script

#!/usr/local/bin/wish8.5

# Copyright (c) 2020 W. David Rinehart
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
# USE OR PERFORMANCE OF THIS SOFTWARE.

global lastVolume
global lastMute
proc setVolume { volume } {

    global lastVolume
    if { $volume != $lastVolume } {
        set lastVolume $volume
        exec /usr/bin/sndioctl output.level=[ expr double( $volume ) / 100 ]
        .window.slider.scale set $volume
        .window.slider.percent configure -text [ expr int( $volume ) ]%
    }
}
proc getVolume { } {

    return [ expr int( [ exec /usr/bin/sndioctl -n output.level ] * 100 ) ]
}
proc setVolumeAdd { increment } {

    setVolume [ expr max( min( ( [ getVolume ]\
        + $increment ), 100 ), 0 ) ]
}
proc setMute { mute } {

    global lastMute
    if { $mute != $lastMute } {
        set lastMute $mute
        exec /usr/bin/sndioctl output.mute=$mute
        .window.mute.button configure\
            -bg [ expr { $mute == 1 ? "gray10" : "gray25" } ]
    }
}
proc getMute { } {

    return [ exec /usr/bin/sndioctl -n output.mute ]
}
proc setMuteToggle { } {

    setMute [ expr { [ getMute ] == 1 ? 0 : 1 } ]
}
proc refresh { } {

    setMute   [ getMute ]
    setVolume [ getVolume ]
}
proc every { milliseonds command } {

    eval  $command
    after $milliseonds [info level 0]
}
proc initialize { } {

    global lastVolume
    global lastMute

    set lastVolume -1
    set lastMute unknown

    wm title . "Master Volume"
    wm resizable . 0 0
    bind . <Prior>   { setVolumeAdd 25 }
    bind . <Next>    { setVolumeAdd -25 }
    bind . <Up>      { setVolumeAdd 2 }
    bind . <Right>   { setVolumeAdd 2 }
    bind . <Down>    { setVolumeAdd -2 }
    bind . <Left>    { setVolumeAdd -2 }
    bind . <space>   { setMuteToggle }
    frame .window -bg gray25
    frame .window.title -bg gray25 -pady 3
    label .window.title.label -bg gray25 -fg gray70 -text "Master\nVolume"
    frame .window.slider -bg gray25 -pady 5
    scale .window.slider.scale -troughcolor gray40 -bg gray30 -width 45\
        -length 200 -showvalue false -from 100 -to 0 -command "setVolume"
    label .window.slider.percent -bg gray25 -fg gray70 -pady 3
    frame .window.mute -bg gray25 -padx 8 -pady 5
    button .window.mute.button -bg gray25 -highlightbackground gray25\
        -fg gray70 -text "Mute" -command "setMuteToggle"
    refresh
    pack .window.title
    pack .window.title.label
    pack .window.slider
    pack .window.slider.scale
    pack .window.slider.percent
    pack .window.mute
    pack .window.mute.button
    pack .window
}
initialize
every 2000 { refresh }

----- End script


On 7/1/20 11:48 AM, wdaver wrote:
There are posts asking for a GUI to control volume for OpenBSD.
I wanted the same and wrote an 85 line TCL (8.5) script.  It calls
sndioctl, has a volume slider and mute button, sized for touch
screen convenience.  I use it every day.

I am ok with just posting here, for users to copy and paste.

It could be a port (maybe the smallest port ever).  I know there is an
introduction in the FAQ for ports and I have zero experience creating
ports.  Seems like it would need a brief man page.

The script may stop people from asking about it...

Suggestions for the best way to contribute this tiny script to OpenBSD?


Reply via email to