module Xmobar.Plugins.Monitors.Bright (brightConfig, runBright) where
import Control.Exception (SomeException, handle)
import qualified Data.ByteString.Lazy.Char8 as B
import System.FilePath ((</>))
import System.Posix.Files (fileExist)
import System.Console.GetOpt
import Xmobar.Plugins.Monitors.Common
data BrightOpts = BrightOpts { BrightOpts -> String
subDir :: String
, BrightOpts -> String
currBright :: String
, BrightOpts -> String
maxBright :: String
, BrightOpts -> Maybe IconPattern
curBrightIconPattern :: Maybe IconPattern
}
defaultOpts :: BrightOpts
defaultOpts :: BrightOpts
defaultOpts = BrightOpts { subDir :: String
subDir = String
"acpi_video0"
, currBright :: String
currBright = String
"actual_brightness"
, maxBright :: String
maxBright = String
"max_brightness"
, curBrightIconPattern :: Maybe IconPattern
curBrightIconPattern = Maybe IconPattern
forall a. Maybe a
Nothing
}
options :: [OptDescr (BrightOpts -> BrightOpts)]
options :: [OptDescr (BrightOpts -> BrightOpts)]
options = [ String
-> [String]
-> ArgDescr (BrightOpts -> BrightOpts)
-> String
-> OptDescr (BrightOpts -> BrightOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"D" [String
"device"] ((String -> BrightOpts -> BrightOpts)
-> String -> ArgDescr (BrightOpts -> BrightOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x BrightOpts
o -> BrightOpts
o { subDir = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (BrightOpts -> BrightOpts)
-> String
-> OptDescr (BrightOpts -> BrightOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"C" [String
"curr"] ((String -> BrightOpts -> BrightOpts)
-> String -> ArgDescr (BrightOpts -> BrightOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x BrightOpts
o -> BrightOpts
o { currBright = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (BrightOpts -> BrightOpts)
-> String
-> OptDescr (BrightOpts -> BrightOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"M" [String
"max"] ((String -> BrightOpts -> BrightOpts)
-> String -> ArgDescr (BrightOpts -> BrightOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x BrightOpts
o -> BrightOpts
o { maxBright = x }) String
"") String
""
, String
-> [String]
-> ArgDescr (BrightOpts -> BrightOpts)
-> String
-> OptDescr (BrightOpts -> BrightOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"" [String
"brightness-icon-pattern"] ((String -> BrightOpts -> BrightOpts)
-> String -> ArgDescr (BrightOpts -> BrightOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x BrightOpts
o ->
BrightOpts
o { curBrightIconPattern = Just $ parseIconPattern x }) String
"") String
""
]
sysDir :: FilePath
sysDir :: String
sysDir = String
"/sys/class/backlight/"
brightConfig :: IO MConfig
brightConfig :: IO MConfig
brightConfig = String -> [String] -> IO MConfig
mkMConfig String
"<percent>"
[String
"vbar", String
"percent", String
"bar", String
"ipat"]
data Files = Files { Files -> String
fCurr :: String
, Files -> String
fMax :: String
}
| NoFiles
brightFiles :: BrightOpts -> IO Files
brightFiles :: BrightOpts -> IO Files
brightFiles BrightOpts
opts = do
is_curr <- String -> IO Bool
fileExist (String -> IO Bool) -> String -> IO Bool
forall a b. (a -> b) -> a -> b
$ Files -> String
fCurr Files
files
is_max <- fileExist $ fCurr files
return (if is_curr && is_max then files else NoFiles)
where prefix :: String
prefix = String
sysDir String -> String -> String
</> BrightOpts -> String
subDir BrightOpts
opts
files :: Files
files = Files { fCurr :: String
fCurr = String
prefix String -> String -> String
</> BrightOpts -> String
currBright BrightOpts
opts
, fMax :: String
fMax = String
prefix String -> String -> String
</> BrightOpts -> String
maxBright BrightOpts
opts
}
runBright :: [String] -> Monitor String
runBright :: [String] -> Monitor String
runBright [String]
args = do
opts <- IO BrightOpts -> Monitor BrightOpts
forall a. IO a -> Monitor a
io (IO BrightOpts -> Monitor BrightOpts)
-> IO BrightOpts -> Monitor BrightOpts
forall a b. (a -> b) -> a -> b
$ [OptDescr (BrightOpts -> BrightOpts)]
-> BrightOpts -> [String] -> IO BrightOpts
forall opts.
[OptDescr (opts -> opts)] -> opts -> [String] -> IO opts
parseOptsWith [OptDescr (BrightOpts -> BrightOpts)]
options BrightOpts
defaultOpts [String]
args
f <- io $ brightFiles opts
c <- io $ readBright f
case f of
Files
NoFiles -> String -> Monitor String
forall a. a -> ReaderT MConfig IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"hurz"
Files
_ -> BrightOpts -> Float -> Monitor [String]
fmtPercent BrightOpts
opts Float
c Monitor [String] -> ([String] -> Monitor String) -> Monitor String
forall a b.
ReaderT MConfig IO a
-> (a -> ReaderT MConfig IO b) -> ReaderT MConfig IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [String] -> Monitor String
parseTemplate
where fmtPercent :: BrightOpts -> Float -> Monitor [String]
fmtPercent :: BrightOpts -> Float -> Monitor [String]
fmtPercent BrightOpts
opts Float
c = do r <- Float -> Float -> Monitor String
showVerticalBar (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c) Float
c
s <- showPercentWithColors c
t <- showPercentBar (100 * c) c
d <- showIconPattern (curBrightIconPattern opts) c
return [r,s,t,d]
readBright :: Files -> IO Float
readBright :: Files -> IO Float
readBright Files
NoFiles = Float -> IO Float
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Float
0
readBright Files
files = do
currVal<- String -> IO Float
grab (String -> IO Float) -> String -> IO Float
forall a b. (a -> b) -> a -> b
$ Files -> String
fCurr Files
files
maxVal <- grab $ fMax files
return (currVal / maxVal)
where grab :: String -> IO Float
grab String
f = (SomeException -> IO Float) -> IO Float -> IO Float
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle SomeException -> IO Float
handler (String -> Float
forall a. Read a => String -> a
read (String -> Float) -> (ByteString -> String) -> ByteString -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
B.unpack (ByteString -> Float) -> IO ByteString -> IO Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
B.readFile String
f)
handler :: SomeException -> IO Float
handler = IO Float -> SomeException -> IO Float
forall a b. a -> b -> a
const (Float -> IO Float
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Float
0) :: SomeException -> IO Float