diff options
| -rw-r--r-- | README | 33 | ||||
| -rw-r--r-- | src/Plugins/Monitors.hs | 12 | ||||
| -rw-r--r-- | src/Plugins/Monitors/Volume.hs | 122 | ||||
| -rw-r--r-- | xmobar.cabal | 9 | 
4 files changed, 176 insertions, 0 deletions
| @@ -120,6 +120,10 @@ Otherwise, you'll need to install them yourself.       headers in your system (e.g., install `libiw-dev` in Debian-based       systems). +`with_alsa` +:    Support for ALSA sound cards. Enables the Volume plugin. Requires the +     [alsa-mixer] package. +  `all_extensions`  :    Enables all the extensions above. @@ -616,6 +620,34 @@ Monitors have default aliases.           Run MBox [("I ", "inbox", "red"), ("O ", "~/foo/mbox", "")]                    ["-d", "/var/mail/", "-p", " "] "mbox" +`Volume Mixer Element Args RefreshRate` + +- Aliases to the mixer name and element name separated by a colon. Thus, +  `Volume "default" "Master" [] 10` can be used as `%default:Master%`. +- Args: default monitor arguments (see below). Also accepts: +    - `-O` _string_ On string +        - The string used in place of `<status>` when the mixer element +          is on. +        - Long option: `--on` +    - `-o` _string_ Off string +        - The string used in place of `<status>` when the mixer element +          is off. +        - Long option: `--off` +    - `-C` _color_ On color +        - The color to be used for `<status>` when the mixer element is on. +        - Long option: `--onc` +    - `-c` _color_ Off color +        - The color to be used for `<status>` when the mixer element is off. +        - Long option: `--offc` +    - `--highd` _number_ High threshold for dB +    - `--lowd` _number_ Low threshold for dB +- Variables that can be used with the `-t`/`--template` argument: +            `volume`, `dB`, `status` +- Default template: `Vol: <volume>% <fc=green><on></fc><fc=red><off></fc>` +- Requires the package [alsa-mixer] installed in your system. In addition, +  to activate this plugin you must pass `--flags="with_alsa"` during +  compilation. +  `XPropertyLog PropName`  - Aliases to `PropName` @@ -998,3 +1030,4 @@ Copyright © 2010 Jose Antonio Ortega Ruiz  [libmpd]: http://hackage.haskell.org/package/libmpd/  [sawfish]: http://sawfish.wikia.com/  [utf8-string]: http://hackage.haskell.org/package/utf8-string/ +[alsa-mixer]: http://hackage.haskell.org/package/alsa-mixer diff --git a/src/Plugins/Monitors.hs b/src/Plugins/Monitors.hs index 9887d74..14d97a2 100644 --- a/src/Plugins/Monitors.hs +++ b/src/Plugins/Monitors.hs @@ -38,6 +38,9 @@ import Plugins.Monitors.Wireless  #ifdef LIBMPD  import Plugins.Monitors.MPD  #endif +#ifdef ALSA +import Plugins.Monitors.Volume +#endif  data Monitors = Weather  Station    Args Rate                | Network  Interface  Args Rate @@ -61,6 +64,9 @@ data Monitors = Weather  Station    Args Rate  #ifdef LIBMPD                | MPD      Args       Rate  #endif +#ifdef ALSA +              | Volume   String     String Args Rate +#endif                  deriving (Show,Read,Eq)  type Args      = [String] @@ -95,6 +101,9 @@ instance Exec Monitors where  #ifdef LIBMPD      alias (MPD        _ _) = "mpd"  #endif +#ifdef ALSA +    alias (Volume m c _ _) = m ++ ":" ++ c +#endif      start (Weather  s a r) = runM (a ++ [s]) weatherConfig  runWeather    r      start (Network  i a r) = runM (a ++ [i]) netConfig      runNet        r      start (Thermal  z a r) = runM (a ++ [z]) thermalConfig  runThermal    r @@ -117,3 +126,6 @@ instance Exec Monitors where  #ifdef LIBMPD      start (MPD        a r) = runM a          mpdConfig      runMPD        r  #endif +#ifdef ALSA +    start (Volume m c a r) = runM a          volumeConfig  (runVolume m c) r +#endif diff --git a/src/Plugins/Monitors/Volume.hs b/src/Plugins/Monitors/Volume.hs new file mode 100644 index 0000000..72a9b0e --- /dev/null +++ b/src/Plugins/Monitors/Volume.hs @@ -0,0 +1,122 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Plugins.Monitors.Volume +-- Copyright   :  (c) 2011 Thomas Tuegel +-- License     :  BSD-style (see LICENSE) +-- +-- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- A monitor for ALSA soundcards +-- +----------------------------------------------------------------------------- + +module Plugins.Monitors.Volume (runVolume, volumeConfig) where + +import Control.Monad ( liftM ) +import Data.Maybe +import Plugins.Monitors.Common +import Sound.ALSA.Mixer +import System.Console.GetOpt + +data VolumeOpts = VolumeOpts +    { onString :: String +    , offString :: String +    , onColor :: Maybe String +    , offColor :: Maybe String +    , highDbThresh :: Float +    , lowDbThresh :: Float +    } + +defaultOpts :: VolumeOpts +defaultOpts = VolumeOpts +    { onString = "[on] " +    , offString = "[off]" +    , onColor = Just "green" +    , offColor = Just "red" +    , highDbThresh = -5.0 +    , lowDbThresh = -30.0 +    } + +options :: [OptDescr (VolumeOpts -> VolumeOpts)] +options = +    [ Option "O" ["on"] (ReqArg (\x o -> o { onString = x }) "") "" +    , Option "o" ["off"] (ReqArg (\x o -> o { offString = x }) "") "" +    , Option "" ["lowd"] (ReqArg (\x o -> o { lowDbThresh = read x }) "") "" +    , 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 }) "") "" +    ] + +parseOpts :: [String] -> IO VolumeOpts +parseOpts argv = +    case getOpt Permute options argv of +        (o, _, []) -> return $ foldr id defaultOpts o +        (_, _, errs) -> ioError . userError $ concat errs + +percent :: Integer -> Integer -> Integer -> Float +percent v' lo' hi' = (v - lo) / (hi - lo) +  where v = fromIntegral v' +        lo = fromIntegral lo' +        hi = fromIntegral hi' + +volumeConfig :: IO MConfig +volumeConfig = mkMConfig "Vol: <volume>% <status>" +                         ["volume","dB","status"] + +formatVol :: Integer -> Integer -> Integer -> Monitor String +formatVol v lo hi = +    showPercentWithColors $ percent v lo hi + +switchHelper :: VolumeOpts +             -> (VolumeOpts -> Maybe String) +             -> (VolumeOpts -> String) +             -> Monitor String +switchHelper opts cHelp strHelp = return $ +    colorHelper (cHelp opts) +    ++ strHelp opts +    ++ maybe "" (const "</fc>") (cHelp opts) + +formatSwitch :: VolumeOpts -> Bool -> Monitor String +formatSwitch opts True = switchHelper opts onColor onString +formatSwitch opts False = switchHelper opts offColor offString + +colorHelper :: Maybe String -> String +colorHelper = maybe "" (\c -> "<fc=" ++ c ++ ">") + +formatDb :: VolumeOpts -> Float -> Monitor String +formatDb opts db = do +    h <- getConfigValue highColor +    m <- getConfigValue normalColor +    l <- getConfigValue lowColor +    let digits = showDigits 0 db +        startColor | db >= highDbThresh opts = colorHelper h +                   | db < lowDbThresh opts = colorHelper l +                   | otherwise = colorHelper m +        stopColor | null startColor = "" +                  | otherwise = "</fc>" +    return $ startColor ++ digits ++ stopColor + +runVolume :: String -> String -> [String] -> Monitor String +runVolume mixerName controlName argv = do +    opts <- io $ parseOpts argv +    control <- liftM fromJust $ io $ getControlByName mixerName controlName +    let volumeControl = fromJust $ maybe (playback $ volume control) Just +                                         (common $ volume control) +        switchControl = fromJust $ maybe (playback $ switch control) Just +                                         (common $ switch control) +    (lo, hi) <- io $ getRange volumeControl +    val <- io $ getChannel FrontLeft $ value volumeControl +    db <- io $ getChannel FrontLeft $ dB volumeControl +    sw <- io $ getChannel FrontLeft switchControl +    p <- case val of +             Just x -> formatVol x lo hi +             Nothing -> formatVol hi lo hi +    d <- case db of +             Just x -> formatDb opts $ fromIntegral x / 100.0 +             Nothing -> formatDb opts 0.0 +    s <- case sw of +             Just x -> formatSwitch opts x +             Nothing -> formatSwitch opts True +    parseTemplate [ p, d, s ] diff --git a/xmobar.cabal b/xmobar.cabal index e5ee507..343570d 100644 --- a/xmobar.cabal +++ b/xmobar.cabal @@ -53,6 +53,10 @@ flag all_extensions    description: Includes all optional extensions.    default: False +flag with_alsa +  description: Use alsa-mixer to get the volume from soundcards. +  default: False +  executable xmobar      hs-source-dirs:     src      main-is:            Main.hs @@ -109,3 +113,8 @@ executable xmobar         build-depends: libmpd >= 0.5         other-modules: Plugins.Monitors.MPD         cpp-options: -DLIBMPD + +    if flag(with_alsa) || flag(all_extensions) +       build-depends: alsa-mixer == 0.1.* +       other-modules: Plugins.Monitors.Volume +       cpp-options: -DALSA | 
