diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Plugins/Monitors.hs | 2 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Batt.hs | 38 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Bright.hs | 19 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Common.hs | 36 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Cpu.hs | 38 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Disk.hs | 79 | ||||
| -rw-r--r-- | src/Plugins/Monitors/MPD.hs | 9 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Mem.hs | 45 | ||||
| -rw-r--r-- | src/Plugins/Monitors/MultiCpu.hs | 50 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Net.hs | 55 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Volume.hs | 13 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Wireless.hs | 34 | 
12 files changed, 348 insertions, 70 deletions
| diff --git a/src/Plugins/Monitors.hs b/src/Plugins/Monitors.hs index 68ec3de..bee3c06 100644 --- a/src/Plugins/Monitors.hs +++ b/src/Plugins/Monitors.hs @@ -156,7 +156,7 @@ instance Exec Monitors where      start (Uptime a r) = runM a uptimeConfig runUptime r      start (CatInt _ s a r) = runM a catIntConfig (runCatInt s) r  #ifdef IWLIB -    start (Wireless i a r) = runM (a ++ [i]) wirelessConfig runWireless r +    start (Wireless i a r) = runM a wirelessConfig (runWireless i) r  #endif  #ifdef LIBMPD      start (MPD a r) = runMD a mpdConfig runMPD r mpdReady diff --git a/src/Plugins/Monitors/Batt.hs b/src/Plugins/Monitors/Batt.hs index ac8cb24..f7b31e4 100644 --- a/src/Plugins/Monitors/Batt.hs +++ b/src/Plugins/Monitors/Batt.hs @@ -34,6 +34,9 @@ data BattOpts = BattOpts    , highThreshold :: Float    , onlineFile :: FilePath    , scale :: Float +  , onIconPattern :: Maybe IconPattern +  , offIconPattern :: Maybe IconPattern +  , idleIconPattern :: Maybe IconPattern    }  defaultOpts :: BattOpts @@ -49,6 +52,9 @@ defaultOpts = BattOpts    , highThreshold = -10    , onlineFile = "AC/online"    , scale = 1e6 +  , onIconPattern = Nothing +  , offIconPattern = Nothing +  , idleIconPattern = Nothing    }  options :: [OptDescr (BattOpts -> BattOpts)] @@ -64,6 +70,12 @@ options =    , Option "H" ["hight"] (ReqArg (\x o -> o { highThreshold = read x }) "") ""    , Option "f" ["online"] (ReqArg (\x o -> o { onlineFile = x }) "") ""    , Option "s" ["scale"] (ReqArg (\x o -> o {scale = read x}) "") "" +  , Option "" ["on-icon-pattern"] (ReqArg (\x o -> +     o { onIconPattern = Just $ parseIconPattern x }) "") "" +  , Option "" ["off-icon-pattern"] (ReqArg (\x o -> +     o { offIconPattern = Just $ parseIconPattern x }) "") "" +  , Option "" ["idle-icon-pattern"] (ReqArg (\x o -> +     o { idleIconPattern = Just $ parseIconPattern x }) "") ""    ]  parseOpts :: [String] -> IO BattOpts @@ -72,7 +84,9 @@ parseOpts argv =      (o, _, []) -> return $ foldr id defaultOpts o      (_, _, errs) -> ioError . userError $ concat errs -data Result = Result Float Float Float String | NA +data Status = Charging | Discharging | Idle + +data Result = Result Float Float Float Status | NA  sysDir :: FilePath  sysDir = "/sys/class/power_supply" @@ -80,7 +94,7 @@ sysDir = "/sys/class/power_supply"  battConfig :: IO MConfig  battConfig = mkMConfig         "Batt: <watts>, <left>% / <timeleft>" -- template -       ["leftbar", "leftvbar", "left", "acstatus", "timeleft", "watts"] -- replacements +       ["leftbar", "leftvbar", "left", "acstatus", "timeleft", "watts", "leftipat"] -- replacements  data Files = Files    { fFull :: String @@ -150,10 +164,10 @@ readBatteries opts bfs =             time = if idle then 0 else sum $ map time' bats             mwatts = if idle then 1 else sign * watts             time' b = (if ac then full b - now b else now b) / mwatts -           acstr | idle      = idleString opts -                 | ac        = onString opts -                 | otherwise = offString opts -       return $ if isNaN left then NA else Result left watts time acstr +           acst | idle      = Idle +                | ac        = Charging +                | otherwise = Discharging +       return $ if isNaN left then NA else Result left watts time acst  runBatt :: [String] -> Monitor String  runBatt = runBatt' ["BAT0","BAT1","BAT2"] @@ -168,7 +182,8 @@ runBatt' bfs args = do      Result x w t s ->        do l <- fmtPercent x           ws <- fmtWatts w opts suffix d -         parseTemplate (l ++ [s, fmtTime $ floor t, ws]) +         si <- getIconPattern opts s x +         parseTemplate (l ++ [fmtStatus opts s, fmtTime $ floor t, ws, si])      NA -> getConfigValue naString    where fmtPercent :: Float -> Monitor [String]          fmtPercent x = do @@ -185,9 +200,18 @@ runBatt' bfs args = do                                      then minutes else '0' : minutes            where hours = show (x `div` 3600)                  minutes = show ((x `mod` 3600) `div` 60) +        fmtStatus opts Idle = idleString opts +        fmtStatus opts Charging = onString opts +        fmtStatus opts Discharging = offString opts          maybeColor Nothing str = str          maybeColor (Just c) str = "<fc=" ++ c ++ ">" ++ str ++ "</fc>"          color x o | x >= 0 = maybeColor (posColor o)                    | -x >= highThreshold o = maybeColor (highWColor o)                    | -x >= lowThreshold o = maybeColor (mediumWColor o)                    | otherwise = maybeColor (lowWColor o) +        getIconPattern opts status x = do +          let x' = minimum [1, x] +          case status of +               Idle -> showIconPattern (idleIconPattern opts) x' +               Charging -> showIconPattern (onIconPattern opts) x' +               Discharging -> showIconPattern (offIconPattern opts) x' diff --git a/src/Plugins/Monitors/Bright.hs b/src/Plugins/Monitors/Bright.hs index d29c5a4..cb510f6 100644 --- a/src/Plugins/Monitors/Bright.hs +++ b/src/Plugins/Monitors/Bright.hs @@ -26,18 +26,22 @@ import Plugins.Monitors.Common  data BrightOpts = BrightOpts { subDir :: String                               , currBright :: String                               , maxBright :: String +                             , curBrightIconPattern :: Maybe IconPattern                               }  defaultOpts :: BrightOpts  defaultOpts = BrightOpts { subDir = "acpi_video0"                           , currBright = "actual_brightness"                           , maxBright = "max_brightness" +                         , curBrightIconPattern = Nothing                           }  options :: [OptDescr (BrightOpts -> BrightOpts)]  options = [ Option "D" ["device"] (ReqArg (\x o -> o { subDir = x }) "") ""            , Option "C" ["curr"] (ReqArg (\x o -> o { currBright = x }) "") ""            , Option "M" ["max"] (ReqArg (\x o -> o { maxBright = x }) "") "" +          , Option "" ["brightness-icon-pattern"] (ReqArg (\x o -> +             o { curBrightIconPattern = Just $ parseIconPattern x }) "") ""            ]  -- from Batt.hs @@ -52,7 +56,7 @@ sysDir = "/sys/class/backlight/"  brightConfig :: IO MConfig  brightConfig = mkMConfig "<percent>" -- template -                         ["vbar", "percent", "bar"] -- replacements +                         ["vbar", "percent", "bar", "ipat"] -- replacements  data Files = Files { fCurr :: String                     , fMax :: String @@ -76,12 +80,13 @@ runBright args = do    c <- io $ readBright f    case f of      NoFiles -> return "hurz" -    _ -> fmtPercent c >>= parseTemplate -  where fmtPercent :: Float -> Monitor [String] -        fmtPercent c = do r <- showVerticalBar (100 * c) c -                          s <- showPercentWithColors c -                          t <- showPercentBar (100 * c) c -                          return [r,s,t] +    _ -> fmtPercent opts c >>= parseTemplate +  where fmtPercent :: BrightOpts -> Float -> Monitor [String] +        fmtPercent opts c = do r <- showVerticalBar (100 * c) c +                               s <- showPercentWithColors c +                               t <- showPercentBar (100 * c) c +                               d <- showIconPattern (curBrightIconPattern opts) c +                               return [r,s,t,d]  readBright :: Files -> IO Float  readBright NoFiles = return 0 diff --git a/src/Plugins/Monitors/Common.hs b/src/Plugins/Monitors/Common.hs index 971de16..7d11258 100644 --- a/src/Plugins/Monitors/Common.hs +++ b/src/Plugins/Monitors/Common.hs @@ -40,6 +40,8 @@ module Plugins.Monitors.Common (                         , parseTemplate'                         -- ** String Manipulation                         -- $strings +                       , IconPattern +                       , parseIconPattern                         , padString                         , showWithPadding                         , showWithColors @@ -48,8 +50,10 @@ module Plugins.Monitors.Common (                         , showPercentsWithColors                         , showPercentBar                         , showVerticalBar +                       , showIconPattern                         , showLogBar                         , showLogVBar +                       , showLogIconPattern                         , showWithUnits                         , takeDigits                         , showDigits @@ -348,6 +352,18 @@ combine m ((s,ts,ss):xs) =  -- $strings +type IconPattern = Int -> String + +parseIconPattern :: String -> IconPattern +parseIconPattern path = +    let spl = splitOnPercent path +    in \i -> concat $ intersperse (show i) spl +  where splitOnPercent [] = [[]] +        splitOnPercent ('%':'%':xs) = [] : splitOnPercent xs +        splitOnPercent (x:xs) = +            let rest = splitOnPercent xs +            in (x : head rest) : tail rest +  type Pos = (Int, Int)  takeDigits :: Int -> Float -> Float @@ -453,6 +469,15 @@ showPercentBar v x = do    s <- colorizeString v (take len $ cycle bf)    return $ s ++ take (bw - len) (cycle bb) +showIconPattern :: Maybe IconPattern -> Float -> Monitor String +showIconPattern Nothing _ = return "" +showIconPattern (Just str) x = return $ str $ convert $ 100 * x +  where convert val +          | t <= 0 = 0 +          | t > 8 = 8 +          | otherwise = t +          where t = round val `div` 12 +  showVerticalBar :: Float -> Float -> Monitor String  showVerticalBar v x = colorizeString v [convert $ 100 * x]    where convert :: Float -> Char @@ -485,3 +510,14 @@ showLogVBar f v = do                 | x <= ll = 1 / bw                 | otherwise = f + logBase 2 (x / hh) / bw    showVerticalBar v $ choose v + +showLogIconPattern :: Maybe IconPattern -> Float -> Float -> Monitor String +showLogIconPattern str f v = do +  h <- fromIntegral `fmap` getConfigValue high +  l <- fromIntegral `fmap` getConfigValue low +  bw <- fromIntegral `fmap` getConfigValue barWidth +  let [ll, hh] = sort [l, h] +      choose x | x == 0.0 = 0 +               | x <= ll = 1 / bw +               | otherwise = f + logBase 2 (x / hh) / bw +  showIconPattern str $ choose v diff --git a/src/Plugins/Monitors/Cpu.hs b/src/Plugins/Monitors/Cpu.hs index 10d945f..7fed989 100644 --- a/src/Plugins/Monitors/Cpu.hs +++ b/src/Plugins/Monitors/Cpu.hs @@ -18,11 +18,33 @@ module Plugins.Monitors.Cpu (startCpu) where  import Plugins.Monitors.Common  import qualified Data.ByteString.Lazy.Char8 as B  import Data.IORef (IORef, newIORef, readIORef, writeIORef) +import System.Console.GetOpt + +data CpuOpts = CpuOpts +  { loadIconPattern :: Maybe IconPattern +  } + +defaultOpts :: CpuOpts +defaultOpts = CpuOpts +  { loadIconPattern = Nothing +  } + +options :: [OptDescr (CpuOpts -> CpuOpts)] +options = +  [ Option "" ["load-icon-pattern"] (ReqArg (\x o -> +     o { loadIconPattern = Just $ parseIconPattern x }) "") "" +  ] + +parseOpts :: [String] -> IO CpuOpts +parseOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs  cpuConfig :: IO MConfig  cpuConfig = mkMConfig         "Cpu: <total>%" -       ["bar","vbar","total","user","nice","system","idle","iowait"] +       ["bar","vbar","ipat","total","user","nice","system","idle","iowait"]  type CpuDataRef = IORef [Int] @@ -42,19 +64,21 @@ parseCpu cref =             percent = map ((/ tot) . fromIntegral) dif         return percent -formatCpu :: [Float] -> Monitor [String] -formatCpu [] = return $ replicate 8 "" -formatCpu xs = do +formatCpu :: CpuOpts -> [Float] -> Monitor [String] +formatCpu _ [] = return $ replicate 8 "" +formatCpu opts xs = do    let t = sum $ take 3 xs    b <- showPercentBar (100 * t) t    v <- showVerticalBar (100 * t) t +  d <- showIconPattern (loadIconPattern opts) t    ps <- showPercentsWithColors (t:xs) -  return (b:v:ps) +  return (b:v:d:ps)  runCpu :: CpuDataRef -> [String] -> Monitor String -runCpu cref _ = +runCpu cref argv =      do c <- io (parseCpu cref) -       l <- formatCpu c +       opts <- io $ parseOpts argv +       l <- formatCpu opts c         parseTemplate l  startCpu :: [String] -> Int -> (String -> IO ()) -> IO () diff --git a/src/Plugins/Monitors/Disk.hs b/src/Plugins/Monitors/Disk.hs index b43aede..0019c1a 100644 --- a/src/Plugins/Monitors/Disk.hs +++ b/src/Plugins/Monitors/Disk.hs @@ -25,16 +25,67 @@ import qualified Data.ByteString.Lazy.Char8 as B  import Data.List (isPrefixOf, find)  import Data.Maybe (catMaybes)  import System.Directory (canonicalizePath, doesFileExist) +import System.Console.GetOpt + +data DiskIOOpts = DiskIOOpts +  { totalIconPattern :: Maybe IconPattern +  , writeIconPattern :: Maybe IconPattern +  , readIconPattern :: Maybe IconPattern +  } + +parseDiskIOOpts :: [String] -> IO DiskIOOpts +parseDiskIOOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs + where defaultOpts = DiskIOOpts +          { totalIconPattern = Nothing +          , writeIconPattern = Nothing +          , readIconPattern = Nothing +          } +       options = +          [ Option "" ["total-icon-pattern"] (ReqArg (\x o -> +             o { totalIconPattern = Just $ parseIconPattern x}) "") "" +          , Option "" ["write-icon-pattern"] (ReqArg (\x o -> +             o { writeIconPattern = Just $ parseIconPattern x}) "") "" +          , Option "" ["read-icon-pattern"] (ReqArg (\x o -> +             o { readIconPattern = Just $ parseIconPattern x}) "") "" +          ]  diskIOConfig :: IO MConfig  diskIOConfig = mkMConfig "" ["total", "read", "write"                              ,"totalbar", "readbar", "writebar"                              ,"totalvbar", "readvbar", "writevbar" +                            ,"totalipat", "readipat", "writeipat"                              ] +data DiskUOpts = DiskUOpts +  { freeIconPattern :: Maybe IconPattern +  , usedIconPattern :: Maybe IconPattern +  } + +parseDiskUOpts :: [String] -> IO DiskUOpts +parseDiskUOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs + where defaultOpts = DiskUOpts +          { freeIconPattern = Nothing +          , usedIconPattern = Nothing +          } +       options = +          [ Option "" ["free-icon-pattern"] (ReqArg (\x o -> +             o { freeIconPattern = Just $ parseIconPattern x}) "") "" +          , Option "" ["used-icon-pattern"] (ReqArg (\x o -> +             o { usedIconPattern = Just $ parseIconPattern x}) "") "" +          ] +  diskUConfig :: IO MConfig  diskUConfig = mkMConfig "" -              ["size", "free", "used", "freep", "usedp", "freebar", "freevbar", "usedbar", "usedvbar"] +              [ "size", "free", "used", "freep", "usedp" +              , "freebar", "freevbar", "freeipat" +              , "usedbar", "usedvbar", "usedipat" +              ]  type DevName = String  type Path = String @@ -127,19 +178,22 @@ devTemplates disks mounted dat =                           Nothing -> [0, 0, 0]                           Just (_, xs) -> xs -runDiskIO' :: (String, [Float]) -> Monitor String -runDiskIO' (tmp, xs) = do +runDiskIO' :: DiskIOOpts -> (String, [Float]) -> Monitor String +runDiskIO' opts (tmp, xs) = do    s <- mapM (showWithColors speedToStr) xs    b <- mapM (showLogBar 0.8) xs    vb <- mapM (showLogVBar 0.8) xs +  ipat <- mapM (\(f,v) -> showLogIconPattern (f opts) 0.8 v) +        $ zip [totalIconPattern, readIconPattern, writeIconPattern] xs    setConfigValue tmp template -  parseTemplate $ s ++ b ++ vb +  parseTemplate $ s ++ b ++ vb ++ ipat  runDiskIO :: DevDataRef -> [(String, String)] -> [String] -> Monitor String -runDiskIO dref disks _ = do +runDiskIO dref disks argv = do +  opts <- io $ parseDiskIOOpts argv    dev <- io $ mountedOrDiskDevices (map fst disks)    dat <- io $ mountedData dref (map fst dev) -  strs <- mapM runDiskIO' $ devTemplates disks dev dat +  strs <- mapM (runDiskIO' opts) $ devTemplates disks dev dat    return $ unwords strs  startDiskIO :: [(String, String)] -> @@ -160,8 +214,8 @@ fsStats path = do                    used = fsStatBytesUsed f                in return [tot, free, used] -runDiskU' :: String -> String -> Monitor String -runDiskU' tmp path = do +runDiskU' :: DiskUOpts -> String -> String -> Monitor String +runDiskU' opts tmp path = do    setConfigValue tmp template    [total, free, diff] <-  io (handle ign $ fsStats path)    let strs = map sizeToStr [free, diff] @@ -171,14 +225,17 @@ runDiskU' tmp path = do    sp <- showPercentsWithColors [fr, 1 - fr]    fb <- showPercentBar (fromIntegral freep) fr    fvb <- showVerticalBar (fromIntegral freep) fr +  fipat <- showIconPattern (freeIconPattern opts) fr    ub <- showPercentBar (fromIntegral $ 100 - freep) (1 - fr)    uvb <- showVerticalBar (fromIntegral $ 100 - freep) (1 - fr) -  parseTemplate $ [sizeToStr total] ++ s ++ sp ++ [fb,fvb,ub,uvb] +  uipat <- showIconPattern (usedIconPattern opts) (1 - fr) +  parseTemplate $ [sizeToStr total] ++ s ++ sp ++ [fb,fvb,fipat,ub,uvb,uipat]    where ign = const (return [0, 0, 0]) :: SomeException -> IO [Integer]  runDiskU :: [(String, String)] -> [String] -> Monitor String -runDiskU disks _ = do +runDiskU disks argv = do    devs <- io $ mountedDevices (map fst disks) -  strs <- mapM (\(d, p) -> runDiskU' (findTempl d p disks) p) devs +  opts <- io $ parseDiskUOpts argv +  strs <- mapM (\(d, p) -> runDiskU' opts (findTempl d p disks) p) devs    return $ unwords strs diff --git a/src/Plugins/Monitors/MPD.hs b/src/Plugins/Monitors/MPD.hs index ac976f2..1a49ad3 100644 --- a/src/Plugins/Monitors/MPD.hs +++ b/src/Plugins/Monitors/MPD.hs @@ -22,7 +22,7 @@ import Control.Concurrent (threadDelay)  mpdConfig :: IO MConfig  mpdConfig = mkMConfig "MPD: <state>" -              [ "bar", "vbar", "state", "statei", "volume", "length" +              [ "bar", "vbar", "ipat", "state", "statei", "volume", "length"                , "lapsed", "remaining", "plength", "ppos", "file"                , "name", "artist", "composer", "performer"                , "album", "title", "track", "genre" @@ -32,6 +32,7 @@ data MOpts = MOpts    { mPlaying :: String    , mStopped :: String    , mPaused :: String +  , mLapsedIconPattern :: Maybe IconPattern    }  defaultOpts :: MOpts @@ -39,6 +40,7 @@ defaultOpts = MOpts    { mPlaying = ">>"    , mStopped = "><"    , mPaused = "||" +  , mLapsedIconPattern = Nothing    }  options :: [OptDescr (MOpts -> MOpts)] @@ -46,6 +48,8 @@ options =    [ Option "P" ["playing"] (ReqArg (\x o -> o { mPlaying = x }) "") ""    , Option "S" ["stopped"] (ReqArg (\x o -> o { mStopped = x }) "") ""    , Option "Z" ["paused"] (ReqArg (\x o -> o { mPaused = x }) "") "" +  , Option "" ["lapsed-icon-pattern"] (ReqArg (\x o -> +     o { mLapsedIconPattern = Just $ parseIconPattern x }) "") ""    ]  runMPD :: [String] -> Monitor String @@ -87,7 +91,8 @@ parseMPD (Right st) song opts = do    songData <- parseSong song    bar <- showPercentBar (100 * b) b    vbar <- showVerticalBar (100 * b) b -  return $ [bar, vbar, ss, si, vol, len, lap, remain, plen, ppos] ++ songData +  ipat <- showIconPattern (mLapsedIconPattern opts) b +  return $ [bar, vbar, ipat, ss, si, vol, len, lap, remain, plen, ppos] ++ songData    where s = M.stState st          ss = show s          si = stateGlyph s opts diff --git a/src/Plugins/Monitors/Mem.hs b/src/Plugins/Monitors/Mem.hs index db2e5de..b19c5a7 100644 --- a/src/Plugins/Monitors/Mem.hs +++ b/src/Plugins/Monitors/Mem.hs @@ -16,12 +16,38 @@ module Plugins.Monitors.Mem (memConfig, runMem, totalMem, usedMem) where  import Plugins.Monitors.Common  import qualified Data.Map as M +import System.Console.GetOpt + +data MemOpts = MemOpts +  { usedIconPattern :: Maybe IconPattern +  , freeIconPattern :: Maybe IconPattern +  } + +defaultOpts :: MemOpts +defaultOpts = MemOpts +  { usedIconPattern = Nothing +  , freeIconPattern = Nothing +  } + +options :: [OptDescr (MemOpts -> MemOpts)] +options = +  [ Option "" ["used-icon-pattern"] (ReqArg (\x o -> +     o { usedIconPattern = Just $ parseIconPattern x }) "") "" +  , Option "" ["free-icon-pattern"] (ReqArg (\x o -> +     o { freeIconPattern = Just $ parseIconPattern x }) "") "" +  ] + +parseOpts :: [String] -> IO MemOpts +parseOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs  memConfig :: IO MConfig  memConfig = mkMConfig         "Mem: <usedratio>% (<cache>M)" -- template -       ["usedbar", "usedvbar", "freebar", "freevbar", "usedratio", "freeratio", "total", -        "free", "buffer", "cache", "rest", "used"] -- available replacements +       ["usedbar", "usedvbar", "usedipat", "freebar", "freevbar", "freeipat", "usedratio", "freeratio", +        "total", "free", "buffer", "cache", "rest", "used"] -- available replacements  fileMEM :: IO String  fileMEM = readFile "/proc/meminfo" @@ -44,22 +70,25 @@ totalMem = fmap ((*1024) . (!!1)) parseMEM  usedMem :: IO Float  usedMem = fmap ((*1024) . (!!6)) parseMEM -formatMem :: [Float] -> Monitor [String] -formatMem (r:fr:xs) = +formatMem :: MemOpts -> [Float] -> Monitor [String] +formatMem opts (r:fr:xs) =      do let f = showDigits 0             rr = 100 * r         ub <- showPercentBar rr r         uvb <- showVerticalBar rr r +       uipat <- showIconPattern (usedIconPattern opts) r         fb <- showPercentBar (100 - rr) (1 - r)         fvb <- showVerticalBar (100 - rr) ( 1 - r) +       fipat <- showIconPattern (freeIconPattern opts) (1 - r)         rs <- showPercentWithColors r         fs <- showPercentWithColors fr         s <- mapM (showWithColors f) xs -       return (ub:uvb:fb:fvb:rs:fs:s) -formatMem _ = replicate 10 `fmap` getConfigValue naString +       return (ub:uvb:uipat:fb:fvb:fipat:rs:fs:s) +formatMem _ _ = replicate 10 `fmap` getConfigValue naString  runMem :: [String] -> Monitor String -runMem _ = +runMem argv =      do m <- io parseMEM -       l <- formatMem m +       opts <- io $ parseOpts argv +       l <- formatMem opts m         parseTemplate l diff --git a/src/Plugins/Monitors/MultiCpu.hs b/src/Plugins/Monitors/MultiCpu.hs index 150fb7e..eab21da 100644 --- a/src/Plugins/Monitors/MultiCpu.hs +++ b/src/Plugins/Monitors/MultiCpu.hs @@ -19,9 +19,35 @@ import Control.Applicative ((<$>))  import qualified Data.ByteString.Lazy.Char8 as B  import Data.List (isPrefixOf, transpose, unfoldr)  import Data.IORef (IORef, newIORef, readIORef, writeIORef) +import System.Console.GetOpt + +data MultiCpuOpts = MultiCpuOpts +  { loadIconPatterns :: [IconPattern] +  , loadIconPattern :: Maybe IconPattern +  } + +defaultOpts :: MultiCpuOpts +defaultOpts = MultiCpuOpts +  { loadIconPatterns = [] +  , loadIconPattern = Nothing +  } + +options :: [OptDescr (MultiCpuOpts -> MultiCpuOpts)] +options = +  [ Option "" ["load-icon-pattern"] (ReqArg (\x o -> +     o { loadIconPattern = Just $ parseIconPattern x }) "") "" +  , Option "" ["load-icon-patterns"] (ReqArg (\x o -> +     o { loadIconPatterns = parseIconPattern x : loadIconPatterns o }) "") "" +  ] + +parseOpts :: [String] -> IO MultiCpuOpts +parseOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs  variables :: [String] -variables = ["bar", "vbar","total","user","nice","system","idle"] +variables = ["bar", "vbar","ipat","total","user","nice","system","idle"]  vNum :: Int  vNum = length variables @@ -55,18 +81,23 @@ percent b a = if tot > 0 then map (/ tot) $ take 4 dif else [0, 0, 0, 0]    where dif = zipWith (-) b a          tot = sum dif -formatMultiCpus :: [[Float]] -> Monitor [String] -formatMultiCpus [] = return [] -formatMultiCpus xs = concat <$> mapM formatCpu xs +formatMultiCpus :: MultiCpuOpts -> [[Float]] -> Monitor [String] +formatMultiCpus _ [] = return [] +formatMultiCpus opts xs = concat <$> mapM (\(i, x) -> formatCpu opts i x) (zip [0..] xs) -formatCpu :: [Float] -> Monitor [String] -formatCpu xs +formatCpu :: MultiCpuOpts -> Int -> [Float] -> Monitor [String] +formatCpu opts i xs    | length xs < 4 = showPercentsWithColors $ replicate vNum 0.0    | otherwise = let t = sum $ take 3 xs                  in do b <- showPercentBar (100 * t) t                        h <- showVerticalBar (100 * t) t +                      d <- showIconPattern tryString t                        ps <- showPercentsWithColors (t:xs) -                      return (b:h:ps) +                      return (b:h:d:ps) +  where tryString +          | i == 0 = loadIconPattern opts +          | i <= length (loadIconPatterns opts) = Just $ (loadIconPatterns opts) !! (i - 1) +          | otherwise = Nothing  splitEvery :: (Eq a) => Int -> [a] -> [[a]]  splitEvery n = unfoldr (\x -> if null x then Nothing else Just $ splitAt n x) @@ -79,9 +110,10 @@ formatAutoCpus [] = return $ replicate vNum ""  formatAutoCpus xs = return $ map unwords (groupData xs)  runMultiCpu :: CpuDataRef -> [String] -> Monitor String -runMultiCpu cref _ = +runMultiCpu cref argv =    do c <- io $ parseCpuData cref -     l <- formatMultiCpus c +     opts <- io $ parseOpts argv +     l <- formatMultiCpus opts c       a <- formatAutoCpus l       parseTemplate $ a ++ l diff --git a/src/Plugins/Monitors/Net.hs b/src/Plugins/Monitors/Net.hs index 51c760c..5954a77 100644 --- a/src/Plugins/Monitors/Net.hs +++ b/src/Plugins/Monitors/Net.hs @@ -25,9 +25,35 @@ import Data.Time.Clock (UTCTime, getCurrentTime, diffUTCTime)  import Control.Monad (forM, filterM, liftM)  import System.Directory (getDirectoryContents, doesFileExist)  import System.FilePath ((</>)) +import System.Console.GetOpt  import qualified Data.ByteString.Lazy.Char8 as B +data NetOpts = NetOpts +  { rxIconPattern :: Maybe IconPattern +  , txIconPattern :: Maybe IconPattern +  } + +defaultOpts :: NetOpts +defaultOpts = NetOpts +  { rxIconPattern = Nothing +  , txIconPattern = Nothing +  } + +options :: [OptDescr (NetOpts -> NetOpts)] +options = +  [ Option "" ["rx-icon-pattern"] (ReqArg (\x o -> +     o { rxIconPattern = Just $ parseIconPattern x }) "") "" +  , Option "" ["tx-icon-pattern"] (ReqArg (\x o -> +     o { txIconPattern = Just $ parseIconPattern x }) "") "" +  ] + +parseOpts :: [String] -> IO NetOpts +parseOpts argv = +  case getOpt Permute options argv of +    (o, _, []) -> return $ foldr id defaultOpts o +    (_, _, errs) -> ioError . userError $ concat errs +  data UnitPerSec = Bs | KBs | MBs | GBs deriving (Eq,Enum,Ord)  data NetValue = NetValue Float UnitPerSec deriving (Eq,Show) @@ -62,7 +88,7 @@ instance Ord NetDev where  netConfig :: IO MConfig  netConfig = mkMConfig      "<dev>: <rx>KB|<tx>KB"      -- template -    ["dev", "rx", "tx", "rxbar", "rxvbar", "txbar", "txvbar"]     -- available replacements +    ["dev", "rx", "tx", "rxbar", "rxvbar", "rxipat", "txbar", "txvbar", "txipat"]     -- available replacements  operstateDir :: String -> FilePath  operstateDir d = "/sys/class/net" </> d </> "operstate" @@ -106,8 +132,8 @@ findNetDev dev = do          isDev (NI d) = d == dev          isDev NA = False -formatNet :: Float -> Monitor (String, String, String) -formatNet d = do +formatNet :: Maybe IconPattern -> Float -> Monitor (String, String, String, String) +formatNet mipat d = do      s <- getConfigValue useSuffix      dd <- getConfigValue decDigits      let str True v = showDigits dd d' ++ show u @@ -115,16 +141,17 @@ formatNet d = do          str False v = showDigits dd $ v / 1024      b <- showLogBar 0.9 d      vb <- showLogVBar 0.9 d +    ipat <- showLogIconPattern mipat 0.9 d      x <- showWithColors (str s) d -    return (x, b, vb) +    return (x, b, vb, ipat) -printNet :: NetDev -> Monitor String -printNet nd = +printNet :: NetOpts -> NetDev -> Monitor String +printNet opts nd =    case nd of      ND d r t -> do -        (rx, rb, rvb) <- formatNet r -        (tx, tb, tvb) <- formatNet t -        parseTemplate [d,rx,tx,rb,rvb,tb,tvb] +        (rx, rb, rvb, ripat) <- formatNet (rxIconPattern opts) r +        (tx, tb, tvb, tipat) <- formatNet (txIconPattern opts) t +        parseTemplate [d,rx,tx,rb,rvb,ripat,tb,tvb,tipat]      NI _ -> return ""      NA -> getConfigValue naString @@ -144,13 +171,19 @@ parseNet nref nd = do    return $ diffRate n0 n1  runNet :: NetDevRef -> String -> [String] -> Monitor String -runNet nref i _ = io (parseNet nref i) >>= printNet +runNet nref i argv = do +  dev <- io $ parseNet nref i +  opts <- io $ parseOpts argv +  printNet opts dev  parseNets :: [(NetDevRef, String)] -> IO [NetDev]  parseNets = mapM $ uncurry parseNet  runNets :: [(NetDevRef, String)] -> [String] -> Monitor String -runNets refs _ = io (parseActive refs) >>= printNet +runNets refs argv = do +  dev <- io $ parseActive refs +  opts <- io $ parseOpts argv +  printNet opts dev      where parseActive refs' = liftM selectActive (parseNets refs')             selectActive = maximum diff --git a/src/Plugins/Monitors/Volume.hs b/src/Plugins/Monitors/Volume.hs index 22b7f6c..8c39b9f 100644 --- a/src/Plugins/Monitors/Volume.hs +++ b/src/Plugins/Monitors/Volume.hs @@ -24,7 +24,7 @@ import System.Console.GetOpt  volumeConfig :: IO MConfig  volumeConfig = mkMConfig "Vol: <volume>% <status>" -                         ["volume", "volumebar", "volumevbar", "dB","status"] +                         ["volume", "volumebar", "volumevbar", "dB","status", "volumeipat"]  data VolumeOpts = VolumeOpts @@ -34,6 +34,7 @@ data VolumeOpts = VolumeOpts      , offColor :: Maybe String      , highDbThresh :: Float      , lowDbThresh :: Float +    , volumeIconPattern :: Maybe IconPattern      }  defaultOpts :: VolumeOpts @@ -44,6 +45,7 @@ defaultOpts = VolumeOpts      , offColor = Just "red"      , highDbThresh = -5.0      , lowDbThresh = -30.0 +    , volumeIconPattern = Nothing      }  options :: [OptDescr (VolumeOpts -> VolumeOpts)] @@ -54,6 +56,8 @@ options =      , Option "" ["highd"] (ReqArg (\x o -> o { highDbThresh = read x }) "") ""      , Option "C" ["onc"] (ReqArg (\x o -> o { onColor = Just x }) "") ""      , Option "c" ["offc"] (ReqArg (\x o -> o { offColor = Just x }) "") "" +    , Option "" ["volume-icon-pattern"] (ReqArg (\x o -> +       o { volumeIconPattern = Just $ parseIconPattern x }) "") ""      ]  parseOpts :: [String] -> IO VolumeOpts @@ -80,6 +84,10 @@ formatVolVBar :: Integer -> Integer -> Integer -> Monitor String  formatVolVBar lo hi v =      showVerticalBar (100 * x) x where x = percent v lo hi +formatVolDStr :: Maybe IconPattern -> Integer -> Integer -> Integer -> Monitor String +formatVolDStr ipat lo hi v = +    showIconPattern ipat $ percent v lo hi +  switchHelper :: VolumeOpts               -> (VolumeOpts -> Maybe String)               -> (VolumeOpts -> String) @@ -126,7 +134,8 @@ runVolume mixerName controlName argv = do      v <- liftMonitor $ liftM3 formatVolVBar lo hi val      d <- getFormatDB opts db      s <- getFormatSwitch opts sw -    parseTemplate [p, b, v, d, s] +    ipat <- liftMonitor $ liftM3 (formatVolDStr $ volumeIconPattern opts) lo hi val +    parseTemplate [p, b, v, d, s, ipat]    where diff --git a/src/Plugins/Monitors/Wireless.hs b/src/Plugins/Monitors/Wireless.hs index c6e6b44..b1e3c7e 100644 --- a/src/Plugins/Monitors/Wireless.hs +++ b/src/Plugins/Monitors/Wireless.hs @@ -14,15 +14,39 @@  module Plugins.Monitors.Wireless (wirelessConfig, runWireless)  where +import System.Console.GetOpt +  import Plugins.Monitors.Common  import IWlib +data WirelessOpts = WirelessOpts +  { qualityIconPattern :: Maybe IconPattern +  } + +defaultOpts :: WirelessOpts +defaultOpts = WirelessOpts +  { qualityIconPattern = Nothing +  } + +options :: [OptDescr (WirelessOpts -> WirelessOpts)] +options = +  [ Option "" ["quality-icon-pattern"] (ReqArg (\d opts -> +     opts { qualityIconPattern = Just $ parseIconPattern d }) "") "" +  ] + +parseOpts :: [String] -> IO WirelessOpts +parseOpts argv = +  case getOpt Permute options argv of +       (o, _, []) -> return $ foldr id defaultOpts o +       (_, _, errs) -> ioError . userError $ concat errs +  wirelessConfig :: IO MConfig  wirelessConfig = -  mkMConfig "<essid> <quality>" ["essid", "quality", "qualitybar", "qualityvbar"] +  mkMConfig "<essid> <quality>" ["essid", "quality", "qualitybar", "qualityvbar", "qualityipat"] -runWireless :: [String] -> Monitor String -runWireless (iface:_) = do +runWireless :: String -> [String] -> Monitor String +runWireless iface args = do +  opts <- io $ parseOpts args    wi <- io $ getWirelessInfo iface    na <- getConfigValue naString    let essid = wiEssid wi @@ -34,5 +58,5 @@ runWireless (iface:_) = do         else showWithPadding ""    qb <- showPercentBar qlty (qlty / 100)    qvb <- showVerticalBar qlty (qlty / 100) -  parseTemplate [ep, q, qb, qvb] -runWireless _ = getConfigValue naString +  qipat <- showIconPattern (qualityIconPattern opts) (qlty / 100) +  parseTemplate [ep, q, qb, qvb, qipat] | 
