module System.Linux.Input.Event (
Event(..)
, hReadEvent
, KeyEventType(..)
, module System.Linux.Input.Event.Constants
) where
import Data.Word
import Data.Int
import Data.ByteString as BS
import Data.ByteString.Internal
import Data.Time.Clock
import Foreign.Storable
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.C.Types
import System.IO
import System.Linux.Input.Event.Constants
data Event = SyncEvent { evTimestamp :: DiffTime
, evSyncCode :: SyncType }
| KeyEvent { evTimestamp :: DiffTime
, evKeyCode :: Key
, evKeyEventType :: KeyEventType }
| RelEvent { evTimestamp :: DiffTime
, evRelAxis :: RelAxis
, evValue :: Int32 }
| AbsEvent { evTimestamp :: DiffTime
, evAbsAxis :: AbsAxis
, evValue :: Int32 }
| MscEvent { evTimestamp :: DiffTime }
| SwEvent { evTimestamp :: DiffTime }
| LedEvent { evTimestamp :: DiffTime }
| SndEvent { evTimestamp :: DiffTime }
| RepEvent { evTimestamp :: DiffTime }
| FfEvent { evTimestamp :: DiffTime }
| FfStatusEvent { evTimestamp :: DiffTime }
deriving (Show, Eq)
data KeyEventType = Released | Depressed | Repeated
deriving (Show, Eq, Ord, Enum, Bounded)
instance Storable Event where
sizeOf _ = ((24))
alignment = sizeOf
peek ptr = do let time = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) ptr
sec <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) time
usec <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) time
_type <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) ptr :: IO Word16
code <- ((\hsc_ptr -> peekByteOff hsc_ptr 18)) ptr :: IO Word16
value <- ((\hsc_ptr -> peekByteOff hsc_ptr 20)) ptr :: IO Int32
let t = 1000000000000*fromIntegral (sec::Int) + 1000000*fromIntegral (usec::Int)
return $ case _type of
(0) -> SyncEvent { evTimestamp = picosecondsToDiffTime t
, evSyncCode = SyncType code
}
(1) -> KeyEvent { evTimestamp = picosecondsToDiffTime t
, evKeyCode = Key code
, evKeyEventType = toEnum (fromIntegral value)
}
(2) -> RelEvent { evTimestamp = picosecondsToDiffTime t
, evRelAxis = RelAxis code
, evValue = value
}
(3) -> AbsEvent { evTimestamp = picosecondsToDiffTime t
, evAbsAxis = AbsAxis code
, evValue = value
}
(4) -> MscEvent { evTimestamp = picosecondsToDiffTime t }
(5) -> SwEvent { evTimestamp = picosecondsToDiffTime t }
(17) -> LedEvent { evTimestamp = picosecondsToDiffTime t }
(18) -> SndEvent { evTimestamp = picosecondsToDiffTime t }
(20) -> RepEvent { evTimestamp = picosecondsToDiffTime t }
(21) -> FfEvent { evTimestamp = picosecondsToDiffTime t }
(23) -> FfStatusEvent { evTimestamp = picosecondsToDiffTime t }
otherwise -> error $ "unknown event type: " ++ show _type
poke = error "Storable(System.Linux.Input.Event): poke not supported"
hReadEvent :: Handle -> IO (Maybe Event)
hReadEvent h = do
a <- hGet h $ sizeOf (undefined::Event)
case a of
_ | BS.null a -> return Nothing
_ | otherwise -> getEvent a >>= return . Just
getEvent :: ByteString -> IO Event
getEvent bs = do
let (fptr, off, len) = toForeignPtr bs
withForeignPtr fptr $ peek . castPtr