module Xmobar.Plugins.Monitors.Volume
( runVolume
, runVolumeWith
, volumeConfig
, options
, defaultOpts
, VolumeOpts
) where
import Control.Applicative ( liftA3 )
import Control.Monad ( liftM2, liftM3, mplus )
import Xmobar.Plugins.Monitors.Common
import Sound.ALSA.Mixer
import qualified Sound.ALSA.Exception as AE
import System.Console.GetOpt
volumeConfig :: IO MConfig
volumeConfig :: IO MConfig
volumeConfig =
String -> [String] -> IO MConfig
mkMConfig
String
"Vol: <volume>% <status>"
[ String
"volume"
, String
"volumebar"
, String
"volumevbar"
, String
"dB"
, String
"status"
, String
"volumeipat"
, String
"volumestatus"
]
data VolumeOpts = VolumeOpts
{ VolumeOpts -> String
onString :: String
, VolumeOpts -> String
offString :: String
, VolumeOpts -> Maybe String
onColor :: Maybe String
, VolumeOpts -> Maybe String
offColor :: Maybe String
, VolumeOpts -> Float
highDbThresh :: Float
, VolumeOpts -> Float
lowDbThresh :: Float
, VolumeOpts -> Maybe IconPattern
volumeIconPattern :: Maybe IconPattern
, VolumeOpts -> Maybe Float
lowVolThresh :: Maybe Float
, VolumeOpts -> Maybe Float
highVolThresh :: Maybe Float
, VolumeOpts -> String
lowString :: String
, VolumeOpts -> String
mediumString :: String
, VolumeOpts -> String
highString :: String
}
defaultOpts :: VolumeOpts
defaultOpts :: VolumeOpts
defaultOpts = VolumeOpts
{ onString :: String
onString = String
"[on] "
, offString :: String
offString = String
"[off]"
, onColor :: Maybe String
onColor = String -> Maybe String
forall a. a -> Maybe a
Just String
"green"
, offColor :: Maybe String
offColor = String -> Maybe String
forall a. a -> Maybe a
Just String
"red"
, highDbThresh :: Float
highDbThresh = -Float
5.0
, lowDbThresh :: Float
lowDbThresh = -Float
30.0
, volumeIconPattern :: Maybe IconPattern
volumeIconPattern = Maybe IconPattern
forall a. Maybe a
Nothing
, lowVolThresh :: Maybe Float
lowVolThresh = Float -> Maybe Float
forall a. a -> Maybe a
Just Float
20.0
, highVolThresh :: Maybe Float
highVolThresh = Float -> Maybe Float
forall a. a -> Maybe a
Just Float
60.0
, lowString :: String
lowString = String
""
, mediumString :: String
mediumString = String
""
, highString :: String
highString = String
""
}
data VolumeStatus
= VolLow
| VolMedium
| VolHigh
| VolOff
getVolStatus :: Float
-> Float
-> Float
-> VolumeStatus
getVolStatus :: Float -> Float -> Float -> VolumeStatus
getVolStatus Float
lo Float
hi Float
val'
| Float
val Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
hi = VolumeStatus
VolHigh
| Float
val Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
lo = VolumeStatus
VolMedium
| Bool
otherwise = VolumeStatus
VolLow
where
val :: Float
val = Float
val' Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
100
options :: [OptDescr (VolumeOpts -> VolumeOpts)]
options :: [OptDescr (VolumeOpts -> VolumeOpts)]
options =
[ String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"O" [String
"on"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { onString = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"o" [String
"off"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { offString = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"" [String
"lowd"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { lowDbThresh = read x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"" [String
"highd"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { highDbThresh = read x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"C" [String
"onc"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { onColor = Just x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"c" [String
"offc"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { offColor = Just x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"" [String
"volume-icon-pattern"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o ->
VolumeOpts
o { volumeIconPattern = Just $ parseIconPattern x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"L" [String
"lowv"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { lowVolThresh = Just $ read x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"H" [String
"highv"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { highVolThresh = Just $ read x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"l" [String
"lows"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { lowString = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"m" [String
"mediums"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { mediumString = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (VolumeOpts -> VolumeOpts)
-> String
-> OptDescr (VolumeOpts -> VolumeOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"h" [String
"highs"] ((String -> VolumeOpts -> VolumeOpts)
-> String -> ArgDescr (VolumeOpts -> VolumeOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x VolumeOpts
o -> VolumeOpts
o { highString = x }) String
"") String
""
]
percent :: Integer -> Integer -> Integer -> Float
percent :: Integer -> Integer -> Integer -> Float
percent Integer
v' Integer
lo' Integer
hi' = (Float
v Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
lo) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
hi Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
lo)
where v :: Float
v = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
v'
lo :: Float
lo = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
lo'
hi :: Float
hi = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
hi'
formatVol :: Integer -> Integer -> Integer -> Monitor String
formatVol :: Integer -> Integer -> Integer -> Monitor String
formatVol Integer
lo Integer
hi Integer
v =
Float -> Monitor String
showPercentWithColors (Float -> Monitor String) -> Float -> Monitor String
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Float
percent Integer
v Integer
lo Integer
hi
formatVolBar :: Integer -> Integer -> Integer -> Monitor String
formatVolBar :: Integer -> Integer -> Integer -> Monitor String
formatVolBar Integer
lo Integer
hi Integer
v =
Float -> Float -> Monitor String
showPercentBar (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float
x where x :: Float
x = Integer -> Integer -> Integer -> Float
percent Integer
v Integer
lo Integer
hi
formatVolVBar :: Integer -> Integer -> Integer -> Monitor String
formatVolVBar :: Integer -> Integer -> Integer -> Monitor String
formatVolVBar Integer
lo Integer
hi Integer
v =
Float -> Float -> Monitor String
showVerticalBar (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) Float
x where x :: Float
x = Integer -> Integer -> Integer -> Float
percent Integer
v Integer
lo Integer
hi
formatVolDStr :: Maybe IconPattern -> Integer -> Integer -> Integer -> Monitor String
formatVolDStr :: Maybe IconPattern
-> Integer -> Integer -> Integer -> Monitor String
formatVolDStr Maybe IconPattern
ipat Integer
lo Integer
hi Integer
v =
Maybe IconPattern -> Float -> Monitor String
showIconPattern Maybe IconPattern
ipat (Float -> Monitor String) -> Float -> Monitor String
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Float
percent Integer
v Integer
lo Integer
hi
switchHelper :: VolumeOpts
-> (VolumeOpts -> Maybe String)
-> (VolumeOpts -> String)
-> VolumeStatus
-> Monitor String
switchHelper :: VolumeOpts
-> (VolumeOpts -> Maybe String)
-> (VolumeOpts -> String)
-> VolumeStatus
-> Monitor String
switchHelper VolumeOpts
opts VolumeOpts -> Maybe String
cHelp VolumeOpts -> String
strHelp VolumeStatus
vs = String -> Monitor String
forall a. a -> ReaderT MConfig IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Monitor String) -> String -> Monitor String
forall a b. (a -> b) -> a -> b
$
Maybe String -> String
colorHelper (VolumeOpts -> Maybe String
cHelp VolumeOpts
opts)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ VolumeStatus -> VolumeOpts -> String
volHelper VolumeStatus
vs VolumeOpts
opts
String -> String -> String
forall a. [a] -> [a] -> [a]
++ VolumeOpts -> String
strHelp VolumeOpts
opts
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (String -> String -> String
forall a b. a -> b -> a
const String
"</fc>") (VolumeOpts -> Maybe String
cHelp VolumeOpts
opts)
formatSwitch :: VolumeOpts -> Bool -> VolumeStatus -> Monitor String
formatSwitch :: VolumeOpts -> Bool -> VolumeStatus -> Monitor String
formatSwitch VolumeOpts
opts Bool
True VolumeStatus
vs = VolumeOpts
-> (VolumeOpts -> Maybe String)
-> (VolumeOpts -> String)
-> VolumeStatus
-> Monitor String
switchHelper VolumeOpts
opts VolumeOpts -> Maybe String
onColor VolumeOpts -> String
onString VolumeStatus
vs
formatSwitch VolumeOpts
opts Bool
False VolumeStatus
_ = VolumeOpts
-> (VolumeOpts -> Maybe String)
-> (VolumeOpts -> String)
-> VolumeStatus
-> Monitor String
switchHelper VolumeOpts
opts VolumeOpts -> Maybe String
offColor VolumeOpts -> String
offString VolumeStatus
VolOff
volHelper :: VolumeStatus -> VolumeOpts -> String
volHelper :: VolumeStatus -> VolumeOpts -> String
volHelper VolumeStatus
volStatus VolumeOpts
opts =
case VolumeStatus
volStatus of
VolumeStatus
VolHigh -> VolumeOpts -> String
highString VolumeOpts
opts
VolumeStatus
VolMedium -> VolumeOpts -> String
mediumString VolumeOpts
opts
VolumeStatus
VolLow -> VolumeOpts -> String
lowString VolumeOpts
opts
VolumeStatus
VolOff -> String
""
colorHelper :: Maybe String -> String
colorHelper :: Maybe String -> String
colorHelper = String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (\String
c -> String
"<fc=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
">")
formatDb :: VolumeOpts -> Integer -> Monitor String
formatDb :: VolumeOpts -> Integer -> Monitor String
formatDb VolumeOpts
opts Integer
dbi = do
h <- Selector (Maybe String) -> Monitor (Maybe String)
forall a. Selector a -> Monitor a
getConfigValue Selector (Maybe String)
highColor
m <- getConfigValue normalColor
l <- getConfigValue lowColor
d <- getConfigValue decDigits
let db = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
dbi Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
100.0
digits = Int -> Float -> String
forall a. RealFloat a => Int -> a -> String
showDigits Int
d Float
db
startColor | Float
db Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= VolumeOpts -> Float
highDbThresh VolumeOpts
opts = Maybe String -> String
colorHelper Maybe String
h
| Float
db Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< VolumeOpts -> Float
lowDbThresh VolumeOpts
opts = Maybe String -> String
colorHelper Maybe String
l
| Bool
otherwise = Maybe String -> String
colorHelper Maybe String
m
stopColor | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
startColor = String
""
| Bool
otherwise = String
"</fc>"
return $ startColor ++ digits ++ stopColor
runVolume :: String -> String -> [String] -> Monitor String
runVolume :: String -> String -> [String] -> Monitor String
runVolume String
mixerName String
controlName [String]
argv = do
opts <- IO VolumeOpts -> Monitor VolumeOpts
forall a. IO a -> Monitor a
io (IO VolumeOpts -> Monitor VolumeOpts)
-> IO VolumeOpts -> Monitor VolumeOpts
forall a b. (a -> b) -> a -> b
$ [OptDescr (VolumeOpts -> VolumeOpts)]
-> VolumeOpts -> [String] -> IO VolumeOpts
forall opts.
[OptDescr (opts -> opts)] -> opts -> [String] -> IO opts
parseOptsWith [OptDescr (VolumeOpts -> VolumeOpts)]
options VolumeOpts
defaultOpts [String]
argv
runVolumeWith opts mixerName controlName
runVolumeWith :: VolumeOpts -> String -> String -> Monitor String
runVolumeWith :: VolumeOpts -> String -> String -> Monitor String
runVolumeWith VolumeOpts
opts String
mixerName String
controlName = do
(lo, hi, val, db, sw) <- IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> Monitor
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a. IO a -> Monitor a
io IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
readMixer
p <- liftMonitor $ liftM3 formatVol lo hi val
b <- liftMonitor $ liftM3 formatVolBar lo hi val
v <- liftMonitor $ liftM3 formatVolVBar lo hi val
d <- getFormatDB opts db
let volStat = (Float -> Float -> Float -> VolumeStatus)
-> Maybe Float -> Maybe Float -> Maybe Float -> Maybe VolumeStatus
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 Float -> Float -> Float -> VolumeStatus
getVolStatus
(VolumeOpts -> Maybe Float
lowVolThresh VolumeOpts
opts)
(VolumeOpts -> Maybe Float
highVolThresh VolumeOpts
opts)
((Integer -> Integer -> Integer -> Float)
-> Maybe Integer -> Maybe Integer -> Maybe Integer -> Maybe Float
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 Integer -> Integer -> Integer -> Float
percent Maybe Integer
val Maybe Integer
lo Maybe Integer
hi)
s <- getFormatSwitch opts sw volStat
ipat <- liftMonitor $ liftM3 (formatVolDStr $ volumeIconPattern opts) lo hi val
let vs = if Maybe Bool -> Bool
isVolOff Maybe Bool
sw
then VolumeOpts -> String
offString VolumeOpts
opts
else String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
p
parseTemplate [p, b, v, d, s, ipat, vs]
where
readMixer :: IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
readMixer =
IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> (T
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a. IO a -> (T -> IO a) -> IO a
AE.catch (String
-> (Mixer
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a. String -> (Mixer -> IO a) -> IO a
withMixer String
mixerName ((Mixer
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> (Mixer
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a b. (a -> b) -> a -> b
$ \Mixer
mixer -> do
control <- Mixer -> String -> IO (Maybe Control)
getControlByName Mixer
mixer String
controlName
(lo, hi) <- liftMaybe $ getRange <$> volumeControl control
val <- getVal $ volumeControl control
db <- getDB $ volumeControl control
sw <- getSw $ switchControl control
return (fmap toInteger lo, fmap toInteger hi, val, db, sw))
(IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> T
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a b. a -> b -> a
const (IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> T
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool))
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> T
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a b. (a -> b) -> a -> b
$ (Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Integer
forall a. Maybe a
Nothing, Maybe Integer
forall a. Maybe a
Nothing, Maybe Integer
forall a. Maybe a
Nothing, Maybe Integer
forall a. Maybe a
Nothing, Maybe Bool
forall a. Maybe a
Nothing))
volumeControl :: Maybe Control -> Maybe Volume
volumeControl :: Maybe Control -> Maybe Volume
volumeControl Maybe Control
c = (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume
forall a. Either a (Maybe a, Maybe a) -> Maybe a
playback (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume)
-> (Control -> Either Volume (Maybe Volume, Maybe Volume))
-> Control
-> Maybe Volume
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Volume (Maybe Volume, Maybe Volume)
volume (Control -> Maybe Volume) -> Maybe Control -> Maybe Volume
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
Maybe Volume -> Maybe Volume -> Maybe Volume
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume
forall a. Either a (Maybe a, Maybe a) -> Maybe a
capture (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume)
-> (Control -> Either Volume (Maybe Volume, Maybe Volume))
-> Control
-> Maybe Volume
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Volume (Maybe Volume, Maybe Volume)
volume (Control -> Maybe Volume) -> Maybe Control -> Maybe Volume
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
Maybe Volume -> Maybe Volume -> Maybe Volume
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume
forall a. Either a (Maybe a, Maybe a) -> Maybe a
common (Either Volume (Maybe Volume, Maybe Volume) -> Maybe Volume)
-> (Control -> Either Volume (Maybe Volume, Maybe Volume))
-> Control
-> Maybe Volume
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Volume (Maybe Volume, Maybe Volume)
volume (Control -> Maybe Volume) -> Maybe Control -> Maybe Volume
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
switchControl :: Maybe Control -> Maybe Switch
switchControl :: Maybe Control -> Maybe Switch
switchControl Maybe Control
c = (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch
forall a. Either a (Maybe a, Maybe a) -> Maybe a
playback (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch)
-> (Control -> Either Switch (Maybe Switch, Maybe Switch))
-> Control
-> Maybe Switch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Switch (Maybe Switch, Maybe Switch)
switch (Control -> Maybe Switch) -> Maybe Control -> Maybe Switch
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
Maybe Switch -> Maybe Switch -> Maybe Switch
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch
forall a. Either a (Maybe a, Maybe a) -> Maybe a
capture (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch)
-> (Control -> Either Switch (Maybe Switch, Maybe Switch))
-> Control
-> Maybe Switch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Switch (Maybe Switch, Maybe Switch)
switch (Control -> Maybe Switch) -> Maybe Control -> Maybe Switch
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
Maybe Switch -> Maybe Switch -> Maybe Switch
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch
forall a. Either a (Maybe a, Maybe a) -> Maybe a
common (Either Switch (Maybe Switch, Maybe Switch) -> Maybe Switch)
-> (Control -> Either Switch (Maybe Switch, Maybe Switch))
-> Control
-> Maybe Switch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Control -> Either Switch (Maybe Switch, Maybe Switch)
switch (Control -> Maybe Switch) -> Maybe Control -> Maybe Switch
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Control
c)
liftMaybe :: Maybe (IO (a,b)) -> IO (Maybe a, Maybe b)
liftMaybe :: forall a b. Maybe (IO (a, b)) -> IO (Maybe a, Maybe b)
liftMaybe = (Maybe (a, b) -> (Maybe a, Maybe b))
-> IO (Maybe (a, b)) -> IO (Maybe a, Maybe b)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Maybe a -> Maybe b -> (Maybe a, Maybe b))
-> (Maybe (a, b) -> Maybe a)
-> (Maybe (a, b) -> Maybe b)
-> Maybe (a, b)
-> (Maybe a, Maybe b)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (((a, b) -> a) -> Maybe (a, b) -> Maybe a
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> a
forall a b. (a, b) -> a
fst) (((a, b) -> b) -> Maybe (a, b) -> Maybe b
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> b
forall a b. (a, b) -> b
snd)) (IO (Maybe (a, b)) -> IO (Maybe a, Maybe b))
-> (Maybe (IO (a, b)) -> IO (Maybe (a, b)))
-> Maybe (IO (a, b))
-> IO (Maybe a, Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (IO (a, b)) -> IO (Maybe (a, b))
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => Maybe (f a) -> f (Maybe a)
sequenceA
liftMonitor :: Maybe (Monitor String) -> Monitor String
liftMonitor :: Maybe (Monitor String) -> Monitor String
liftMonitor Maybe (Monitor String)
Nothing = Monitor String
unavailable
liftMonitor (Just Monitor String
m) = Monitor String
m
channel' :: PerChannel a -> IO (Maybe a)
channel' :: forall a. PerChannel a -> IO (Maybe a)
channel' PerChannel a
v = IO (Maybe a) -> (T -> IO (Maybe a)) -> IO (Maybe a)
forall a. IO a -> (T -> IO a) -> IO a
AE.catch (Channel -> PerChannel a -> IO (Maybe a)
forall x. Channel -> PerChannel x -> IO (Maybe x)
getChannel Channel
FrontLeft PerChannel a
v) (IO (Maybe a) -> T -> IO (Maybe a)
forall a b. a -> b -> a
const (Maybe a -> IO (Maybe a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing))
channel :: PerChannel CLong -> IO (Maybe Integer)
channel :: PerChannel CLong -> IO (Maybe Integer)
channel PerChannel CLong
v = (Maybe CLong -> Maybe Integer)
-> IO (Maybe CLong) -> IO (Maybe Integer)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CLong -> Integer) -> Maybe CLong -> Maybe Integer
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CLong -> Integer
forall a. Integral a => a -> Integer
toInteger) (PerChannel CLong -> IO (Maybe CLong)
forall a. PerChannel a -> IO (Maybe a)
channel' PerChannel CLong
v)
getDB :: Maybe Volume -> IO (Maybe Integer)
getDB :: Maybe Volume -> IO (Maybe Integer)
getDB Maybe Volume
Nothing = Maybe Integer -> IO (Maybe Integer)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Integer
forall a. Maybe a
Nothing
getDB (Just Volume
v) = PerChannel CLong -> IO (Maybe Integer)
channel (Volume -> PerChannel CLong
dB Volume
v)
getVal :: Maybe Volume -> IO (Maybe Integer)
getVal :: Maybe Volume -> IO (Maybe Integer)
getVal Maybe Volume
Nothing = Maybe Integer -> IO (Maybe Integer)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Integer
forall a. Maybe a
Nothing
getVal (Just Volume
v) = PerChannel CLong -> IO (Maybe Integer)
channel (Volume -> PerChannel CLong
value Volume
v)
getSw :: Maybe Switch -> IO (Maybe Bool)
getSw :: Maybe Switch -> IO (Maybe Bool)
getSw Maybe Switch
Nothing = Maybe Bool -> IO (Maybe Bool)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Bool
forall a. Maybe a
Nothing
getSw (Just Switch
s) = Switch -> IO (Maybe Bool)
forall a. PerChannel a -> IO (Maybe a)
channel' Switch
s
getFormatDB :: VolumeOpts -> Maybe Integer -> Monitor String
getFormatDB :: VolumeOpts -> Maybe Integer -> Monitor String
getFormatDB VolumeOpts
_ Maybe Integer
Nothing = Monitor String
unavailable
getFormatDB VolumeOpts
opts' (Just Integer
d) = VolumeOpts -> Integer -> Monitor String
formatDb VolumeOpts
opts' Integer
d
getFormatSwitch :: VolumeOpts -> Maybe Bool -> Maybe VolumeStatus -> Monitor String
getFormatSwitch :: VolumeOpts -> Maybe Bool -> Maybe VolumeStatus -> Monitor String
getFormatSwitch VolumeOpts
_ Maybe Bool
Nothing Maybe VolumeStatus
_ = Monitor String
unavailable
getFormatSwitch VolumeOpts
_ Maybe Bool
_ Maybe VolumeStatus
Nothing = Monitor String
unavailable
getFormatSwitch VolumeOpts
opts' (Just Bool
sw) (Just VolumeStatus
vs) = VolumeOpts -> Bool -> VolumeStatus -> Monitor String
formatSwitch VolumeOpts
opts' Bool
sw VolumeStatus
vs
isVolOff :: Maybe Bool -> Bool
isVolOff = (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
/=)
unavailable :: Monitor String
unavailable = Selector String -> Monitor String
forall a. Selector a -> Monitor a
getConfigValue Selector String
naString