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 :: String
-> String
-> Maybe String
-> Maybe String
-> Float
-> Float
-> Maybe IconPattern
-> Maybe Float
-> Maybe Float
-> String
-> String
-> String
-> VolumeOpts
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 :: String
onString = String
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 :: String
offString = String
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 :: Float
lowDbThresh = String -> Float
forall a. Read a => String -> a
read String
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 :: Float
highDbThresh = String -> Float
forall a. Read a => String -> a
read String
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 :: Maybe String
onColor = String -> Maybe String
forall a. a -> Maybe a
Just String
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 :: Maybe String
offColor = String -> Maybe String
forall a. a -> Maybe a
Just String
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 :: Maybe IconPattern
volumeIconPattern = IconPattern -> Maybe IconPattern
forall a. a -> Maybe a
Just (IconPattern -> Maybe IconPattern)
-> IconPattern -> Maybe IconPattern
forall a b. (a -> b) -> a -> b
$ String -> IconPattern
parseIconPattern String
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 :: Maybe Float
lowVolThresh = Float -> Maybe Float
forall a. a -> Maybe a
Just (Float -> Maybe Float) -> Float -> Maybe Float
forall a b. (a -> b) -> a -> b
$ String -> Float
forall a. Read a => String -> a
read String
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 :: Maybe Float
highVolThresh = Float -> Maybe Float
forall a. a -> Maybe a
Just (Float -> Maybe Float) -> Float -> Maybe Float
forall a b. (a -> b) -> a -> b
$ String -> Float
forall a. Read a => String -> a
read String
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 :: String
lowString = String
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 :: String
mediumString = String
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 :: String
highString = String
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 (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
Maybe String
h <- Selector (Maybe String) -> Monitor (Maybe String)
forall a. Selector a -> Monitor a
getConfigValue Selector (Maybe String)
highColor
Maybe String
m <- Selector (Maybe String) -> Monitor (Maybe String)
forall a. Selector a -> Monitor a
getConfigValue Selector (Maybe String)
normalColor
Maybe String
l <- Selector (Maybe String) -> Monitor (Maybe String)
forall a. Selector a -> Monitor a
getConfigValue Selector (Maybe String)
lowColor
Int
d <- Selector Int -> Monitor Int
forall a. Selector a -> Monitor a
getConfigValue Selector Int
decDigits
let db :: Float
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 :: String
digits = Int -> Float -> String
forall a. RealFloat a => Int -> a -> String
showDigits Int
d Float
db
startColor :: String
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
stopColor | String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
startColor = String
""
| Bool
otherwise = String
"</fc>"
String -> Monitor String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Monitor String) -> String -> Monitor String
forall a b. (a -> b) -> a -> b
$ String
startColor String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
digits String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
stopColor
runVolume :: String -> String -> [String] -> Monitor String
runVolume :: String -> String -> [String] -> Monitor String
runVolume String
mixerName String
controlName [String]
argv = do
VolumeOpts
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
VolumeOpts -> String -> String -> Monitor String
runVolumeWith VolumeOpts
opts String
mixerName String
controlName
runVolumeWith :: VolumeOpts -> String -> String -> Monitor String
runVolumeWith :: VolumeOpts -> String -> String -> Monitor String
runVolumeWith VolumeOpts
opts String
mixerName String
controlName = do
(Maybe Integer
lo, Maybe Integer
hi, Maybe Integer
val, Maybe Integer
db, Maybe Bool
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
String
p <- Maybe (Monitor String) -> Monitor String
liftMonitor (Maybe (Monitor String) -> Monitor String)
-> Maybe (Monitor String) -> Monitor String
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer -> Monitor String)
-> Maybe Integer
-> Maybe Integer
-> Maybe Integer
-> Maybe (Monitor String)
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 Integer -> Integer -> Integer -> Monitor String
formatVol Maybe Integer
lo Maybe Integer
hi Maybe Integer
val
String
b <- Maybe (Monitor String) -> Monitor String
liftMonitor (Maybe (Monitor String) -> Monitor String)
-> Maybe (Monitor String) -> Monitor String
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer -> Monitor String)
-> Maybe Integer
-> Maybe Integer
-> Maybe Integer
-> Maybe (Monitor String)
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 Integer -> Integer -> Integer -> Monitor String
formatVolBar Maybe Integer
lo Maybe Integer
hi Maybe Integer
val
String
v <- Maybe (Monitor String) -> Monitor String
liftMonitor (Maybe (Monitor String) -> Monitor String)
-> Maybe (Monitor String) -> Monitor String
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer -> Monitor String)
-> Maybe Integer
-> Maybe Integer
-> Maybe Integer
-> Maybe (Monitor String)
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 Integer -> Integer -> Integer -> Monitor String
formatVolVBar Maybe Integer
lo Maybe Integer
hi Maybe Integer
val
String
d <- VolumeOpts -> Maybe Integer -> Monitor String
getFormatDB VolumeOpts
opts Maybe Integer
db
let volStat :: Maybe VolumeStatus
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)
String
s <- VolumeOpts -> Maybe Bool -> Maybe VolumeStatus -> Monitor String
getFormatSwitch VolumeOpts
opts Maybe Bool
sw Maybe VolumeStatus
volStat
String
ipat <- Maybe (Monitor String) -> Monitor String
liftMonitor (Maybe (Monitor String) -> Monitor String)
-> Maybe (Monitor String) -> Monitor String
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer -> Monitor String)
-> Maybe Integer
-> Maybe Integer
-> Maybe Integer
-> Maybe (Monitor String)
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 (Maybe IconPattern
-> Integer -> Integer -> Integer -> Monitor String
formatVolDStr (Maybe IconPattern
-> Integer -> Integer -> Integer -> Monitor String)
-> Maybe IconPattern
-> Integer
-> Integer
-> Integer
-> Monitor String
forall a b. (a -> b) -> a -> b
$ VolumeOpts -> Maybe IconPattern
volumeIconPattern VolumeOpts
opts) Maybe Integer
lo Maybe Integer
hi Maybe Integer
val
let vs :: String
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
[String] -> Monitor String
parseTemplate [String
p, String
b, String
v, String
d, String
s, String
ipat, String
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
Maybe Control
control <- Mixer -> String -> IO (Maybe Control)
getControlByName Mixer
mixer String
controlName
(Maybe CLong
lo, Maybe CLong
hi) <- Maybe (IO (CLong, CLong)) -> IO (Maybe CLong, Maybe CLong)
forall a b. Maybe (IO (a, b)) -> IO (Maybe a, Maybe b)
liftMaybe (Maybe (IO (CLong, CLong)) -> IO (Maybe CLong, Maybe CLong))
-> Maybe (IO (CLong, CLong)) -> IO (Maybe CLong, Maybe CLong)
forall a b. (a -> b) -> a -> b
$ Volume -> IO (CLong, CLong)
getRange (Volume -> IO (CLong, CLong))
-> Maybe Volume -> Maybe (IO (CLong, CLong))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Control -> Maybe Volume
volumeControl Maybe Control
control
Maybe Integer
val <- Maybe Volume -> IO (Maybe Integer)
getVal (Maybe Volume -> IO (Maybe Integer))
-> Maybe Volume -> IO (Maybe Integer)
forall a b. (a -> b) -> a -> b
$ Maybe Control -> Maybe Volume
volumeControl Maybe Control
control
Maybe Integer
db <- Maybe Volume -> IO (Maybe Integer)
getDB (Maybe Volume -> IO (Maybe Integer))
-> Maybe Volume -> IO (Maybe Integer)
forall a b. (a -> b) -> a -> b
$ Maybe Control -> Maybe Volume
volumeControl Maybe Control
control
Maybe Bool
sw <- Maybe Switch -> IO (Maybe Bool)
getSw (Maybe Switch -> IO (Maybe Bool))
-> Maybe Switch -> IO (Maybe Bool)
forall a b. (a -> b) -> a -> b
$ Maybe Control -> Maybe Switch
switchControl Maybe Control
control
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
-> IO
(Maybe Integer, Maybe Integer, Maybe Integer, Maybe Integer,
Maybe Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return ((CLong -> Integer) -> Maybe CLong -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CLong -> Integer
forall a. Integral a => a -> Integer
toInteger Maybe CLong
lo, (CLong -> Integer) -> Maybe CLong -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CLong -> Integer
forall a. Integral a => a -> Integer
toInteger Maybe CLong
hi, Maybe Integer
val, Maybe Integer
db, Maybe Bool
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 (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 (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 (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 (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 (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 :: 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 (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 (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 (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)
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' :: 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 (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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CLong -> Integer) -> Maybe CLong -> Maybe Integer
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 (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 (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 (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