7 import Text.Regex.Posix
11 stPowerMate :: Handle,
16 stLastPress :: UTCTime
19 processEvent :: State -> Event -> IO State
20 processEvent state (Button True) = do
21 time <- getCurrentTime
22 state <- updateLastPress state (time)
23 state <- updateButton state True
25 processEvent state (Button False) = do
26 time <- getCurrentTime
27 if (diffUTCTime (time) (stLastPress state) > 0.8)
28 then ( do createProcess(proc "volume-toggle" []); return () )
29 else ( do runCommand "music-toggle"; return () )
30 state <- updateButton state False
33 processEvent state (Rotate dir) = do
34 state <- (if (stPressed state) == False
36 && (stPrevDir state) == 1
37 && (stPrevAction state) == 1
40 state <- (if (stPressed state) == False
42 && (stPrevDir state) == 0
43 && (stPrevAction state) == 0
46 when ((stPressed state) == True && dir < 2) ( do runCommand "next"; return () )
47 when ((stPressed state) == True && dir > 2) ( do runCommand "back"; return () )
48 state <- updatePrevState state (if dir < 2 then 1 else 0)
49 updateBrightness state
50 state <- updatePrevAction state (if (stPrevAction state) == 1 then 0 else 1)
53 readState :: State -> IO State
57 next :: a -> (a -> IO a) -> IO ()
59 newstate <- func state
63 updateBrightness :: State -> IO ()
64 updateBrightness state = do
65 let brightness = (stVolume state)
66 writeStatus (stPowerMate state) $
67 statusInit { brightness=brightness }
69 volumeUp :: State -> IO State
71 createProcess (proc "volume-up" [])
72 state <- readState $ State {
73 stPowerMate=(stPowerMate state),
74 stVolume=(max 0 $ 1+(stVolume state)),
75 stPrevAction=(stPrevAction state),
76 stPrevDir=(stPrevDir state),
77 stPressed=(stPressed state),
78 stLastPress=(stLastPress state) }
79 state <- updatePrevAction state 1
82 volumeDown :: State -> IO State
84 createProcess (proc "volume-down" [])
85 state <- readState $ State {
86 stPowerMate=(stPowerMate state),
87 stVolume=(max 0 $ (stVolume state)-1),
88 stPrevAction=(stPrevAction state),
89 stPrevDir=(stPrevDir state),
90 stPressed=(stPressed state),
91 stLastPress=(stLastPress state) }
92 state <- updatePrevAction state 0
95 updatePrevState :: State -> Int -> IO State
96 updatePrevState state dir = do
97 state <- readState $ State {
98 stPowerMate=(stPowerMate state),
99 stVolume=(stVolume state),
100 stPrevAction=(stPrevAction state),
102 stPressed=(stPressed state),
103 stLastPress=(stLastPress state) }
106 updatePrevAction :: State -> Int -> IO State
107 updatePrevAction state action = do
108 state <- readState $ State {
109 stPowerMate=(stPowerMate state),
110 stVolume=(stVolume state),
112 stPrevDir=(stPrevDir state),
113 stPressed=(stPressed state),
114 stLastPress=(stLastPress state) }
117 updateButton :: State -> Bool -> IO State
118 updateButton state button = do
119 state <- readState $ State {
120 stPowerMate=(stPowerMate state),
121 stVolume=(stVolume state),
122 stPrevAction=(stPrevAction state),
123 stPrevDir=(stPrevDir state),
125 stLastPress=(stLastPress state) }
128 updateLastPress :: State -> UTCTime -> IO State
129 updateLastPress state lastPress = do
130 state <- readState $ State {
131 stPowerMate=(stPowerMate state),
132 stVolume=(stVolume state),
133 stPrevAction=(stPrevAction state),
134 stPrevDir=(stPrevDir state),
135 stPressed=(stPressed state),
136 stLastPress=lastPress }
139 loop :: FilePath -> IO ()
141 powermate <- openDevice devname
143 alsaMixers <- readProcess "amixer" ["get", "Master"] []
144 let alsaMaster = (alsaMixers =~ "\\[([0-9]{1,2})%\\]" :: String)
145 let volume = read (drop 1
148 (length alsaMaster)) alsaMaster)) :: Int
149 time <- getCurrentTime
150 state <- readState $ State {
151 stPowerMate=powermate,
157 updateBrightness state
159 next state $ \call -> do
160 event <- readEventWithSkip powermate Nothing
162 Nothing -> return call
163 Just event -> processEvent call event
167 powermate <- searchForDevice