diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2015 Moritz Kiefer
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,70 @@
+-- stolen from https://github.com/haskell/c2hs/issues/117#issuecomment-77403079
+module Main (main) where
+
+import Control.Exception (catch)
+import Control.Monad (forM)
+
+import Distribution.PackageDescription
+    (BuildInfo(..), Executable(..), Library(..), PackageDescription(..))
+import Distribution.Simple (UserHooks(..), defaultMainWithHooks, simpleUserHooks)
+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
+import Distribution.Simple.Setup (BuildFlags)
+-- Test-suites require Cabal-1.10 or greater
+import Distribution.PackageDescription (TestSuite(..))
+-- Benchmarks require Cabal-1.14 or greater
+import Distribution.PackageDescription (Benchmark(..))
+
+import System.Directory (doesDirectoryExist, getDirectoryContents)
+import System.Exit (ExitCode)
+import System.FilePath ((</>), takeExtensions)
+
+main :: IO ()
+main = defaultMainWithHooks simpleUserHooks { buildHook = chsBuildHook }
+
+addCSources :: [FilePath] -> BuildInfo -> BuildInfo
+addCSources newSrcs bi@(BuildInfo { cSources = oldSrcs }) = bi { cSources = newSrcs ++ oldSrcs }
+
+hasChsCExtension :: FilePath -> Bool
+hasChsCExtension file = takeExtensions file == ".chs.c"
+
+getRecursiveContents :: FilePath -> IO [FilePath]
+getRecursiveContents topdir = do
+    topdirExists <- doesDirectoryExist topdir
+    if (not topdirExists)
+       then return []
+       else do
+           names <- getDirectoryContents topdir
+           let properNames = filter (`notElem` [".", ".."]) names
+           paths <- forM properNames $ \name -> do
+               let path = topdir </> name
+               isDirectory <- doesDirectoryExist path
+               if isDirectory
+                  then getRecursiveContents path
+                  else return [path]
+           return (concat paths)
+
+chsBuildHook :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
+chsBuildHook pd lbi uh bf = (hook `catchExitCode` \_ -> hook) >> hook
+  where
+    hook :: IO ()
+    hook = chsBuildHook' pd lbi uh bf
+
+    catchExitCode :: IO a -> (ExitCode -> IO a) -> IO a
+    catchExitCode = catch
+
+chsBuildHook' :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
+chsBuildHook' pd@(PackageDescription
+                   { library     = mbLib
+                   , executables = exes
+                   , testSuites  = tss
+                   , benchmarks  = bms
+                   })
+             lbi uh bf = do
+    let distBuildDir = buildDir lbi
+    chsCFiles <- fmap (filter hasChsCExtension) $ getRecursiveContents distBuildDir
+    let pd' = pd { library     = fmap (\lib -> lib { libBuildInfo       = addCSources chsCFiles (libBuildInfo lib)      }) mbLib
+                 , executables = fmap (\exe -> exe { buildInfo          = addCSources chsCFiles (buildInfo exe)         }) exes
+                 , testSuites  = fmap (\ts  -> ts  { testBuildInfo      = addCSources chsCFiles (testBuildInfo ts)      }) tss
+                 , benchmarks  = fmap (\bm  -> bm  { benchmarkBuildInfo = addCSources chsCFiles (benchmarkBuildInfo bm) }) bms
+                 }
+    buildHook simpleUserHooks pd' lbi uh bf
diff --git a/src/WLC.chs b/src/WLC.chs
new file mode 100644
--- /dev/null
+++ b/src/WLC.chs
@@ -0,0 +1,326 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module WLC
+  ( WLCGeometry(..)
+  , WLCInterface(..)
+  , WLCKeyState(..)
+  , WLCKeyboard(..)
+  , WLCModifiers(..)
+  , WLCOrigin(..)
+  , WLCOutput(..)
+  , WLCPointer(..)
+  , WLCRequest(..)
+  , WLCSize(..)
+  , WLCTouch(..)
+  , WLCView(..)
+  , WLCViewState(..)
+  , WLCGeometryPtr
+  , WLCModifiersPtr
+  , WLCOriginPtr
+  , WLCSizePtr
+  , CBool
+  , WLCHandle
+  , WLCOutputPtr(..)
+  , WLCViewPtr(..)
+  , WLCModifier(..)
+  , WLCButtonStateBit(..)
+  , WLCKeyStateBit(..)
+  , WLCModifierBit(..)
+  , WLCTouchTypeBit(..)
+  , WLCViewStateBit(..)
+  , wlcInit
+  , wlcOutputGetMask
+  , wlcOutputGetViews
+  , wlcOutputGetResolution
+  , wlcOutputFocus
+  , wlcOutputSetMask
+  , wlcRun
+  , wlcTerminate
+  , wlcViewBringToFront
+  , wlcViewClose
+  , wlcViewFocus
+  , wlcViewGetMask
+  , wlcViewGetOutput
+  , wlcViewSetGeometry
+  , wlcViewSetMask
+  , wlcViewSetState
+  ) where
+
+import Control.Lens
+import Data.Default
+import Foreign
+import Foreign.C.String
+import Foreign.C.Types
+import Text.PrettyPrint.HughesPJClass
+import System.IO.Unsafe
+
+#include <wlc/wlc.h>
+
+
+data WLCInterface =
+  WLCInterface {_output :: WLCOutput
+               ,_view :: WLCView
+               ,_keyboard :: WLCKeyboard
+               ,_pointer :: WLCPointer
+               ,_touch :: WLCTouch
+               ,_compositor :: WLCCompositor}
+  deriving (Show)
+
+instance Default WLCInterface where
+  def = WLCInterface def def def def def def
+
+data WLCOutput =
+  WLCOutput {_outputCreated :: FunPtr (WLCHandle -> IO CBool)
+            ,_outputDestroyed :: FunPtr (WLCHandle -> IO ())
+            ,_outputFocus :: FunPtr (WLCHandle -> CBool -> IO ())
+            ,_outputResolution :: FunPtr (WLCHandle -> WLCSizePtr -> WLCSizePtr -> IO ())}
+  deriving (Show)
+
+instance Default WLCOutput where
+  def = WLCOutput nullFunPtr nullFunPtr nullFunPtr nullFunPtr
+
+data WLCView =
+  WLCView {_viewCreated :: FunPtr (WLCHandle -> IO CBool)
+          ,_viewDestroyed :: FunPtr (WLCHandle -> IO ())
+          ,_viewFocus :: FunPtr (WLCHandle -> CBool -> IO ())
+          ,_viewMoveToOutput :: FunPtr (WLCHandle -> WLCHandle -> WLCHandle -> IO ())
+          ,_viewRequest :: WLCRequest}
+  deriving (Show)
+
+instance Default WLCView where
+  def = WLCView nullFunPtr nullFunPtr nullFunPtr nullFunPtr def
+
+data WLCKeyboard =
+  WLCKeyboard {_keyboardKey :: FunPtr (WLCHandle ->
+                                      CUInt ->
+                                      WLCModifiersPtr ->
+                                      CUInt ->
+                                      CUInt ->
+                                      WLCKeyStateBit ->
+                                      IO CBool)}
+  deriving (Show)
+
+instance Default WLCKeyboard where
+  def = WLCKeyboard nullFunPtr
+
+data WLCPointer =
+  WLCPointer {_pointerButton :: FunPtr (WLCHandle ->
+                                       CUInt ->
+                                       WLCModifiersPtr ->
+                                       CUInt ->
+                                       WLCButtonStateBit ->
+                                       IO CBool)
+             ,_pointerScroll :: FunPtr (WLCHandle -> CUInt -> WLCModifiersPtr -> CUChar -> Ptr CDouble -> IO CBool)
+             ,_pointerMotion :: FunPtr (WLCHandle -> CUInt -> WLCOriginPtr -> IO CBool)}
+  deriving (Show)
+
+instance Default WLCPointer where
+  def = WLCPointer nullFunPtr nullFunPtr nullFunPtr
+
+data WLCTouch =
+  WLCTouch {_touchTouch :: FunPtr (WLCHandle ->
+                                  CUInt ->
+                                  WLCModifiersPtr ->
+                                  WLCTouchTypeBit ->
+                                  CInt ->
+                                  WLCOriginPtr ->
+                                  IO CBool)}
+  deriving (Show)
+
+instance Default WLCTouch where
+  def = WLCTouch nullFunPtr
+
+data WLCCompositor =
+  WLCCompositor {_ready :: FunPtr (IO ())}
+  deriving (Show)
+
+instance Default WLCCompositor where
+  def = WLCCompositor nullFunPtr
+
+data WLCSize =
+  WLCSize CUInt
+          CUInt
+  deriving (Show,Eq,Ord)
+
+
+data WLCRequest =
+  WLCRequest {_requestGeomety :: FunPtr (WLCHandle -> WLCGeometryPtr -> IO ())
+             ,_requestState :: FunPtr (WLCHandle -> WLCViewStateBit -> CBool -> IO ())}
+  deriving (Show)
+
+instance Default WLCRequest where
+  def = WLCRequest nullFunPtr nullFunPtr
+
+data WLCModifiers =
+  WLCModifiers {modifierLEDs :: CUInt
+               ,modifierMods :: CUInt}
+
+data WLCOrigin =
+  WLCOrigin {originX :: CInt
+            ,originY :: CInt} deriving Show
+
+instance Storable WLCOrigin where
+  sizeOf _ = {#sizeof wlc_origin#}
+  alignment _ = {#alignof wlc_origin#}
+  peek p = do
+    x <- {#get wlc_origin->x#} p
+    y <- {#get wlc_origin->y#} p
+    return (WLCOrigin x y)
+  poke p (WLCOrigin x y) = do
+    {#set wlc_origin.x#} p x
+    {#set wlc_origin.y#} p y
+
+data WLCGeometry =
+  WLCGeometry {origin :: WLCOrigin
+              ,size :: WLCSize}
+  deriving (Show)
+
+instance Storable WLCGeometry where
+  sizeOf _ = {#sizeof wlc_geometry#}
+  alignment _ = {#alignof wlc_geometry#}
+  peek p = do
+    origin <- peekByteOff p {#offsetof wlc_geometry->origin#}
+    size <- peekByteOff p {#offsetof wlc_geometry->size#}
+    return (WLCGeometry origin size)
+  poke p (WLCGeometry origin size) = do
+    pokeByteOff p {#offsetof wlc_geometry->origin#} origin
+    pokeByteOff p {#offsetof wlc_geometry->size#} size
+
+{#enum wlc_view_state_bit as WLCViewState {underscoreToCase} deriving (Eq,Show,Ord)#}
+{#enum wlc_key_state as WLCKeyState {underscoreToCase} deriving (Eq,Show,Ord)#}
+{#enum wlc_button_state as WLCButtonState {underscoreToCase} deriving (Eq,Show,Ord)#}
+{#enum wlc_touch_type as WLCTouchType {underscoreToCase} deriving (Eq,Show,Ord)#}
+{#enum wlc_modifier_bit as WLCModifier {underscoreToCase} deriving (Eq,Show,Ord)#}
+
+{#pointer *wlc_modifiers as WLCModifiersPtr -> WLCModifiers#}
+{#pointer *wlc_origin as WLCOriginPtr -> WLCOrigin#}
+{#pointer *wlc_interface as WLCInterfacePtr -> WLCInterface#}
+{#pointer *wlc_geometry as WLCGeometryPtr -> WLCGeometry#}
+{#pointer *wlc_size as WLCSizePtr -> WLCSize#}
+
+type WLCViewStateBit = CInt
+type WLCKeyStateBit = CInt
+type WLCButtonStateBit = CInt
+type WLCTouchTypeBit = CInt
+type WLCModifierBit = CInt
+type WLCHandle = CULong
+type CBool = CInt
+
+newtype WLCOutputPtr = WLCOutputPtr { unwrapOutput ::  WLCHandle } deriving (Show,Eq,Ord)
+newtype WLCViewPtr = WLCViewPtr { unwrapView :: WLCHandle } deriving (Show,Eq,Ord)
+
+instance Pretty WLCOutputPtr where
+  pPrint (WLCOutputPtr h) = text "WLCOutputPtr" <+> pPrint h
+
+instance Pretty WLCViewPtr where
+  pPrint (WLCViewPtr h) = text "WLCViewPtr" <+> pPrint h
+
+instance Pretty CULong where
+  pPrint = text . show
+
+instance Pretty CUInt where
+  pPrint = text . show
+
+instance Storable WLCInterface where
+  sizeOf _ = {#sizeof wlc_interface#}
+  alignment _ = {#alignof wlc_interface#}
+  peek p = do
+    o_created <- {#get wlc_interface->output.created#} p
+    o_destroyed <- {#get wlc_interface->output.destroyed#} p
+    o_focus <- {#get wlc_interface->output.focus#} p
+    o_resolution <- {#get wlc_interface->output.resolution#} p
+    v_created <- {#get wlc_interface->view.created#} p
+    v_destroyed <- {#get wlc_interface->view.destroyed#} p
+    v_focus <- {#get wlc_interface->view.focus#} p
+    v_move_to_output <- {#get wlc_interface->view.move_to_output#} p
+    v_r_geometry <- {#get wlc_interface->view.request.geometry#} p
+    v_r_state <- {#get wlc_interface->view.request.state#} p
+    k_key <- {#get wlc_interface->keyboard.key#} p
+    p_button <- {#get wlc_interface->pointer.button#} p
+    p_scroll <- {#get wlc_interface->pointer.scroll#} p
+    p_motion <- {#get wlc_interface->pointer.motion#} p
+    t_touch <- {#get wlc_interface->touch.touch#} p
+    c_ready <- {#get wlc_interface->compositor.ready#} p
+    return (WLCInterface
+              (WLCOutput o_created o_destroyed o_focus o_resolution)
+              (WLCView v_created v_destroyed v_focus v_move_to_output
+                       (WLCRequest v_r_geometry v_r_state))
+              (WLCKeyboard k_key)
+              (WLCPointer p_button p_scroll p_motion)
+              (WLCTouch t_touch)
+              (WLCCompositor c_ready))
+  poke p (WLCInterface
+          (WLCOutput o_created o_destroyed o_focus o_resolution)
+          (WLCView v_created v_destroyed v_focus v_move_to_output
+                   (WLCRequest v_r_geometry v_r_state))
+          (WLCKeyboard k_key)
+          (WLCPointer p_button p_scroll p_motion)
+          (WLCTouch t_touch)
+          (WLCCompositor c_ready)) = do
+            {#set wlc_interface.output.created#} p o_created
+            {#set wlc_interface.output.destroyed#} p o_destroyed
+            {#set wlc_interface.output.focus#} p o_focus
+            {#set wlc_interface.output.resolution#} p o_resolution
+            {#set wlc_interface.view.created#} p v_created
+            {#set wlc_interface.view.destroyed#} p v_destroyed
+            {#set wlc_interface.view.focus#} p v_focus
+            {#set wlc_interface.view.move_to_output#} p v_move_to_output
+            {#set wlc_interface.view.request.geometry#} p v_r_geometry
+            {#set wlc_interface.view.request.state#} p v_r_state
+            {#set wlc_interface.keyboard.key#} p k_key
+            {#set wlc_interface.pointer.button#} p p_button
+            {#set wlc_interface.pointer.scroll#} p p_scroll
+            {#set wlc_interface.pointer.motion#} p p_motion
+            {#set wlc_interface.touch.touch#} p t_touch
+            {#set wlc_interface.compositor.ready#} p c_ready
+
+instance Storable WLCModifiers where
+  sizeOf _ = {#sizeof wlc_modifiers#}
+  alignment _ = {#alignof wlc_modifiers#}
+  peek p = do
+    leds <- {#get wlc_modifiers->leds#} p
+    mods <- {#get wlc_modifiers->mods#} p
+    return (WLCModifiers leds mods)
+  poke p (WLCModifiers leds mods) = do
+    {#set wlc_modifiers.leds#} p leds
+    {#set wlc_modifiers.mods#} p mods
+
+instance Storable WLCSize where
+  sizeOf _ = {#sizeof wlc_size#}
+  alignment _ = {#alignof wlc_size#}
+  peek p = do
+    w <- {#get wlc_size->w#} p
+    h <- {#get wlc_size->h#} p
+    return (WLCSize w h)
+  poke p (WLCSize w h) = do
+    {#set wlc_size.w#} p w
+    {#set wlc_size.h#} p h
+
+{#typedef size_t CSize#}
+
+{#fun wlc_init as ^ {with* `WLCInterface', withStringListLen* `[String]'&} -> `Bool'#}
+{#fun wlc_run as ^ {} -> `()'#}
+{#fun wlc_terminate as ^ {} -> `()'#}
+{#fun wlc_output_get_resolution as ^ {unwrapOutput `WLCOutputPtr'} -> `WLCSize' peek*#}
+{#fun wlc_output_get_views as wlcOutputGetViews' {unwrapOutput `WLCOutputPtr', alloca- `CSize' peek*} -> `Ptr WLCHandle' id#}
+{#fun wlc_output_get_mask as ^ {unwrapOutput `WLCOutputPtr'} -> `CUInt' id#}
+{#fun wlc_output_set_mask as ^ {unwrapOutput `WLCOutputPtr', `CUInt'} -> `()' id#}
+{#fun wlc_output_focus as ^ {unwrapOutput `WLCOutputPtr'} -> `()' id#}
+{#fun wlc_view_bring_to_front as ^ {unwrapView `WLCViewPtr'} -> `()'#}
+{#fun wlc_view_focus as ^ {unwrapView `WLCViewPtr'} -> `()'#}
+{#fun wlc_view_get_mask as ^ {unwrapView `WLCViewPtr'} -> `CUInt' id#}
+{#fun wlc_view_set_mask as ^ {unwrapView `WLCViewPtr', `CUInt'} -> `()' id#}
+{#fun wlc_view_get_output as ^ {unwrapView `WLCViewPtr'} -> `WLCHandle' id#}
+{#fun wlc_view_set_geometry as ^ {unwrapView `WLCViewPtr', with* `WLCGeometry'} -> `()'#}
+{#fun wlc_view_set_state as ^ {unwrapView `WLCViewPtr', `WLCViewState', `Bool'} -> `()'#}
+{#fun wlc_view_close as ^ {unwrapView `WLCViewPtr'} -> `()' id#}
+
+wlcOutputGetViews :: WLCOutputPtr -> IO [WLCHandle]
+wlcOutputGetViews handle = do
+  (ptr,size) <- wlcOutputGetViews' handle
+  peekArray (fromIntegral size) ptr
+
+withStringListLen :: [String] -> ((CInt, Ptr (Ptr CChar)) -> IO a) -> IO a
+withStringListLen args f = do
+  cstrings <- mapM newCString args
+  withArray cstrings (\array -> f (fromIntegral $ length args, array))
diff --git a/src/WLC/Lenses.hs b/src/WLC/Lenses.hs
new file mode 100644
--- /dev/null
+++ b/src/WLC/Lenses.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE TemplateHaskell #-}
+module WLC.Lenses where
+
+import Control.Lens
+
+import WLC
+
+makeLenses ''WLCInterface
+makeLenses ''WLCOutput
+makeLenses ''WLCView
+makeLenses ''WLCKeyboard
+makeLenses ''WLCPointer
+makeLenses ''WLCTouch
+makeLenses ''WLCRequest
diff --git a/src/WLC/Wrapper.hs b/src/WLC/Wrapper.hs
new file mode 100644
--- /dev/null
+++ b/src/WLC/Wrapper.hs
@@ -0,0 +1,73 @@
+module WLC.Wrapper
+  ( wrapCreated
+  , wrapDestroyed
+  , wrapFocus
+  , wrapResolution
+  , wrapMoveToOutput
+  , wrapGeometry
+  , wrapState
+  , wrapKey
+  , wrapButton
+  , wrapScroll
+  , wrapMotion
+  , wrapTouch
+  ) where
+
+import Foreign.C.Types
+import Foreign
+
+import WLC
+
+foreign import ccall "wrapper"
+  wrapCreated :: (WLCHandle -> IO CBool) -> IO (FunPtr (WLCHandle -> IO CBool))
+
+foreign import ccall "wrapper"
+  wrapDestroyed :: (WLCHandle -> IO ()) -> IO (FunPtr (WLCHandle -> IO ()))
+
+foreign import ccall "wrapper"
+  wrapFocus :: (WLCHandle -> CBool -> IO ()) -> IO (FunPtr (WLCHandle -> CBool -> IO ()))
+
+foreign import ccall safe "wrapper" 
+  wrapResolution ::
+    (WLCHandle -> WLCSizePtr -> WLCSizePtr -> IO ()) ->
+    IO (FunPtr (WLCHandle -> WLCSizePtr -> WLCSizePtr -> IO ()))
+
+foreign import ccall safe "wrapper"
+  wrapMoveToOutput ::
+    (WLCHandle -> WLCHandle -> WLCHandle -> IO ()) ->
+    IO (FunPtr (WLCHandle -> WLCHandle -> WLCHandle -> IO ()))
+
+foreign import ccall safe "wrapper"
+  wrapGeometry ::
+    (WLCHandle -> WLCGeometryPtr -> IO ()) ->
+    IO (FunPtr (WLCHandle -> WLCGeometryPtr -> IO ()))
+
+foreign import ccall safe "wrapper"
+  wrapState ::
+    (WLCHandle -> WLCViewStateBit -> CBool -> IO ()) ->
+    IO (FunPtr (WLCHandle -> WLCViewStateBit -> CBool -> IO ()))
+
+foreign import ccall safe "wrapper"
+  wrapKey ::
+    (WLCHandle -> CUInt -> WLCModifiersPtr -> CUInt -> CUInt -> WLCKeyStateBit -> IO CBool) ->
+    IO (FunPtr (WLCHandle -> CUInt -> WLCModifiersPtr -> CUInt -> CUInt -> WLCKeyStateBit -> IO CBool))
+
+foreign import ccall safe "wrapper"
+  wrapButton ::
+    (WLCHandle -> CUInt -> WLCModifiersPtr -> CUInt -> WLCButtonStateBit -> IO CBool) ->
+    IO (FunPtr (WLCHandle -> CUInt -> WLCModifiersPtr -> CUInt -> WLCButtonStateBit -> IO CBool))
+
+foreign import ccall safe "wrapper"
+  wrapScroll ::
+    (WLCHandle -> CUInt -> WLCModifiersPtr -> CUChar -> Ptr CDouble -> IO CBool) ->
+    IO (FunPtr (WLCHandle -> CUInt -> WLCModifiersPtr -> CUChar -> Ptr CDouble -> IO CBool))
+
+foreign import ccall safe "wrapper"
+  wrapMotion ::
+    (WLCHandle -> CUInt -> WLCOriginPtr -> IO CBool) ->
+    IO (FunPtr (WLCHandle -> CUInt -> WLCOriginPtr -> IO CBool))
+
+foreign import ccall safe "wrapper"
+  wrapTouch ::
+    (WLCHandle -> CUInt -> WLCModifiersPtr -> WLCTouchTypeBit -> CInt -> WLCOriginPtr -> IO CBool) ->
+    IO (FunPtr (WLCHandle -> CUInt -> WLCModifiersPtr -> WLCTouchTypeBit -> CInt -> WLCOriginPtr -> IO CBool))
diff --git a/wlc-hs.cabal b/wlc-hs.cabal
new file mode 100644
--- /dev/null
+++ b/wlc-hs.cabal
@@ -0,0 +1,79 @@
+-- Initial wlc-hs.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                wlc-hs
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- http://www.haskell.org/haskellwiki/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            Haskell bindings for the wlc library
+
+-- A longer description of the package.
+-- description:         
+
+-- The license under which the package is released.
+license:             ISC
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Moritz Kiefer
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          moritz.kiefer@purelyfunctional.org
+
+-- A copyright notice.
+-- copyright:           
+
+category:            System
+
+build-type:          Custom
+
+-- Extra files to be distributed with the package, such as examples or a 
+-- README.
+-- extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.10
+
+
+library
+  -- Modules exported by the library.
+  exposed-modules:     WLC
+                     , WLC.Wrapper
+                     , WLC.Lenses
+  
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- LANGUAGE extensions used by modules in this package.
+  -- other-extensions:    
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base >=4.8 && < 4.9
+                     , containers >= 0.5 && < 0.6
+                     , data-default >= 0.5 && < 0.6
+                     , lens >= 4.8 && < 4.12
+                     , process >= 1.2 && < 1.3
+                     , transformers >= 0.4 && < 0.5
+                     , xkbcommon >= 0.0 && < 0.1
+                     , pretty >= 1.1 && < 1.2
+  
+  -- Directories containing source files.
+  hs-source-dirs:      src
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
+  build-tools:         c2hs
+  extra-libraries:     wlc
+  -- c-sources:
