diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2012, Ben Gamari
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Ben Gamari nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/System/Linux/Input/Event.hsc b/System/Linux/Input/Event.hsc
new file mode 100644
--- /dev/null
+++ b/System/Linux/Input/Event.hsc
@@ -0,0 +1,89 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module System.Linux.Input.Event ( Event(..)
+                                , hReadEvent
+                                , 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
+
+#include <linux/input.h>
+
+data Event = SyncEvent { evTimestamp :: DiffTime
+                       , evSyncCode :: SyncType }
+           | KeyEvent { evTimestamp :: DiffTime
+                      , evKeyCode :: Key }
+           | 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)
+
+instance Storable Event where
+  sizeOf _ = (#size struct input_event)
+  alignment = sizeOf
+  peek ptr = do let time = (#ptr struct input_event, time) ptr
+                sec <- (#peek struct timeval, tv_sec) time
+                usec <- (#peek struct timeval, tv_usec) time
+                _type <- (#peek struct input_event, type) ptr :: IO Word16
+                code <- (#peek struct input_event, code) ptr :: IO Word16
+                value <- (#peek struct input_event, value) ptr :: IO Int32
+                let t = 1000000000000*fromIntegral (sec::Int) + 1000000*fromIntegral (usec::Int)
+                return $ case _type of
+                     (#const EV_SYN)     -> SyncEvent { evTimestamp = picosecondsToDiffTime t
+                                                      , evSyncCode = SyncType code }
+                     (#const EV_KEY)     -> KeyEvent { evTimestamp = picosecondsToDiffTime t
+                                                     , evKeyCode = Key code }
+                     (#const EV_REL)     -> RelEvent { evTimestamp = picosecondsToDiffTime t
+                                                     , evRelAxis = RelAxis code
+                                                     , evValue = value }
+                     (#const EV_ABS)     -> AbsEvent { evTimestamp = picosecondsToDiffTime t
+                                                     , evAbsAxis = AbsAxis code
+                                                     , evValue = value }
+                     (#const EV_MSC)     -> MscEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_SW )     -> SwEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_LED)     -> LedEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_SND)     -> SndEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_REP)     -> RepEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_FF)      -> FfEvent { evTimestamp = picosecondsToDiffTime t }
+                     (#const EV_FF_STATUS) -> FfStatusEvent { evTimestamp = picosecondsToDiffTime t }
+                     otherwise  -> error $ "unknown event type: " ++ show _type
+
+  poke = undefined
+
+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
+     print off
+     print len
+     withForeignPtr fptr $ peek . castPtr 
+
diff --git a/System/Linux/Input/Event/Constants.hsc b/System/Linux/Input/Event/Constants.hsc
new file mode 100644
--- /dev/null
+++ b/System/Linux/Input/Event/Constants.hsc
@@ -0,0 +1,48 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module System.Linux.Input.Event.Constants where
+
+import Foreign.C.Types
+import Data.Word
+import Data.Int
+
+#include <linux/input.h>
+
+newtype SyncType = SyncType Word16 deriving (Show, Eq)
+#{enum SyncType, SyncType
+ , sync_report      = SYN_REPORT
+ , sync_config      = SYN_CONFIG
+ , sync_mt_report   = SYN_MT_REPORT
+ , sync_dropped     = SYN_DROPPED
+ }
+
+-- TODO Finish
+newtype Key = Key Word16 deriving (Show, Eq)
+#{enum Key, Key
+ , key_reserved    = KEY_RESERVED
+ , key_esc         = KEY_ESC
+ }
+
+newtype RelAxis = RelAxis Word16 deriving (Show, Eq)
+#{enum RelAxis, RelAxis
+ , rel_x            = REL_X
+ , rel_y            = REL_Y
+ , rel_z            = REL_Z
+ , rel_rx           = REL_RX
+ , rel_ry           = REL_RY
+ , rel_rz           = REL_RZ
+ , rel_hWheel       = REL_HWHEEL
+ , rel_dial         = REL_DIAL
+ , rel_wheel        = REL_WHEEL
+ , rel_misc         = REL_MISC
+ }
+
+newtype AbsAxis = AbsAxis Word16 deriving (Show, Eq)
+#{enum AbsAxis, AbsAxis
+ , abs_x            = ABS_X
+ , abs_y            = ABS_Y
+ , abs_z            = ABS_Z
+ , abs_rx           = ABS_RX
+ , abs_ry           = ABS_RY
+ , abs_rz           = ABS_RZ
+ }
diff --git a/linux-evdev.cabal b/linux-evdev.cabal
new file mode 100644
--- /dev/null
+++ b/linux-evdev.cabal
@@ -0,0 +1,18 @@
+Name:                linux-evdev
+Version:             0.1
+Synopsis:            Bindings to Linux evdev input device interface.
+License:             BSD3
+License-file:        LICENSE
+Author:              Ben Gamari
+Maintainer:          bgamari.foss@gmail.com
+Category:            System
+Build-type:          Simple
+Cabal-version:       >=1.2
+
+Library
+  Exposed-modules:   System.Linux.Input.Event, System.Linux.Input.Event.Constants
+  Build-tools:       hsc2hs
+  Build-depends:     base           >= 4.0         && < 5.0,
+                     time           >= 1.4         && < 1.5,
+                     bytestring     >= 0.9         && < 0.11
+  
