packages feed

xmobar 0.13 → 0.14

raw patch · 24 files changed

+1185/−219 lines, 24 filesdep +alsa-coredep +timezone-olsondep +timezone-seriesdep ~libmpd

Dependencies added: alsa-core, timezone-olson, timezone-series

Dependency ranges changed: libmpd

Files

NEWS view
@@ -1,6 +1,45 @@ % xmobar - Release notes % Jose A. Ortega Ruiz +## Version 0.14++_New features_++  - New brightness monitor, courtesy of Martin Perner.+  - New DateZone plugin, for configurable timezone and localized+    datetimes, also by Martin.+  - New keyboard layout monitor (Kbd).  Yes, by Martin.+  - Rewrite of the event handling ([issue 53], [issue 57]), you+    guessed it.+  - Cpu monitor now also reports `iowait` field ([issue 55]).+  - Battery monitor: the full charge file is now settable in the+    monitor arguments (olpc systems use charge_full_design; see [issue 62]).++_Bug fixes_++  - [issue 45]: Fix for crashes with AC status changes in battery monitor.+  - [issue 48]: The <quality> field of Wireless behaves like a percentage.+  - [issue 50]/[issue 61]: `MPD` monitor now works with libmpd 0.6.+  - [issue 60]: Fixes for crashes on power resume for battery monitor.+  - Template sections without fields are now correctly displayed.+  - Catch errors when reading battery status (Ben Boeckel).+  - Compilation issues with ghc 7.x (Sergei Trofimovich).+  - Fixes for CoreTemp monitor in new kernels (Norbert Zeh).+  - Fix for pulseaudio problems in volume monitor (Martin Perner).+  - Fix for parsing errors when a `Run` entry ended in an array+    (Martin).+  - Fixed compilation in OpenBSD (Ivo van der Sangen).++[issue 45]: http://code.google.com/p/xmobar/issues/detail?id=45+[issue 48]: http://code.google.com/p/xmobar/issues/detail?id=48+[issue 50]: http://code.google.com/p/xmobar/issues/detail?id=50+[issue 53]: http://code.google.com/p/xmobar/issues/detail?id=53+[issue 55]: http://code.google.com/p/xmobar/issues/detail?id=55+[issue 57]: http://code.google.com/p/xmobar/issues/detail?id=57+[issue 60]: http://code.google.com/p/xmobar/issues/detail?id=60+[issue 61]: http://code.google.com/p/xmobar/issues/detail?id=61+[issue 62]: http://code.google.com/p/xmobar/issues/detail?id=62+ ## Version 0.13 (March 28, 2011)  _New features_@@ -15,6 +54,9 @@  _Incompatible changes_ +  - In the process of solving [issue 14], we've broken those+    configurations that rely on including alignment separators in the+    input fed to `StdinReader`.   - The MPD plugin does not accept host and port options anymore: use     the environment variables MPD_HOST and MPD_PORT instead.   - The `Mail` plugin now takes a second parameter (a string)
README view
@@ -1,5 +1,4 @@ % xmobar - A Minimalistic Text Based Status Bar-% Andrea Rossato, Jose A. Ortega Ruiz  About =====@@ -12,19 +11,27 @@ features, like dynamic color management, output templates, and extensibility through plugins. -This page documents xmobar 0.13 (see [release notes]).+This page documents xmobar 0.14 (see [release notes]).  [This is a screen shot] of Andrea's desktop with [xmonad] and xmobar.-[This] is xmobar running under [sawfish], with antialiased fonts. And-[this one] is my desktop with [xmonad] and two instances of xmobar.+[This screenshot] shows xmobar running under [sawfish], with+antialiased fonts. And [this one] is my desktop with [xmonad] and two+instances of xmobar.  [release notes]: http://projects.haskell.org/xmobar/releases.html [xmonad]: http://xmonad.org [Ion3]: http://tuomov.iki.fi/software/-[This is a screen shot]: http://haskell.org/sitewiki/images/a/ae/Arossato-config.png-[This]: http://projects.haskell.org/xmobar/xmobar-sawfish.png+[This screenshot]: http://projects.haskell.org/xmobar/xmobar-sawfish.png [this one]: http://projects.haskell.org/xmobar/xmobar-xmonad.png +Bug Reports+===========++To submit bug reports you can use the [bug tracker over at Google+code] or send mail to our [Mailing list].++[bug tracker over at Google code]: http://code.google.com/p/xmobar/issues+ Installation ============ @@ -46,7 +53,7 @@ If you don't have `cabal-install` installed, you can get xmobar's source code in a variety of ways: -  - From [Hackage]. Just download [xmobar-0.13.tar.gz] from xmobar's+  - From [Hackage]. Just download [xmobar-0.14.tar.gz] from xmobar's     hackage page.   - From [Github]. You can also obtain a tarball in [Github's     downloads page]. You'll find there links to each tagged release.@@ -55,13 +62,13 @@     git:         git clone git://github.com/jaor/xmobar -[xmobar-0.13.tar.gz]: http://hackage.haskell.org/packages/archive/xmobar/0.13/xmobar-0.13.tar.gz+[xmobar-0.14.tar.gz]: http://hackage.haskell.org/packages/archive/xmobar/0.14/xmobar-0.14.tar.gz [Github's downloads page]: https://github.com/jaor/xmobar/downloads  To install simply run (if needed): -        tar xvfz xmobar-0.13-        cd xmobar-0.13+        tar xvfz xmobar-0.14+        cd xmobar-0.14  If you have cabal installed, you can now use it from within xmobar's source tree. Otherwise, run the configure script:@@ -124,6 +131,10 @@ :    Support for ALSA sound cards. Enables the Volume plugin. Requires the      [alsa-mixer] package. +`with_datezone`+:    Support for other timezones. Enables the DateZone plugin.+     Requires [timezone-olson] and [timezone-series] package.+ `all_extensions` :    Enables all the extensions above. @@ -140,6 +151,14 @@  if you have the default configuration file saved as `~/.xmobarrc` +### Signal Handling++Since 0.14 xmobar reacts to SIGUSR1 and SIGUSR2:++- After receiving SIGUSR1 xmobar moves its position to the next screen.++- After receiving SIGUSR2 xmobar repositions it self on the current screen.+ Configuration ============= @@ -225,26 +244,13 @@ `template` :    The output template. -## Running xmobar with i3status--xmobar can be used to display information gathered by [i3status], a-small program that gathers information and formats it suitable for-being displayed by the dzen2 status bar, wmii's status bar or xmobar's-StdinReader.--Since xmobar support has been added only recently you need to get the-git repository, and build it with the appropriate flags:--    git clone git://code.stapelberg.de/i3status--and then build it:--    cd i3status-    make EXTRA_CFLAGS="-DXMOBAR--Then you can run it with:+### Running xmobar with i3status -    ./i3status -c i3status.conf | xmobar -o -t "%StdinReader%" -c "[Run StdinReader]"+xmobar can be used to display information generated by [i3status], a+small program that gathers system information and outputs it in+formats suitable for being displayed by the dzen2 status bar, wmii's+status bar or xmobar's `StdinReader`.  See [i3status manual] for+further details.  ## Command Line Options @@ -313,13 +319,8 @@ The only internal available command is `Com` (see below Executing External Commands). All other commands are provided by plugins. xmobar comes with some plugins, providing a set of system monitors, a-standard input reader, an Unix named pipe reader, and a configurable-date plugin. These plugins install the following internal commands:-`Weather`, `Network`, `Wireless` (optional), `Memory`, `Swap`, `Cpu`,-`MultiCpu`, `Battery`, `TopProc`, `TopMem`, `DiskU`, `DiskIO`,-`Thermal`, `ThermalZone`, `CpuFreq`, `CoreTemp`, `Volume` (optional),-`MPD` (optional), `Mail` (optional), `MBox` (optional), `Date`,-`Uptime`, `StdinReader`, `CommandReader`, and `PipeReader`.+standard input reader, an Unix named pipe reader, a configurable date+plugin, and much more: we list all available plugins below.  To remove them see below Installing/Removing a Plugin @@ -403,7 +404,7 @@ - Aliases to `cpu` - Args: default monitor arguments (see below) - Variables that can be used with the `-t`/`--template` argument:-	    `total`, `bar`, `user`, `nice`, `system`, `idle`+	    `total`, `bar`, `user`, `nice`, `system`, `idle`, `iowait` - Default template: `Cpu: <total>%`  `MultiCpu Args RefreshRate`@@ -441,6 +442,10 @@     - `-p`: color to display positive power (battery charging)     - `-f`: file in `/sys/class/power_supply` with AC info (default:       "AC/online")+    - `-c`: file in `/sys/class/power/<BAT>/` with full charge+    information (default: "charge_full"; for instance, olpc systems+    use "charge_full_design")+ - Variables that can be used with the `-t`/`--template` argument: 	    `left`, `leftbar`, `timeleft`, `watts`, `acstatus` - Default template: `Batt: <watts>, <left>% / <timeleft>`@@ -452,7 +457,8 @@                        "-L", "10", "-H", "80", "-p", "3",                        "--", "-O", "<fc=green>On</fc> - ", "-o", "",                        "-L", "-15", "-H", "-5",-                       "-l", "red", "-m", "blue", "-h", "green"]+                       "-l", "red", "-m", "blue", "-h", "green",+                       "-c", "charge_full_design"]                       600   In the above example, the thresholds before the "--" separator   refer to the `<left>` field, while those after the separator affect@@ -599,10 +605,12 @@     - `--lowd` _number_ Low threshold for dB. Defaults to -30.0. - Variables that can be used with the `-t`/`--template` argument:             `volume`, `volumebar`, `dB`, `status`+- Note that `dB` might only return 0 on your system. This is known+  to happen on systems with a pulseaudio backend. - Default template: `Vol: <volume>% <status>`-- Requires the package [alsa-mixer] installed in your system. In addition,-  to activate this plugin you must pass `--flags="with_alsa"` during-  compilation.+- Requires the package [alsa-core] and [alsa-mixer] installed in your+  system. In addition, to activate this plugin you must pass+  `--flags="with_alsa"` during compilation.  `MPD Args RefreshRate` @@ -679,6 +687,36 @@  [samples/xmonadpropwrite.hs script]: https://github.com/jaor/xmobar/raw/master/samples/xmonadpropwrite.hs +`Brightness Args RefreshRate`++- Aliases to `bright`+- Args: default monitor arguments (see below), plus the following specif ones:+    - `-D`: directory in `/sys/class/backlight/` with files in it+       (default: "acpi_video0")+    - `-C`: file with the current brightness (default:+       actual_brightness)+    - `-M`: file with the maximum brightness (default:+       max_brigtness)+- Variables that can be used with the `-t`/`--template` argument:+	    `hbar`, `percent`, `bar`+- Default template: `<percent>`+- Example:++       Run Brightness ["-t", "<bar>"] 60++`Kbd Opts`++- Registers to XKB/X11-Events and output the currently active keyboard layout.+  Supports replacement of layoutnames.+- Aliases to `kbd`+- Opts is a list of tuple:+    -  first element of the tuple is the search string+    -  second element of the tuple is the corresponding replacement+- Example:++		Run Kbd [("us(dvorak)", "DV"), ("us", "US")]++ ## Monitor Plugins Commands Arguments  These are the arguments that can be used for internal commands in the@@ -828,6 +866,19 @@   `strftime` function (or Haskell's `formatCalendarTime`). - Sample usage: `Run Date "%a %b %_d %Y <fc=#ee9a00>%H:%M:%S</fc>" "date" 10` +`DateZone Format Locale Zone Alias RefreshRate`++- Format is a time format string, as accepted by the standard ISO C+  `strftime` function (or Haskell's `formatCalendarTime`).+- If Locale is "" the default locale of the system is used, otherwise the given+  locale. If there are more instances of DateZone, using "" as input for Locale+  is not recommended.+- Zone is the name of the TimeZone. It is assumed that the tz database is stored+  in /usr/share/zoneinfo/. If "" is given as Zone, the default system time is+  used.+- Sample usage:+  `Run DateZone "%a %H:%M:%S" "de_DE.UTF-8" "Europe/Vienna" "viennaTime" 10`+ `CommandReader "/path/to/program" Alias`  - Runs the given program, and displays its standard output.@@ -971,23 +1022,15 @@  3. rebuild xmobar. -Bug Reports-===========--To submit bug reports you can use the [bug tracker over at Google-code] or send mail to our [Mailing list].--[bug tracker over at Google code]: http://code.google.com/p/xmobar/issues- Credits =======  xmobar [incorporates patches] by Ben Boeckel, Roman Cheplyaka, John Goerzen, Juraj Hercek, Tomas Janousek, Spencer Janssen, Lennart-Kolmodin, Krzysztof Kosciuszkiewicz, Dmitry Kurochkin, Svein Ove, Jens-Petersen, Petr Rockai, Andrew Sackville-West, Alexander Solovyov,-Sergei Trofimovich, Thomas Tuegel, Jan Vornberger, Daniel Wagner and-Norbert Zeh.+Kolmodin, Krzysztof Kosciuszkiewicz, Dmitry Kurochkin, Svein Ove,+Martin Perner, Jens Petersen, Petr Rockai, Andrew Sackville-West,+Alexander Solovyov, Sergei Trofimovich, Thomas Tuegel, Jan Vornberger,+Daniel Wagner and Norbert Zeh.  [incorporates patches]: http://www.ohloh.net/p/xmobar/contributors @@ -1011,7 +1054,6 @@ - [Github page]. - [Mailing list]. - [xmobar's Ohloh page].-- Andrea's original [xmobar] home page, and [xmobar darcs repository].  - To understand the internal mysteries of xmobar you may try reading   [this tutorial] on X Window Programming in Haskell.@@ -1020,8 +1062,6 @@   in [sawfish].  [xmobar's Ohloh page]: https://www.ohloh.net/p/xmobar-[xmobar]: http://code.haskell.org/~arossato/xmobar/-[xmobar darcs repository]: http://code.haskell.org/xmobar [this tutorial]: http://www.haskell.org/haskellwiki/X_window_programming_in_Haskell [sawflibs]: http://github.com/jaor/sawflibs @@ -1049,10 +1089,14 @@ [Mailing list]: http://projects.haskell.org/cgi-bin/mailman/listinfo/xmobar [MPD]: http://mpd.wikia.com/ [X11-xft]: http://hackage.haskell.org/package/X11-xft/-[i3status]: http://i3.zekjur.net/i3status/+[i3status]: http://i3wm.org/i3status/+[i3status manual]: http://i3wm.org/i3status/manpage.html#_using_i3status_with_xmobar [iwlib]: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html [hinotify]: http://hackage.haskell.org/package/hinotify/ [libmpd]: http://hackage.haskell.org/package/libmpd/ [sawfish]: http://sawfish.wikia.com/ [utf8-string]: http://hackage.haskell.org/package/utf8-string/+[alsa-core]: http://hackage.haskell.org/package/alsa-core [alsa-mixer]: http://hackage.haskell.org/package/alsa-mixer+[timezone-olson]: http://hackage.haskell.org/package/timezone-olson+[timezone-series]: http://hackage.haskell.org/package/timezone-series
src/Commands.hs view
@@ -75,8 +75,7 @@ -- is not possible to set a thread delay grater than about 45 minutes. -- With a little recursion we solve the problem. tenthSeconds :: Int -> IO ()-tenthSeconds s | s >= x = do threadDelay y-                             tenthSeconds (x - s)+tenthSeconds s | s >= x = do threadDelay (x * 100000)+                             tenthSeconds (s - x)                | otherwise = threadDelay (s * 100000)-               where y = maxBound :: Int-                     x = y `div` 100000+               where x = (maxBound :: Int) `div` 100000
src/Config.hs view
@@ -32,12 +32,17 @@ import Plugins.StdinReader import Plugins.XMonadLog import Plugins.EWMH+import Plugins.Kbd  #ifdef INOTIFY import Plugins.Mail import Plugins.MBox #endif +#ifdef DATEZONE+import Plugins.DateZone+#endif+ -- $config -- Configuration data type and default configuration @@ -108,9 +113,12 @@ -- the 'Runnable.Runnable' Read instance. To install a plugin just add -- the plugin's type to the list of types (separated by ':*:') appearing in -- this function's type signature.-runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*:+runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*: #ifdef INOTIFY                  Mail :*: MBox :*:+#endif+#ifdef DATEZONE+                 DateZone :*: #endif                  () runnableTypes = undefined
+ src/Localize.hsc view
@@ -0,0 +1,85 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Localize+-- Copyright   :  (C) 2011 Martin Perner+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Martin Perner <martin@perner.cc>+-- Stability   :  unstable+-- Portability :  unportable+--+-- This module provides an interface to locale information e.g. for DateL+--+-----------------------------------------------------------------------------++module Localize+    ( setupTimeLocale,+      getTimeLocale+    ) where++import Foreign.C+import qualified System.Locale as L++#ifdef UTF8+import Codec.Binary.UTF8.String+#endif++--  get localized strings+type NlItem = CInt++#include <langinfo.h>+foreign import ccall unsafe "langinfo.h nl_langinfo"+  nl_langinfo :: NlItem -> IO CString++#{enum NlItem,+  , AM_STR , PM_STR \+  , D_T_FMT , D_FMT , T_FMT , T_FMT_AMPM \+  , ABDAY_1, ABDAY_7 \+  , DAY_1, DAY_7 \+  , ABMON_1, ABMON_12 \+  , MON_1, MON_12\+ }++getLangInfo :: NlItem -> IO String+getLangInfo item = do+  itemStr <- nl_langinfo item+#ifdef UTF8+  str <- peekCString itemStr+  return $ decodeString str+#else+  peekCString itemStr+#endif++#include <locale.h>+foreign import ccall unsafe "locale.h setlocale"+    setlocale :: CInt -> CString -> IO CString++setupTimeLocale :: String -> IO ()+setupTimeLocale l = withCString l (setlocale #const LC_TIME) >> return ()++getTimeLocale :: IO L.TimeLocale+getTimeLocale = do+  -- assumes that the defined values are increasing by exactly one.+  -- as they are defined consecutive in an enum this is reasonable+  days   <- mapM getLangInfo [day1 .. day7]+  abdays <- mapM getLangInfo [abday1 .. abday7]++  mons   <- mapM getLangInfo [mon1 .. mon12]+  abmons <- mapM getLangInfo [abmon1 .. abmon12]++  amstr <- getLangInfo amStr+  pmstr <- getLangInfo pmStr+  dtfmt <- getLangInfo dTFmt+  dfmt  <- getLangInfo dFmt+  tfmt  <- getLangInfo tFmt+  tfmta <- getLangInfo tFmtAmpm++  let t =  L.defaultTimeLocale {L.wDays  = zip days abdays+                               ,L.months = zip mons abmons+                               ,L.amPm = (amstr, pmstr)+                               ,L.dateTimeFmt = dtfmt+                               ,L.dateFmt = dfmt+                               ,L.timeFmt = tfmt+                               ,L.time12Fmt = tfmta}+  return t
src/Main.hs view
@@ -41,6 +41,7 @@ -- | The main entry point main :: IO () main = do+  initThreads   d   <- openDisplay ""   args     <- getArgs   (o,file) <- getOpts args@@ -51,16 +52,12 @@   unless (null defaultings) $ putStrLn $ "Fields missing from config defaulted: "                                             ++ intercalate "," defaultings -  -- listen for ConfigureEvents on the root window, for xrandr support:-  rootw <- rootWindow d (defaultScreen d)-  selectInput d rootw structureNotifyMask-   conf  <- doOpts c o   fs    <- initFont d (font conf)   cls   <- mapM (parseTemplate conf) (splitTemplate conf)   vars  <- mapM (mapM startCommand) cls   (r,w) <- createWin d fs conf-  eventLoop (XConf d r w fs conf) vars+  startLoop (XConf d r w fs conf) vars  -- | Splits the template in its parts splitTemplate :: Config -> [String]
src/Parsers.hs view
@@ -87,7 +87,7 @@ parseTemplate :: Config -> String -> IO [(Runnable,String,String)] parseTemplate c s =     do str <- case parse (templateParser c) "" s of-                Left _  -> return [("","","")]+                Left _  -> return [("", s, "")]                 Right x -> return x        let cl = map alias (commands c)            m  = Map.fromList $ zip cl (commands c)@@ -159,7 +159,8 @@                      return ("Static {"  ++ p  ++ "}")       tillFieldEnd = staticPos <|> many (noneOf ",}\n\r") -      commandsEnd  = wrapSkip (string "]") >> oneOf "},"+      commandsEnd  = wrapSkip (string "]") >> (string "}" <|> notNextRun)+      notNextRun = do { string ","; notFollowedBy $ wrapSkip $ string "Run"; return ","}        readCommands = manyTill anyChar (try commandsEnd) >>= read' commandsErr . flip (++) "]"        strField e n = field e n . between (strDel "start" n) (strDel "end" n) . many $ noneOf "\"\n\r"
+ src/Plugins/DateZone.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE DoAndIfThenElse #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Plugins.DateZone+-- Copyright   :  (c) Martin Perner+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Martin Perner <martin@perner.cc>+-- Stability   :  unstable+-- Portability :  unportable+--+-- A date plugin with localization and location support for Xmobar+--+-- Based on Plugins.Date+--+-- Usage example: in template put+--+-- > Run DateZone "%a %H:%M:%S" "de_DE.UTF-8" "UTC" "utcDate" 10+--+-----------------------------------------------------------------------------++module Plugins.DateZone (DateZone(..)) where++import Plugins++import Localize++import Control.Concurrent.STM++import Data.Time.LocalTime+import Data.Time.Format+import Data.Time.LocalTime.TimeZone.Olson+import Data.Time.LocalTime.TimeZone.Series++import System.IO.Unsafe+import System.Locale (TimeLocale)+import System.Time++++{-# NOINLINE localeLock #-}+-- ensures that only one plugin instance sets the locale+localeLock :: TMVar Bool+localeLock = unsafePerformIO (newTMVarIO False)++data DateZone = DateZone String String String String Int+    deriving (Read, Show)++instance Exec DateZone where+    alias (DateZone _ _ _ a _) = a+    start (DateZone f l z _ r) cb = do+      lock <- atomically $ takeTMVar localeLock+      setupTimeLocale l+      locale <- getTimeLocale+      atomically $ putTMVar localeLock lock+      if z /= "" then do+        timeZone <- getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ z)+        go (dateZone f locale timeZone)+       else+        go (date f locale)++      where go func = func >>= cb >> tenthSeconds r >> go func++date :: String -> TimeLocale -> IO String+date format loc = do+  t <- toCalendarTime =<< getClockTime+  return $ formatCalendarTime loc format t++dateZone :: String -> TimeLocale -> TimeZoneSeries -> IO String+dateZone format loc timeZone = do+  zonedTime <- getZonedTime+  return $ formatTime loc format $ utcToLocalTime' timeZone $ zonedTimeToUTC zonedTime
+ src/Plugins/Kbd.hsc view
@@ -0,0 +1,397 @@+{-# LANGUAGE ScopedTypeVariables, ForeignFunctionInterface, MultiParamTypeClasses, DeriveDataTypeable, FlexibleInstances, PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Plugins.Kbd+-- Copyright   :  (c) Martin Perner+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Martin Perner <martin@perner.cc>+-- Stability   :  unstable+-- Portability :  unportable+--+-- A keyboard layout indicator for Xmobar+--+-----------------------------------------------------------------------------++module Plugins.Kbd where++import Graphics.X11.Xlib+import Graphics.X11.Xlib.Extras+import Foreign+import Foreign.C.Types (CUInt,CULong,CInt,CUShort,CChar,CUChar)+import Foreign.C.String+import Plugins+import Control.Monad (forever)+import XUtil (nextEvent')+import Data.List (isPrefixOf, findIndex)+import Data.Maybe (fromJust)++#include <X11/XKBlib.h>+#include <X11/extensions/XKB.h>+#include <X11/extensions/XKBstr.h>++-- +-- Definition for XkbStaceRec and getKbdLayout taken from+-- XMonad.Layout.XKBLayout+--+data XkbStateRec = XkbStateRec {+    group :: CUChar,+    locked_group :: CUChar,+    base_group :: CUShort,+    latched_group :: CUShort,+    mods :: CUChar,+    base_mods :: CUChar,+    latched_mods :: CUChar,+    locked_mods :: CUChar,+    compat_state :: CUChar,+    grab_mods :: CUChar,+    compat_grab_mods :: CUChar,+    lookup_mods :: CUChar,+    compat_lookup_mods :: CUChar,+    ptr_buttons :: CUShort+}++instance Storable XkbStateRec where+    sizeOf _ = (#size XkbStateRec)+    alignment _ = alignment (undefined :: CUShort)+    peek ptr = do+        r_group <- (#peek XkbStateRec, group) ptr+        r_locked_group <- (#peek XkbStateRec, locked_group) ptr+        r_base_group <- (#peek XkbStateRec, base_group) ptr+        r_latched_group <- (#peek XkbStateRec, latched_group) ptr+        r_mods <- (#peek XkbStateRec, mods) ptr+        r_base_mods <- (#peek XkbStateRec, base_mods) ptr+        r_latched_mods <- (#peek XkbStateRec, latched_mods) ptr+        r_locked_mods <- (#peek XkbStateRec, locked_mods) ptr+        r_compat_state <- (#peek XkbStateRec, compat_state) ptr+        r_grab_mods <- (#peek XkbStateRec, grab_mods) ptr+        r_compat_grab_mods <- (#peek XkbStateRec, compat_grab_mods) ptr+        r_lookup_mods <- (#peek XkbStateRec, lookup_mods) ptr+        r_compat_lookup_mods <- (#peek XkbStateRec, compat_lookup_mods) ptr+        r_ptr_buttons <- (#peek XkbStateRec, ptr_buttons) ptr+        return XkbStateRec {+            group = r_group,+            locked_group = r_locked_group,+            base_group = r_base_group,+            latched_group = r_latched_group,+            mods = r_mods,+            base_mods = r_base_mods,+            latched_mods = r_latched_mods,+            locked_mods = r_locked_mods,+            compat_state = r_compat_state,+            grab_mods = r_grab_mods,+            compat_grab_mods = r_compat_grab_mods,+            lookup_mods = r_lookup_mods,+            compat_lookup_mods = r_compat_lookup_mods,+            ptr_buttons = r_ptr_buttons+        }++foreign import ccall unsafe "X11/XKBlib.h XkbGetState"+    xkbGetState :: Display -> CUInt -> Ptr XkbStateRec -> IO CInt+++getKbdLayout :: Display -> IO Int+getKbdLayout d = alloca $ \stRecPtr -> do+    xkbGetState d 0x100 stRecPtr+    st <- peek stRecPtr+    return $ fromIntegral (group st)++--+--+--++data XkbKeyNameRec = XkbKeyNameRec {+	name :: Ptr CChar -- array+}++--+-- the t_ before alias is just because of name collisions+--+data XkbKeyAliasRec = XkbKeyAliasRec {+	real  :: Ptr CChar, -- array+	t_alias :: Ptr CChar  -- array+} ++--+-- the t_ before geometry is just because of name collisions+--+data XkbNamesRec = XkbNamesRec {+    keycodes :: Atom,+    t_geometry :: Atom,+    symbols :: Atom,+    types :: Atom,+    compat :: Atom,+    vmods :: Ptr Atom,+    indicators :: Ptr Atom, -- array+    groups :: Ptr Atom, -- array+    keys :: Ptr XkbKeyNameRec,+    key_aliases :: Ptr CChar, -- dont care XkbKeyAliasRec,+    radio_groups :: Ptr Atom,+    phys_symbols :: Atom,+    num_keys :: CUChar,+    num_key_aliases :: CUChar,+    num_rg :: CUShort+}++--+-- the t_ before map, indicators and compat are just because of name collisions+--+data XkbDescRec = XkbDescRec {+    t_dpy :: Ptr CChar, -- struct _XDisplay* ; don't care+    flags :: CUShort,+    device_spec :: CUShort,+    min_key_code :: KeyCode,+    max_key_code :: KeyCode,+    ctrls :: Ptr CChar, -- XkbControlsPtr ;  dont' care+    server :: Ptr CChar, -- XkbServerMapPtr ;  dont' care+    t_map :: Ptr CChar, --XkbClientMapPtr ;  dont' care+    t_indicators :: Ptr CChar, -- XkbIndicatorPtr ;  dont' care+	names :: Ptr XkbNamesRec, -- array+    t_compat :: Ptr CChar, -- XkbCompatMap ;  dont' care+    geom :: Ptr CChar -- XkbGeometryPtr ;  dont' care++}++instance Storable XkbKeyNameRec where+    sizeOf _ = (#size XkbKeyNameRec)+    alignment _ = alignment (undefined :: CUShort)+    peek ptr = do+        r_name <- (#peek XkbKeyNameRec, name) ptr++        return XkbKeyNameRec {+            name = r_name+        }++instance Storable XkbKeyAliasRec where+    sizeOf _ = (#size XkbKeyAliasRec)+    alignment _ = alignment (undefined :: CUShort)+    peek ptr = do+        r_real <- (#peek XkbKeyAliasRec, real) ptr+        r_alias <- (#peek XkbKeyAliasRec, alias) ptr++        return XkbKeyAliasRec {+            real = r_real,+            t_alias = r_alias+        }++instance Storable XkbNamesRec where+    sizeOf _ = (#size XkbNamesRec)+    alignment _ = alignment (undefined :: CUShort)+    peek ptr = do+        r_keycodes <- (#peek XkbNamesRec, keycodes) ptr+        r_geometry <- (#peek XkbNamesRec, geometry) ptr+        r_symbols <- (#peek XkbNamesRec, symbols ) ptr+        r_types <- (#peek XkbNamesRec, types ) ptr+        r_compat <- (#peek XkbNamesRec, compat ) ptr  +        r_vmods <- (#peek XkbNamesRec,  vmods ) ptr+        r_indicators <- (#peek XkbNamesRec, indicators ) ptr  +        r_groups <- (#peek XkbNamesRec, groups ) ptr +        r_keys <- (#peek XkbNamesRec, keys ) ptr   +        r_key_aliases <- (#peek XkbNamesRec, key_aliases  ) ptr+        r_radio_groups <- (#peek XkbNamesRec, radio_groups  ) ptr +        r_phys_symbols <- (#peek XkbNamesRec, phys_symbols ) ptr  +        r_num_keys <- (#peek XkbNamesRec,num_keys  ) ptr+        r_num_key_aliases <- (#peek XkbNamesRec, num_key_aliases  ) ptr+        r_num_rg <- (#peek XkbNamesRec, num_rg ) ptr++        return XkbNamesRec {+            keycodes = r_keycodes,+            t_geometry = r_geometry,+            symbols = r_symbols,+            types = r_types,+            compat = r_compat,+            vmods = r_vmods,+            indicators = r_indicators,+            groups = r_groups,+            keys = r_keys,+            key_aliases = r_key_aliases,+            radio_groups = r_radio_groups,+            phys_symbols = r_phys_symbols,+            num_keys = r_num_keys,+            num_key_aliases = r_num_key_aliases,+            num_rg = r_num_rg+       }++instance Storable XkbDescRec where+    sizeOf _ = (#size XkbDescRec)+    alignment _ = alignment (undefined :: CUShort)+    peek ptr = do+        r_dpy <- (#peek XkbDescRec, dpy) ptr+        r_flags <- (#peek XkbDescRec, flags) ptr+        r_device_spec <- (#peek XkbDescRec, device_spec) ptr+        r_min_key_code <- (#peek XkbDescRec, min_key_code) ptr+        r_max_key_code <- (#peek XkbDescRec, max_key_code) ptr+        r_ctrls <- (#peek XkbDescRec, ctrls) ptr+        r_server <- (#peek XkbDescRec, server) ptr+        r_map <- (#peek XkbDescRec, map) ptr+        r_indicators <- (#peek XkbDescRec, indicators) ptr+        r_names <- (#peek XkbDescRec, names) ptr+        r_compat <- (#peek XkbDescRec, compat) ptr+        r_geom <- (#peek XkbDescRec, geom) ptr++        return XkbDescRec {+            t_dpy = r_dpy,+            flags = r_flags,+            device_spec = r_device_spec,+            min_key_code = r_min_key_code,+            max_key_code = r_max_key_code,+            ctrls = r_ctrls,+            server = r_server,+            t_map = r_map,+            t_indicators = r_indicators,+            names = r_names,+            t_compat = r_compat,+            geom = r_geom+        }++--+-- C bindings+--++foreign import ccall unsafe "X11/XKBlib.h XkbAllocKeyboard"+    xkbAllocKeyboard :: IO (Ptr XkbDescRec)++foreign import ccall unsafe "X11/XKBlib.h XkbGetNames"+    xkbGetNames :: Display -> CUInt -> (Ptr XkbDescRec)  -> IO Status++foreign import ccall unsafe "X11/XKBlib.h XGetAtomName"+    xGetAtomName :: Display -> Atom -> IO CString++foreign import ccall unsafe "X11/XKBlib.h XkbFreeNames"+    xkbFreeNames :: (Ptr XkbDescRec) -> CUInt -> CInt -> IO ()++foreign import ccall unsafe "X11/XKBlib.h XkbFreeKeyboard"+    xkbFreeKeyboard :: (Ptr XkbDescRec) -> CUInt -> CInt -> IO ()++foreign import ccall unsafe "X11/XKBlib.h XkbSelectEventDetails"+	xkbSelectEventDetails :: Display -> CUInt -> CUInt -> CULong -> CULong -> IO CUInt++foreign import ccall unsafe "X11/XKBlib.h XkbSelectEvents"+	xkbSelectEvents :: Display -> CUInt -> CUInt -> CUInt -> IO CUInt+++xkbUseCoreKbd :: CUInt+xkbUseCoreKbd = #const XkbUseCoreKbd++xkbStateNotify :: CUInt+xkbStateNotify = #const XkbStateNotify++xkbMapNotify :: CUInt+xkbMapNotify = #const XkbMapNotify++xkbMapNotifyMask :: CUInt+xkbMapNotifyMask = #const XkbMapNotifyMask++xkbNewKeyboardNotifyMask :: CUInt+xkbNewKeyboardNotifyMask  = #const XkbNewKeyboardNotifyMask++xkbAllStateComponentsMask :: CULong+xkbAllStateComponentsMask = #const XkbAllStateComponentsMask++xkbGroupStateMask :: CULong+xkbGroupStateMask = #const XkbGroupStateMask++xkbSymbolsNameMask :: CUInt+xkbSymbolsNameMask = #const XkbSymbolsNameMask++xkbGroupNamesMask :: CUInt+xkbGroupNamesMask = #const XkbGroupNamesMask++type KbdOpts = [(String, String)]++-- gets the layout string+getLayoutStr :: Display -> IO String+getLayoutStr dpy =  do+        kbdDescPtr <- xkbAllocKeyboard+        status <- xkbGetNames dpy xkbSymbolsNameMask kbdDescPtr+        str <- getLayoutStr' status dpy kbdDescPtr+        xkbFreeNames kbdDescPtr xkbGroupNamesMask 1+        xkbFreeKeyboard kbdDescPtr 0 1+        return str++getLayoutStr' :: Status -> Display -> (Ptr XkbDescRec) -> IO String+getLayoutStr' st dpy kbdDescPtr =+        if st == 0 then -- Success+            do+            kbdDesc <- peek kbdDescPtr+            nameArray <- peek (names kbdDesc)+            atom <- xGetAtomName dpy (symbols nameArray)+            str <- peekCString atom+            return str+        else -- Behaviour on error+            do+                return "Error while requesting layout!"+++-- 'Bad' prefixes of layouts+noLaySymbols :: [String]+noLaySymbols = ["group", "inet", "ctr", "pc", "ctrl"]+++-- splits the layout string into the actual layouts+splitLayout :: String -> [String]+splitLayout s = splitLayout' noLaySymbols $ split s '+' ++splitLayout' :: [String] ->  [String] -> [String]+--                  end of recursion, remove empty strings+splitLayout' [] s = map (takeWhile (\x -> x /= ':')) $ filter (\x -> length x > 0) s+--                    remove current string if it has a 'bad' prefix+splitLayout' bad s  = splitLayout' (tail bad) [x | x <- s, not $ isPrefixOf (head bad) x]++-- split String at each Char+split :: String -> Char -> [String]+split [] _ = [""]+split (c:cs) delim+    | c == delim = "" : rest+    | otherwise = (c : head rest) : tail rest+        where+            rest = split cs delim++-- replaces input string if on search list (exact match) with corresponding+-- element on replacement list.+-- +-- if not found, return string unchanged+searchReplaceLayout :: KbdOpts -> String -> String+searchReplaceLayout opts s = let c = findIndex (\x -> fst x == s) opts in+    case c of+        Nothing -> s+        x -> let i = (fromJust x) in+            snd $ opts!!i++-- returns the active layout+getKbdLay :: Display -> KbdOpts -> IO String+getKbdLay dpy opts = do+        lay <- getLayoutStr dpy+        curLay <- getKbdLayout dpy+        return $ searchReplaceLayout opts $ (splitLayout lay)!!(curLay)++++data Kbd = Kbd [(String, String)]+	deriving (Read, Show)++instance Exec Kbd where+	alias (Kbd _) = "kbd"+	start (Kbd opts) cb = do++        dpy <- openDisplay ""++        -- initial set of layout+        cb =<< (getKbdLay dpy opts)++        -- enable listing for+        -- group changes+        _ <- xkbSelectEventDetails dpy xkbUseCoreKbd xkbStateNotify xkbAllStateComponentsMask xkbGroupStateMask+        -- layout/geometry changes+        _ <- xkbSelectEvents dpy  xkbUseCoreKbd xkbNewKeyboardNotifyMask xkbNewKeyboardNotifyMask++        allocaXEvent $ \e -> forever $ do+            nextEvent' dpy e+            _ <- getEvent e+            cb =<< (getKbdLay dpy opts)++        closeDisplay dpy+        return ()++-- vim:ft=haskell:ts=4:shiftwidth=4:softtabstop=4:expandtab:foldlevel=20:+
src/Plugins/Monitors.hs view
@@ -27,6 +27,7 @@ import Plugins.Monitors.Cpu import Plugins.Monitors.MultiCpu import Plugins.Monitors.Batt+import Plugins.Monitors.Bright import Plugins.Monitors.Thermal import Plugins.Monitors.ThermalZone import Plugins.Monitors.CpuFreq@@ -56,6 +57,7 @@               | Cpu          Args       Rate               | MultiCpu     Args       Rate               | Battery      Args       Rate+              | Brightness   Args       Rate               | CpuFreq      Args       Rate               | CoreTemp     Args       Rate               | TopProc      Args       Rate@@ -93,6 +95,7 @@     alias (MultiCpu _ _) = "multicpu"     alias (Battery _ _) = "battery"     alias (BatteryP _ _ _)= "battery"+    alias (Brightness _ _) = "bright"     alias (CpuFreq _ _) = "cpufreq"     alias (TopProc _ _) = "top"     alias (TopMem _ _) = "topmem"@@ -122,6 +125,7 @@     start (Swap a r) = runM a swapConfig runSwap r     start (Battery a r) = runM a battConfig runBatt r     start (BatteryP s a r) = runM a battConfig (runBatt' s) r+    start (Brightness a r) = runM a brightConfig runBright r     start (CpuFreq a r) = runM a cpuFreqConfig runCpuFreq r     start (CoreTemp a r) = runM a coreTempConfig runCoreTemp r     start (DiskU s a r) = runM a diskUConfig (runDiskU s) r
src/Plugins/Monitors/Batt.hs view
@@ -13,11 +13,14 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE BangPatterns #-}+ module Plugins.Monitors.Batt ( battConfig, runBatt, runBatt' ) where -import qualified Data.ByteString.Lazy.Char8 as B+import Control.Exception (SomeException, handle) import Plugins.Monitors.Common import System.FilePath ((</>))+import System.IO (IOMode(ReadMode), hGetLine, withFile) import System.Posix.Files (fileExist) import System.Console.GetOpt @@ -31,6 +34,7 @@   , lowThreshold :: Float   , highThreshold :: Float   , onlineFile :: FilePath+  , chargeFile :: FilePath   }  defaultOpts :: BattOpts@@ -44,6 +48,7 @@   , lowThreshold = -12   , highThreshold = -10   , onlineFile = "AC/online"+  , chargeFile = "charge_full"   }  options :: [OptDescr (BattOpts -> BattOpts)]@@ -57,6 +62,7 @@   , Option "L" ["lowt"] (ReqArg (\x o -> o { lowThreshold = read x }) "") ""   , Option "H" ["hight"] (ReqArg (\x o -> o { highThreshold = read x }) "") ""   , Option "f" ["online"] (ReqArg (\x o -> o { onlineFile = x }) "") ""+  , Option "c" ["charge"] (ReqArg (\x o -> o { chargeFile = x }) "") ""   ]  parseOpts :: [String] -> IO BattOpts@@ -83,35 +89,36 @@   } | NoFiles  data Battery = Battery-  { full :: Float-  , now :: Float-  , voltage :: Float-  , current :: Float+  { full :: !Float+  , now :: !Float+  , voltage :: !Float+  , current :: !Float   } -batteryFiles :: String -> IO Files-batteryFiles bat =-  do is_charge <- fileExist $ prefix </> "charge_now"-     is_energy <- fileExist $ prefix </> "energy_now"-     is_current <- fileExist $ prefix </> "current_now"+safeFileExist :: String -> IO Bool+safeFileExist f = handle noErrors $ fileExist f+  where noErrors = const (return False) :: SomeException -> IO Bool++batteryFiles :: String -> String -> IO Files+batteryFiles charge_file bat =+  do is_charge <- safeFileExist $ prefix </> "charge_now"+     is_energy <- safeFileExist $ prefix </> "energy_now"+     is_current <- safeFileExist $ prefix </> "current_now"      let cf = if is_current then "current_now" else "power_now"      return $ case (is_charge, is_energy) of        (True, _) -> files "charge" cf        (_, True) -> files "energy" cf        _ -> NoFiles   where prefix = sysDir </> bat-        files ch cf = Files { fFull = prefix </> ch ++ "_full"+        files ch cf = Files { fFull = prefix </> charge_file                             , fNow = prefix </> ch ++ "_now"                             , fCurrent = prefix </> cf                             , fVoltage = prefix </> "voltage_now" }  haveAc :: FilePath -> IO Bool-haveAc f = do-  exists <- fileExist ofile-  if exists-    then fmap ((== "1\n") . B.unpack) (B.readFile ofile)-    else return False-  where ofile = sysDir </> f+haveAc f =+  handle onError $ withFile (sysDir </> f) ReadMode (fmap (== "1") . hGetLine)+  where onError = const (return False) :: SomeException -> IO Bool  readBattery :: Files -> IO Battery readBattery NoFiles = return $ Battery 0 0 0 0@@ -123,18 +130,21 @@        return $ Battery (3600 * a / 1000000) -- wattseconds                         (3600 * b / 1000000) -- wattseconds                         (c / 1000000) -- volts-                        (d / c) -- amperes-    where grab = fmap (read . B.unpack) . B.readFile+                        (if c > 0 then (d / c) else -1) -- amperes+    where grab f = handle onError $ withFile f ReadMode (fmap read . hGetLine)+          onError = const (return (-1)) :: SomeException -> IO Float  readBatteries :: BattOpts -> [Files] -> IO Result readBatteries opts bfs =     do bats <- mapM readBattery (take 3 bfs)        ac <- haveAc (onlineFile opts)        let sign = if ac then 1 else -1-           left = sum (map now bats) / sum (map full bats)+           ft = sum (map full bats)+           left = if ft > 0 then sum (map now bats) / ft else 0            watts = sign * sum (map voltage bats) * sum (map current bats)            time = if watts == 0 then 0 else sum $ map time' bats-           time' b = (if ac then full b - now b else now b) / (sign * watts)+           mwatts = if watts == 0 then 1 else sign * watts+           time' b = (if ac then full b - now b else now b) / mwatts            acstr = if ac then onString opts else offString opts        return $ if isNaN left then NA else Result left watts time acstr @@ -144,26 +154,26 @@ runBatt' :: [String] -> [String] -> Monitor String runBatt' bfs args = do   opts <- io $ parseOpts args-  c <- io $ readBatteries opts =<< mapM batteryFiles bfs+  c <- io $ readBatteries opts =<< mapM (batteryFiles (chargeFile opts)) bfs   case c of     Result x w t s ->       do l <- fmtPercent x          parseTemplate (l ++ s:[fmtTime $ floor t, fmtWatts w opts])     NA -> return "N/A"- where fmtPercent :: Float -> Monitor [String]-       fmtPercent x = do-         p <- showPercentWithColors x-         b <- showPercentBar (100 * x) x-         return [b, p]-       fmtWatts x o = color x o $ showDigits 1 x ++ "W"-       fmtTime :: Integer -> String-       fmtTime x = hours ++ ":" ++ if length minutes == 2-                                   then minutes else '0' : minutes-         where hours = show (x `div` 3600)-               minutes = show ((x `mod` 3600) `div` 60)-       maybeColor Nothing _ = ""-       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)+  where fmtPercent :: Float -> Monitor [String]+        fmtPercent x = do+          p <- showPercentWithColors x+          b <- showPercentBar (100 * x) x+          return [b, p]+        fmtWatts x o = color x o $ showDigits 1 x ++ "W"+        fmtTime :: Integer -> String+        fmtTime x = hours ++ ":" ++ if length minutes == 2+                                    then minutes else '0' : minutes+          where hours = show (x `div` 3600)+                minutes = show ((x `mod` 3600) `div` 60)+        maybeColor Nothing _ = ""+        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)
+ src/Plugins/Monitors/Bright.hs view
@@ -0,0 +1,118 @@+-----------------------------------------------------------------------------+---- |+---- Module      :  Plugins.Monitors.Birght+---- Copyright   :  (c) Martin Perner+---- License     :  BSD-style (see LICENSE)+----+---- Maintainer  :  Martin Perner <martin@perner.cc>+---- Stability   :  unstable+---- Portability :  unportable+----+----  A screen brightness monitor for Xmobar+----+-------------------------------------------------------------------------------++module Plugins.Monitors.Bright (brightConfig, runBright) where++import Plugins.Monitors.Common+import qualified Data.ByteString.Lazy.Char8 as B+import Data.Char+import System.FilePath ((</>))+import System.Posix.Files (fileExist)+import System.Console.GetOpt++data BrightOpts = BrightOpts+	{ subDir :: String+	, currBright :: String+	, maxBright :: String+	}++defaultOpts :: BrightOpts+defaultOpts = BrightOpts+	{ subDir = "acpi_video0"+	, currBright = "actual_brightness"+	, maxBright = "max_brightness"+	}++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 }) "") ""+	]++-- from Batt.hs+parseOpts :: [String] -> IO BrightOpts+parseOpts argv =+	case getOpt Permute options argv of+		(o, _, []) -> return $ foldr id defaultOpts o+		(_, _, errs) -> ioError . userError $ concat errs++sysDir :: FilePath+sysDir = "/sys/class/backlight/"++brightConfig :: IO MConfig+brightConfig = mkMConfig+		"<percent>" -- template+		["hbar", "percent", "bar"] -- replacements++data Files = Files+	{ fCurr :: String+	, fMax :: String+	} | NoFiles++brightFiles :: BrightOpts -> IO Files+brightFiles opts =+	do+		is_curr <- fileExist $ (fCurr files)+		is_max  <- fileExist $ (fCurr files)+		if is_curr && is_max+			then return files+			else return NoFiles+	where+		prefix = sysDir </> (subDir opts)+		files = Files { fCurr = prefix </> (currBright opts)+		              , fMax = prefix </> (maxBright opts)+		              }+++runBright :: [String] ->  Monitor String+runBright args = do+	opts <- io $ parseOpts args+	f <- io $ brightFiles opts+	c <- io $ readBright f+	case f of+		NoFiles -> return "hurz"+		_ -> do x <- fmtPercent c+			parseTemplate (x)+	where+		fmtPercent :: Float -> Monitor [String]+		fmtPercent c = do+			r <- showHorizontalBar (100 * c)+			s <- showPercentWithColors c+			t <- showPercentBar (100 * c) c+			return [r,s,t]++readBright :: Files -> IO Float+readBright NoFiles = return 0+readBright files =+	do+		currVal<- grab $ (fCurr files)+		maxVal <- grab $ (fMax files)+		return $ (currVal / maxVal) +	where+		grab f = catch (fmap (read . B.unpack) $ B.readFile f)(\_ -> return 0)+++showHorizontalBar :: Float -> Monitor String+showHorizontalBar x = do+	return $ [convert x]+	where+		convert :: Float -> Char+		convert val +			| t <= 9600 = ' '+			| t > 9608 = chr 9608+			| otherwise = chr t+			where+				-- we scale from 0 to 100, we have 8 slots (9 elements), 100/8 = 12+				t = 9600 + ((round val) `div` 12)
src/Plugins/Monitors/CoreCommon.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE PatternGuards, CPP #-}+ ----------------------------------------------------------------------------- -- | -- Module      :  Plugins.Monitors.CoreCommon@@ -14,46 +16,128 @@  module Plugins.Monitors.CoreCommon where +import Control.Applicative+import Control.Monad+import Data.Char hiding (Space)+import Data.Function+import Data.List+import Data.Maybe import Plugins.Monitors.Common-import System.Posix.Files (fileExist)-import System.IO (withFile, IOMode(ReadMode), hGetLine) import System.Directory-import Data.Char (isDigit)-import Data.List (isPrefixOf) --- |--- Function checks the existence of first file specified by pattern and if the--- file doesn't exists failure message is shown, otherwise the data retrieval--- is performed.-checkedDataRetrieval :: (Num a, Ord a, Show a) =>-                        String -> String -> String -> String -> (Double -> a)-                        -> (a -> String) -> Monitor String-checkedDataRetrieval failureMessage dir file pattern trans fmt = do-    exists <- io $ fileExist $ concat [dir, "/", pattern, "0/", file]-    case exists of-         False  -> return failureMessage-         True   -> retrieveData dir file pattern trans fmt+#ifdef GHC6+import Control.Monad.Reader --- |--- Function retrieves data from files in directory dir specified by--- pattern. String values are converted to double and 'trans' applied--- to each one. Final array is processed by template parser function--- and returned as monitor string.-retrieveData :: (Num a, Ord a, Show a) =>-                String -> String -> String -> (Double -> a) -> (a -> String) ->-                Monitor String-retrieveData dir file pattern trans fmt = do-    count <- io $ dirCount dir pattern-    contents <- io $ mapM getGuts $ files count-    values <- mapM (showWithColors fmt) $ map conversion contents-    parseTemplate values-    where-        getGuts f = withFile f ReadMode hGetLine-        dirCount path str = getDirectoryContents path-                            >>= return . length-                                       . filter (\s -> str `isPrefixOf` s-                                                       && isDigit (last s))-        files count = map (\i -> concat [dir, "/", pattern, show i, "/", file])-                          [0 .. count - 1]-        conversion = trans . (read :: String -> Double)+instance (Monad f, Applicative f) => Applicative (ReaderT r f) where+    pure a = ReaderT $ const (pure a)+    f <*> a = ReaderT $ \r -> +              ((runReaderT f r) <*> (runReaderT a r))+#endif +checkedDataRetrieval :: (Ord a, Num a)+                     => String -> [String] -> Maybe (String, String -> Int)+                     -> (Double -> a) -> (a -> String) -> Monitor String+checkedDataRetrieval msg path lbl trans fmt = liftM (maybe msg id) $+                                              retrieveData path lbl trans fmt++retrieveData :: (Ord a, Num a)+             => [String] -> Maybe (String, String -> Int)+             -> (Double -> a) -> (a -> String) -> Monitor (Maybe String)+retrieveData path lbl trans fmt = do+  pairs <- map snd . sortBy (compare `on` fst) <$> (mapM readFiles =<< findFiles path lbl)+  if null pairs+    then return Nothing+    else Just <$> (     parseTemplate+                    =<< mapM (showWithColors fmt . trans . read) pairs+                  )++-- | Represents the different types of path components+data Comp = Fix String+          | Var [String]+          deriving Show++-- | Used to represent parts of file names separated by slashes and spaces+data CompOrSep = Slash+               | Space+               | Comp String+               deriving (Eq, Show)++-- | Function to turn a list of of strings into a list of path components+pathComponents :: [String] -> [Comp]+pathComponents = joinComps . drop 2 . concat . intersperse [Space] . map splitParts+  where+    splitParts p | (l, _:r) <- break (== '/') p = (Comp l):Slash:splitParts r+                 | otherwise                    = [Comp p]++    joinComps = uncurry joinComps' . partition isComp++    isComp (Comp _) = True+    isComp _        = False++    fromComp (Comp s) = s+    fromComp _        = error "fromComp applied to value other than (Comp _)"++    joinComps' cs []     = [Fix $ fromComp $ head cs] -- cs should have only one element here,+                                                      -- but this keeps the pattern matching+                                                      -- exhaustive+    joinComps' cs (p:ps) = let (ss, ps') = span (== p) ps+                               ct        = if null ps' || (p == Space) then length ss + 1+                                                                       else length ss+                               (ls, rs)  = splitAt (ct+1) cs+                               c         = case p of+                                             Space -> Var $ map fromComp ls+                                             Slash -> Fix $ intercalate "/" $ map fromComp ls+                                             _     -> error "Should not happen"+                           in  if null ps' then [c]+                                           else c:joinComps' rs (drop ct ps)++-- | Function to find all files matching the given path and possible label file.+-- The path must be absolute (start with a leading slash).+findFiles :: [String] -> Maybe (String, String -> Int)+          -> Monitor [(String, Either Int (String, String -> Int))]+findFiles path lbl  =  catMaybes+                   <$> (     mapM addLabel . zip [0..] . sort+                         =<< recFindFiles (pathComponents path) "/"+                       )+  where+    addLabel (i, f) = maybe (return $ Just (f, Left i))+                            (\(s, t) -> justIfExists f s t)+                            lbl++    justIfExists f s t = let f' = take (length f - length s) f ++ s+                         in  ifthen (Just (f, Right (f', t))) Nothing <$> (io $ doesFileExist f')++    recFindFiles [] d  =  ifthen [d] []+                      <$> (io $ if null d then return False else doesFileExist d)+    recFindFiles ps d  =  ifthen (recFindFiles' ps d) (return [])+                      =<< (io $ if null d then return True else doesDirectoryExist d)++    recFindFiles' []         _  =  error "Should not happen"+    recFindFiles' (Fix p:ps) d  =  recFindFiles ps (d ++ "/" ++ p)+    recFindFiles' (Var p:ps) d  =  concat+                               <$> (     mapM (recFindFiles ps)+                                      .  map (\f -> d ++ "/" ++ f)+                                      .  filter (matchesVar p)+                                     =<< (io $ getDirectoryContents d)+                                   )++    matchesVar []     _  = False+    matchesVar [v]    f  = v == f+    matchesVar (v:vs) f  = let f'  = drop (length v) f+                               f'' = dropWhile isDigit f'+                           in  and [ v `isPrefixOf` f+                                   , not (null f')+                                   , isDigit (head f')+                                   , matchesVar vs f''+                                   ]++-- | Function to read the contents of the given file(s)+readFiles :: (String, Either Int (String, String -> Int))+          -> Monitor (Int, String)+readFiles (fval, flbl) = (,) <$> either return (\(f, ex) -> liftM ex+                                                          $ io $ readFile f) flbl+                             <*> (io $ readFile fval)++-- | Function that captures if-then-else+ifthen :: a -> a -> Bool -> a+ifthen thn els cnd = if cnd then thn else els
src/Plugins/Monitors/CoreTemp.hs view
@@ -31,11 +31,9 @@ -- Function retrieves monitor string holding the core temperature -- (or temperatures) runCoreTemp :: [String] -> Monitor String-runCoreTemp _ = do-    let dir = "/sys/bus/platform/devices"-        file = "temp1_input"-        pattern = "coretemp."-        divisor = 1e3 :: Double-        failureMessage = "CoreTemp: N/A"-    checkedDataRetrieval failureMessage dir file pattern (/divisor) show+runCoreTemp _ = let path = ["/sys/bus/platform/devices/coretemp.", "/temp", "_input"]+                    lbl  = Just ("_label", read . drop 5)+                    divisor = 1e3 :: Double+                    failureMessage = "CoreTemp: N/A"+                in  checkedDataRetrieval failureMessage path lbl (/divisor) show 
src/Plugins/Monitors/Cpu.hs view
@@ -22,7 +22,7 @@ cpuConfig :: IO MConfig cpuConfig = mkMConfig        "Cpu: <total>%"-       ["bar","total","user","nice","system","idle"]+       ["bar","total","user","nice","system","idle","iowait"]  type CpuDataRef = IORef [Float] @@ -45,7 +45,7 @@ formatCpu :: [Float] -> Monitor [String] formatCpu [] = return $ replicate 6 "" formatCpu xs = do-  let t = foldr (+) 0 $ take 3 xs+  let t = sum $ take 3 xs   b <- showPercentBar (100 * t) t   ps <- showPercentsWithColors (t:xs)   return (b:ps)
src/Plugins/Monitors/CpuFreq.hs view
@@ -28,16 +28,12 @@                                                               -- replacements  -- |--- Function retrieves monitor string holding the cpu frequency (or--- frequencies)+-- Function retrieves monitor string holding the cpu frequency (or frequencies) runCpuFreq :: [String] -> Monitor String-runCpuFreq _ = do-    let dir = "/sys/devices/system/cpu"-        file = "cpufreq/scaling_cur_freq"-        pattern = "cpu"-        divisor = 1e6 :: Double-        failureMessage = "CpuFreq: N/A"-        fmt x | x < 1     = show (round (x * 1000) :: Integer) ++ "MHz"-              | otherwise = showDigits 1 x ++ "GHz"-    checkedDataRetrieval failureMessage dir file pattern (/divisor) fmt+runCpuFreq _ = let path = ["/sys/devices/system/cpu/cpu", "/cpufreq/scaling_cur_freq"]+                   divisor = 1e6 :: Double+                   failureMessage = "CpuFreq: N/A"+                   fmt x | x < 1     = (show (round (x * 1000) :: Integer)) ++ "MHz"+                         | otherwise = (show x) ++ "GHz"+               in  checkedDataRetrieval failureMessage path Nothing (/divisor) fmt 
src/Plugins/Monitors/MPD.hs view
@@ -91,7 +91,7 @@ parseSong (Right (Just s)) =   let join [] = ""       join (x:xs) = foldl (\a o -> a ++ ", " ++ o) x xs-      str sel = maybe "" join (M.sgGet sel s)+      str sel = maybe "" join (M.sgGetTag sel s)       sels = [ M.Name, M.Artist, M.Composer, M.Performer              , M.Album, M.Title, M.Track, M.Genre ]       fields = M.sgFilePath s : map str sels
src/Plugins/Monitors/Top.hs view
@@ -13,6 +13,7 @@ -----------------------------------------------------------------------------  {-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE BangPatterns #-}  module Plugins.Monitors.Top (startTop, topMemConfig, runTopMem) where 
src/Plugins/Monitors/Volume.hs view
@@ -14,10 +14,12 @@  module Plugins.Monitors.Volume (runVolume, volumeConfig) where +import Prelude hiding ( catch ) import Control.Monad ( liftM, mplus ) import Data.Maybe import Plugins.Monitors.Common import Sound.ALSA.Mixer+import Sound.ALSA.Exception ( catch ) import System.Console.GetOpt  volumeConfig :: IO MConfig@@ -115,7 +117,8 @@         maybeNA = maybe (return "N/A")     (lo, hi) <- io $ getRange volumeControl     val <- io $ getChannel FrontLeft $ value volumeControl-    db <- io $ getChannel FrontLeft $ dB volumeControl+    db <- io $ catch (getChannel FrontLeft $ dB volumeControl)+                     (\_ -> return $ Just 0)     sw <- io $ getChannel FrontLeft switchControl     p <- maybeNA (formatVol lo hi) val     b <- maybeNA (formatVolBar lo hi) val
src/Plugins/Monitors/Wireless.hs view
@@ -25,10 +25,9 @@ runWireless (iface:_) = do   wi <- io $ getWirelessInfo iface   let essid = wiEssid wi-      qlty = wiQuality wi-      fqlty = fromIntegral qlty+      qlty = fromIntegral $ wiQuality wi       e = if essid == "" then "N/A" else essid-  q <- if qlty >= 0 then showWithColors show qlty else showWithPadding ""-  qb <- showPercentBar fqlty (fqlty / 100)+  q <- if qlty >= 0 then showPercentWithColors (qlty/100) else showWithPadding ""+  qb <- showPercentBar qlty (qlty / 100)   parseTemplate [e, q, qb] runWireless _ = return ""
src/StatFS.hsc view
@@ -23,7 +23,11 @@ import Data.ByteString (useAsCString) import Data.ByteString.Char8 (pack) -#if defined (__FreeBSD__) || defined (__APPLE__)+#if  defined (__FreeBSD__) || defined (__OpenBSD__) ||  defined (__APPLE__)+#define IS_BSD_SYSTEM+#endif++#ifdef IS_BSD_SYSTEM # include <sys/param.h> # include <sys/mount.h> #else@@ -47,7 +51,7 @@  data CStatfs -#if defined (__FreeBSD__) || defined (__APPLE__)+#ifdef IS_BSD_SYSTEM foreign import ccall unsafe "sys/mount.h statfs" #else foreign import ccall unsafe "sys/vfs.h statfs64"
src/XUtil.hsc view
@@ -1,8 +1,8 @@-{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE ForeignFunctionInterface #-} ----------------------------------------------------------------------------- -- | -- Module      :  XUtil--- Copyright   :  (C) 2007 Andrea Rossato+-- Copyright   :  (C) 2007, 2011 Andrea Rossato -- License     :  BSD3 -- -- Maintainer  :  andrea.rossato@unitn.it@@ -28,12 +28,15 @@     , fi     , withColors     , DynPixel(..)+    , xrrSelectInput+    , xrrQueryExtension     ) where  import Control.Concurrent import Control.Monad.Trans import Data.IORef import Foreign+import Foreign.C.Types import Graphics.X11.Xlib hiding (textExtents, textWidth) import qualified Graphics.X11.Xlib as Xlib (textExtents, textWidth) import Graphics.X11.Xlib.Extras@@ -257,3 +260,12 @@ setupLocale :: IO () setupLocale = return () #endif++--  XRRSelectInput+#include <X11/extensions/Xrandr.h>+foreign import ccall unsafe "X11/extensions/Xrandr.h XRRSelectInput"+  xrrSelectInput :: Display -> Window -> EventMask -> IO ()++--  XRRQueryExtension+foreign import ccall unsafe "X11/extensions/Xrandr.h XRRQueryExtension"+  xrrQueryExtension :: Display -> Ptr CInt -> Ptr CInt -> IO (Bool)
src/Xmobar.hs view
@@ -17,7 +17,7 @@     ( -- * Main Stuff       -- $main       X , XConf (..), runX-    , eventLoop+    , startLoop     -- * Program Execution     -- $command     , startCommand@@ -42,7 +42,9 @@ import Data.Bits import Data.Maybe(fromMaybe) import Data.Typeable (Typeable)+import Foreign import System.Posix.Process (getProcessID)+import System.Posix.Signals  import Config import Parsers@@ -73,46 +75,107 @@ data WakeUp = WakeUp deriving (Show,Typeable) instance Exception WakeUp --- | The event loop-eventLoop :: XConf -> [[(Maybe ThreadId, TVar String)]] -> IO ()-eventLoop xc@(XConf d _ w fs c) vs = block $ do+data SignalType = Wakeup | Reposition | ChangeScreen++-- | Starts the main event loop and threads+startLoop :: XConf -> [[(Maybe ThreadId, TVar String)]] -> IO ()+startLoop xcfg@(XConf _ _ w _ _) vs = do     tv <- atomically $ newTVar []-    t  <- myThreadId-    ct <- forkIO (checker t tv [] `catch` \(SomeException _) -> return ())-    go tv ct- where-    -- interrupt the drawing thread every time a var is updated-    checker t tvar ov = do+    sig <- setupSignalHandler+    _ <- forkIO (checker tv [] vs sig `catch` \(SomeException _) -> putStrLn "Thread checker failed" >> return ())+    _ <- forkOS (eventer sig `catch` \(SomeException _) -> putStrLn "Thread eventer failed" >> return ())+    eventLoop tv xcfg sig+  where+    -- Reacts on events from X+    eventer signal =+      alloca $ \ptrEventBase ->+      alloca $ \ptrErrorBase ->+      allocaXEvent $ \e -> do++        dpy <- openDisplay ""+        --  keyPressMask is the same value as RRScreenChangeNotifyMask+        xrrSelectInput    dpy (defaultRootWindow dpy) keyPressMask+        selectInput       dpy w (exposureMask .|. structureNotifyMask)++        _ <- xrrQueryExtension dpy ptrEventBase ptrErrorBase+        xrrEventBase <- peek ptrEventBase++        forever $ do+          nextEvent dpy e+          ev <- getEvent e+          case ev of+            ConfigureEvent {} -> putMVar signal Reposition+            ExposeEvent {} -> putMVar signal Wakeup+            _ ->+              --  0 is the value of RRScreenChangeNotify+              when ( (fromIntegral (ev_event_type ev) - xrrEventBase) == 0)+                   $ putMVar signal Reposition++-- | Send signal to eventLoop every time a var is updated+checker :: TVar [String] -> [String] -> [[(Maybe ThreadId, TVar String)]] -> MVar SignalType -> IO ()+checker tvar ov vs signal = do       nval <- atomically $ do               nv <- mapM concatV vs               guard (nv /= ov)               writeTVar tvar nv               return nv-      throwTo t WakeUp-      checker t tvar nval+      putMVar signal Wakeup+      checker tvar nval vs signal+    where+      concatV = fmap concat . mapM (readTVar . snd) -    concatV = fmap concat . mapM (readTVar . snd) -    -- Continuously wait for a timer interrupt or an expose event-    go tv ct = do-      catch (unblock $ allocaXEvent $ \e ->-                 handle tv ct =<< (nextEvent' d e >> getEvent e))-            (\WakeUp -> runX xc (updateWin tv) >> return ())-      go tv ct+-- | Continuously wait for a signal from a thread or a interrupt handler+eventLoop :: TVar [String] -> XConf -> MVar SignalType -> IO ()+eventLoop tv xc@(XConf d _ w fs cfg) signal = do+      typ <- takeMVar signal+      case typ of+         Wakeup -> do+            runX xc (updateWin tv)+            eventLoop tv xc signal -    -- event hanlder-    handle _ ct (ConfigureEvent {ev_window = win}) = do-      rootw <- rootWindow d (defaultScreen d)-      when (win == rootw) $ block $ do-                      killThread ct-                      destroyWindow d w-                      (r',w') <- createWin d fs c-                      eventLoop (XConf d r' w' fs c) vs+         Reposition ->+            reposWindow cfg -    handle tvar _ (ExposeEvent {}) = runX xc (updateWin tvar)+         ChangeScreen -> do+            ncfg <- updateConfigPosition cfg+            reposWindow ncfg -    handle _ _ _  = return ()+    where+        reposWindow rcfg = do+          r' <- repositionWin d w fs rcfg+          eventLoop tv (XConf d r' w fs rcfg) signal +        updateConfigPosition ocfg =+          case position ocfg of+            OnScreen n o -> do+              srs <- getScreenInfo d+              if n == length srs then+                  return (ocfg {position = OnScreen 1 o})+                else+                  return (ocfg {position = OnScreen (n+1) o})+            o ->+              return (ocfg {position = OnScreen 1 o})+++-- | Signal handling+setupSignalHandler :: IO (MVar SignalType)+setupSignalHandler = do+   tid   <- newEmptyMVar+   installHandler sigUSR2 (Catch $ updatePosHandler tid) Nothing+   installHandler sigUSR1 (Catch $ changeScreenHandler tid) Nothing+   return tid++updatePosHandler :: MVar SignalType -> IO ()+updatePosHandler sig = do+   putMVar sig Reposition+   return ()++changeScreenHandler :: MVar SignalType -> IO ()+changeScreenHandler sig = do+   putMVar sig ChangeScreen+   return ()+ -- $command  -- | Runs a command as an independent thread and returns its thread id@@ -120,7 +183,7 @@ startCommand :: (Runnable,String,String) -> IO (Maybe ThreadId, TVar String) startCommand (com,s,ss)     | alias com == "" = do var <- atomically $ newTVar is-                           atomically $ writeTVar var "Could not parse the template"+                           atomically $ writeTVar var (s ++ ss)                            return (Nothing,var)     | otherwise       = do var <- atomically $ newTVar is                            let cb str = atomically $ writeTVar var (s ++ str ++ ss)@@ -140,12 +203,22 @@   let ht    = as + ds + 4       (r,o) = setPosition (position c) srs (fi ht)   win <- newWindow  d (defaultScreenOfDisplay d) rootw r o-  selectInput       d win (exposureMask .|. structureNotifyMask)   setProperties r c d win srs   when (lowerOnStart c) (lowerWindow d win)   mapWindow         d win   return (r,win) +-- | Updates the size and position of the window+repositionWin :: Display -> Window -> XFont -> Config -> IO (Rectangle)+repositionWin d win fs c = do+  srs     <- getScreenInfo d+  (as,ds) <- textExtents fs "0"+  let ht    = as + ds + 4+      (r,_) = setPosition (position c) srs (fi ht)+  moveResizeWindow d win (rect_x r) (rect_y r) (rect_width r) (rect_height r)+  setProperties r c d win srs+  return r+ setPosition :: XPosition -> [Rectangle] -> Dimension -> (Rectangle,Bool) setPosition p rs ht =   case p' of@@ -292,7 +365,8 @@   let (conf,d)             = (config &&& display) r       Rectangle _ _ wid ht = rect r       totSLen              = foldr (\(_,_,len) -> (+) len) 0 sl-      valign               = (fi ht + fi (as + ds)) `div` 2 - 1+      fntsize              = fi (as + ds)+      valign               = fi ht - 1 - (fi ht - fntsize) `div` 2       remWidth             = fi wid - fi totSLen       offset               = case a of                                C -> (remWidth + offs) `div` 2
xmobar.cabal view
@@ -1,5 +1,5 @@ name:               xmobar-version:            0.13+version:            0.14 homepage:           http://projects.haskell.org/xmobar/ bug-reports:        http://code.google.com/p/xmobar/issues synopsis:           A Minimalistic Text Based Status Bar@@ -57,33 +57,45 @@   description: Use alsa-mixer to get the volume from soundcards.   default: False +flag with_datezone+  description: Enables localized date support+  default: False+ executable xmobar     hs-source-dirs:     src     main-is:            Main.hs     other-modules:-      Xmobar, Config, Parsers, Commands, XUtil, StatFS, Runnable,+      Xmobar, Config, Parsers, Commands, Localize, XUtil, StatFS, Runnable,       Plugins, Plugins.CommandReader, Plugins.Date, Plugins.EWMH,       Plugins.PipeReader, Plugins.StdinReader, Plugins.XMonadLog,-      Plugins.Utils, Plugins.Monitors, Plugins.Monitors.Batt,-      Plugins.Monitors.Common, Plugins.Monitors.CoreCommon,-      Plugins.Monitors.CoreTemp, Plugins.Monitors.CpuFreq,-      Plugins.Monitors.Cpu, Plugins.Monitors.Disk, Plugins.Monitors.Mem,+      Plugins.Utils, Plugins.Kbd, Plugins.Monitors,+      Plugins.Monitors.Batt, Plugins.Monitors.Common,+      Plugins.Monitors.CoreCommon, Plugins.Monitors.CoreTemp,+      Plugins.Monitors.CpuFreq, Plugins.Monitors.Cpu,+      Plugins.Monitors.Disk, Plugins.Monitors.Mem,       Plugins.Monitors.MultiCpu, Plugins.Monitors.Net,       Plugins.Monitors.Swap, Plugins.Monitors.Thermal,       Plugins.Monitors.ThermalZone, Plugins.Monitors.Top,-      Plugins.Monitors.Uptime, Plugins.Monitors.Weather+      Plugins.Monitors.Uptime, Plugins.Monitors.Weather,+      Plugins.Monitors.Bright      ghc-prof-options:   -prof -auto-all      if true-       ghc-options: -funbox-strict-fields -Wall+       ghc-options: -funbox-strict-fields -Wall -threaded+       extra-libraries: Xrandr -    if impl (ghc == 6.10.1) && arch (x86_64)-       ghc-options: -O0+    -- Use --disable-optimization configure flag+    -- if impl (ghc == 6.10.1) && arch (x86_64)+    --    ghc-options: -O0      if impl (ghc >= 6.12.1)        ghc-options: -fno-warn-unused-do-bind +    --  for instance declaration in src/Plugins/Monitors/CoreCommon.hs+    if impl (ghc < 7)+       cpp-options: -DGHC6+     build-depends: X11>=1.3.0, mtl, unix, parsec, filepath, stm, time      if flag(small_base)@@ -111,11 +123,17 @@        cpp-options: -DIWLIB      if flag(with_mpd) || flag(all_extensions)-       build-depends: libmpd >= 0.5+       build-depends: libmpd >= 0.6        other-modules: Plugins.Monitors.MPD        cpp-options: -DLIBMPD      if flag(with_alsa) || flag(all_extensions)        build-depends: alsa-mixer == 0.1.*+       build-depends: alsa-core == 0.5.*        other-modules: Plugins.Monitors.Volume        cpp-options: -DALSA++    if flag(with_datezone) || flag(all_extensions)+       build-depends: timezone-olson, timezone-series+       other-modules: Plugins.DateZone+       cpp-options: -DDATEZONE