module Data.Conduit.XInput
(xinputSource
,Device(..)
,Event(..)
,KeyCode(..))
where
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as S8
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import Data.Conduit.Process
import Data.Monoid
import System.Exit
newtype Device = Device Int
deriving (Num)
data Event
= Press
| Release
deriving (Enum,Bounded,Eq,Show)
newtype KeyCode =
KeyCode Int
deriving (Eq,Show,Num,Ord)
xinputSource :: MonadIO m
=> Device -> ConduitM i (Event,KeyCode) m ExitCode
xinputSource (Device device) =
do (exitCode,()) <- sourceCmdWithConsumer
("unbuffer xinput test " <> show device)
(CB.lines $= CL.mapMaybe parse $=
awaitForever (lift . yield))
return exitCode
parse :: ByteString -> Maybe (Event,KeyCode)
parse line =
case S8.words (S8.drop 4 line) of
[mode,S8.readInt -> Just (code,_)] ->
return (if mode == "release"
then Release
else Press
,KeyCode code)
_ -> Nothing