6 import Text.Regex.Posix
10 stPowerMate :: Handle,
15 stIndeterminate :: Bool,
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
24 state <- updateIndeterminate state True
26 processEvent state (Button False) = do
27 time <- getCurrentTime
28 if (stIndeterminate state)
30 if (diffUTCTime (time) (stLastPress state) > 0.8)
31 then do createProcess(proc "volume-toggle" []); return ()
32 else do runCommand "music-toggle"; return ()
34 state <- updateButton state False
37 processEvent state (Rotate dir) = do
38 state <- updateIndeterminate state False
39 state <- (if (stPressed state) == False
41 && (stPrevDir state) == 1
42 && (stPrevAction state) == 1
45 state <- (if (stPressed state) == False
47 && (stPrevDir state) == 0
48 && (stPrevAction state) == 0
53 if dir < 2 then do runCommand "next"; return ()
54 else do runCommand "back"; return ()
56 state <- updatePrevState state (if dir < 2 then 1 else 0)
57 updateBrightness state
58 state <- updatePrevAction state (if (stPrevAction state) == 1 then 0 else 1)
61 readState :: State -> IO State
65 next :: a -> (a -> IO a) -> IO ()
67 newstate <- func state
71 updateBrightness :: State -> IO ()
72 updateBrightness state = do
73 let brightness = (stVolume state)
74 writeStatus (stPowerMate state) $
75 statusInit { brightness=brightness }
77 updateIndeterminate :: State -> Bool -> IO State
78 updateIndeterminate state value = do
79 state <- readState $ State {
80 stPowerMate=(stPowerMate state),
81 stVolume=(stVolume state),
82 stPrevAction=(stPrevAction state),
83 stPrevDir=(stPrevDir state),
84 stPressed=(stPressed state),
85 stLastPress=(stLastPress state),
86 stIndeterminate=value }
89 volumeUp :: State -> IO State
91 createProcess (proc "volume-up" [])
92 state <- readState $ State {
93 stPowerMate=(stPowerMate state),
94 stVolume=(max 0 $ 1+(stVolume state)),
95 stPrevAction=(stPrevAction state),
96 stPrevDir=(stPrevDir state),
97 stPressed=(stPressed state),
98 stLastPress=(stLastPress state),
99 stIndeterminate=(stIndeterminate state) }
100 state <- updatePrevAction state 1
103 volumeDown :: State -> IO State
104 volumeDown state = do
105 createProcess (proc "volume-down" [])
106 state <- readState $ State {
107 stPowerMate=(stPowerMate state),
108 stVolume=(max 0 $ (stVolume state)-1),
109 stPrevAction=(stPrevAction state),
110 stPrevDir=(stPrevDir state),
111 stPressed=(stPressed state),
112 stLastPress=(stLastPress state),
113 stIndeterminate=(stIndeterminate state) }
114 state <- updatePrevAction state 0
117 updatePrevState :: State -> Int -> IO State
118 updatePrevState state dir = do
119 state <- readState $ State {
120 stPowerMate=(stPowerMate state),
121 stVolume=(stVolume state),
122 stPrevAction=(stPrevAction state),
124 stPressed=(stPressed state),
125 stLastPress=(stLastPress state),
126 stIndeterminate=(stIndeterminate state) }
129 updatePrevAction :: State -> Int -> IO State
130 updatePrevAction state action = do
131 state <- readState $ State {
132 stPowerMate=(stPowerMate state),
133 stVolume=(stVolume state),
135 stPrevDir=(stPrevDir state),
136 stPressed=(stPressed state),
137 stLastPress=(stLastPress state),
138 stIndeterminate=(stIndeterminate state) }
141 updateButton :: State -> Bool -> IO State
142 updateButton state button = do
143 state <- readState $ State {
144 stPowerMate=(stPowerMate state),
145 stVolume=(stVolume state),
146 stPrevAction=(stPrevAction state),
147 stPrevDir=(stPrevDir state),
149 stLastPress=(stLastPress state),
150 stIndeterminate=(stIndeterminate state) }
153 updateLastPress :: State -> UTCTime -> IO State
154 updateLastPress state lastPress = do
155 state <- readState $ State {
156 stPowerMate=(stPowerMate state),
157 stVolume=(stVolume state),
158 stPrevAction=(stPrevAction state),
159 stPrevDir=(stPrevDir state),
160 stPressed=(stPressed state),
161 stLastPress=lastPress,
162 stIndeterminate=(stIndeterminate state) }
165 loop :: FilePath -> IO ()
167 powermate <- openDevice devname
169 alsaMixers <- readProcess "amixer" ["get", "Master"] []
170 let alsaMaster = (alsaMixers =~ "\\[([0-9]{1,2})%\\]" :: String)
171 let volume = read (drop 1
174 (length alsaMaster)) alsaMaster)) :: Int
175 time <- getCurrentTime
176 state <- readState $ State {
177 stPowerMate=powermate,
183 stIndeterminate=False }
184 updateBrightness state
186 next state $ \call -> do
187 event <- readEventWithSkip powermate Nothing
189 Nothing -> return call
190 Just event -> processEvent call event
194 powermate <- searchForDevice