summaryrefslogtreecommitdiff
path: root/custom/thinklight.nix
blob: d3d4e7caf57a03523a320150cca70a9549d96535 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{ stdenv, haskellPackages, thinklight ? "thinklight", makeWrapper }:

stdenv.mkDerivation {
  name = "thinklight-0.1";
  ghc = haskellPackages.ghcWithPackages (self: [self.strict]);
  outputs = [ "out" ];
  builder = builtins.toFile "builder.sh" ''
    source $stdenv/setup
    mkdir -p $out/bin
    $ghc/bin/ghc $src -o $out/bin/thinklight
    wrapProgram $out/bin/thinklight --set THINKLIGHT ${thinklight}
  '';
  src = builtins.toFile "source.hs" ''
    import Control.Monad (sequence)
    import System.IO.Error
    import System.Environment
    import System.FilePath
    import Control.Concurrent (threadDelay)
    import System.IO.Strict (readFile)
    import Prelude hiding (readFile)
    import Data.List (intersperse)
    
    data Mode = On | Off | Toggle | Blink deriving (Read, Show, Eq)
    
    main :: IO ()
    main = do
            args <- getArgs
            let mode = if length args >= 1 then read $ head args else Toggle
            sequence $ map (\g -> catchIOError g (\e -> if isDoesNotExistError e then return () else ioError e)) [thinklight mode]
            return ()

    findBase :: IO FilePath
    findBase = do
      env <- fromMaybe "thinklight" <$> lookupEnv "THINKLIGHT"
      return $ "/sys/class/leds/tpacpi::" ++ env

    readMax, readCurrent :: IO String
    readMax = readFile =<< ((</> "max_brightness") <$> findBase)
    readCurrent = readFile =<< ((</> "brightness") <$> findBase)
    writeCurrent :: String -> IO ()
    writeCurrent str = flip writeFile str =<< ((</> "brightness") <$> findBase)

    thinklight :: Mode -> IO ()
    thinklight On = readMax >>= writeCurrent . show
    thinklight Off = writeCurrent "0"
    thinklight Toggle = do
            c <- readCurrent
            m <- readMax
            let m' = read m :: Int
            let c' = read c :: Int
            writeCurrent $ show $ if c' /= 0 then 0 else m'
    thinklight Blink = do
            args <- getArgs
            thinklight Toggle
            sequence $ intersperse (thinklight Toggle) $ map (\i -> threadDelay $ (read i) * 10^3) (tail args)
            thinklight Toggle
  '';
}