summaryrefslogtreecommitdiff
path: root/custom/thinklight.nix
blob: ced11d02e6f18e39e54536b419020d8dda7d50bf (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
59
60
61
62
{ stdenv, haskellPackages, thinklight ? "thinklight", makeWrapper }:

stdenv.mkDerivation {
  name = "thinklight-0.1";
  ghc = haskellPackages.ghcWithPackages (self: [self.strict self.unix]);
  outputs = [ "out" ];
  buildInputs = [ makeWrapper ];
  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)
    import Data.Maybe (fromMaybe)
    import System.Posix.User (setEffectiveUserID)
    
    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
	    setEffectiveUserID 0
            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
  '';
}