{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
module XMonad.Util.ALSA ( toggleMute
, raiseVolume
, lowerVolume
, volumeKeys
) where
import Control.Composition
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.Map as M
import Graphics.X11.ExtraTypes.XF86
import Graphics.X11.Types
import Sound.ALSA.Mixer
toggleMute :: MonadIO m => m ()
toggleMute = liftIO $
withMixer "default" $ \mixer -> do
Just control <- getControlByName mixer "Master"
let Just playbackSwitch = playback (switch control)
Just sw <- getChannel FrontLeft playbackSwitch
setChannel FrontLeft playbackSwitch $ not sw
changeVolume :: MonadIO m
=> Channel
-> Int
-> m ()
changeVolume channel i = liftIO $
withMixer "default" $ \mixer -> do
Just control <- getControlByName mixer "Master"
let Just playbackVolume = playback $ volume control
(min', max') <- both fromIntegral <$> getRange playbackVolume
Just vol <- fmap fromIntegral <$> getChannel channel (value playbackVolume)
let i' = i * ((max' - min') `div` 100)
when ((i' > 0 && vol < max') || (i' < 0 && vol > min')) $
setChannel channel (value playbackVolume) $ fromIntegral (vol + i')
raiseVolume :: MonadIO m => Int -> m ()
raiseVolume = axe [ changeVolume FrontLeft, changeVolume FrontRight ]
lowerVolume :: MonadIO m => Int -> m ()
lowerVolume = raiseVolume . negate
volumeKeys :: MonadIO m => M.Map (KeyMask, KeySym) (m ()) -> M.Map (KeyMask, KeySym) (m ())
volumeKeys = M.union mediaKeyMap
where mediaKeyMap = M.fromList volumeKeyList
volumeKeyList :: MonadIO m => [((KeyMask, KeySym), m ())]
volumeKeyList = [ ((0, xF86XK_AudioMute), toggleMute)
, ((0, xF86XK_AudioLowerVolume), lowerVolume 5)
, ((0, xF86XK_AudioRaiseVolume), raiseVolume 5)
]