diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2016
+
+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 Author name here 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/bindings-wlc.cabal b/bindings-wlc.cabal
new file mode 100644
--- /dev/null
+++ b/bindings-wlc.cabal
@@ -0,0 +1,43 @@
+name:                bindings-wlc
+version:             0.1.0.0
+synopsis:            Bindings against the wlc library
+description:         Please see README.md
+homepage:            http://github.com/aktowns/bindings-wlc#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Ashley Towns
+maintainer:          mail@ashleytowns.id.au
+copyright:           2016 Ashley Towns
+category:            FFI
+build-type:          Simple
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:
+                       Bindings.WLC
+                       Bindings.WLC.Defines
+                       Bindings.WLC.Geometry
+                       Bindings.WLC.WLC
+                       Bindings.WLC.WLCRender
+                       Bindings.WLC.WLCWayland
+  build-depends:       base >= 4.7 && < 5,
+                       bindings-DSL >= 1.0.23 && < 1.1
+  default-language:    Haskell2010
+  extra-libraries:     wlc
+  default-extensions:
+    ForeignFunctionInterface
+
+test-suite bindings-wlc-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , bindings-wlc
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/aktowns/bindings-wlc
diff --git a/src/Bindings/WLC.hs b/src/Bindings/WLC.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC.hs
@@ -0,0 +1,3 @@
+module Bindings.WLC where
+
+import Bindings.WLC.WLC
diff --git a/src/Bindings/WLC/Defines.hsc b/src/Bindings/WLC/Defines.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC/Defines.hsc
@@ -0,0 +1,8 @@
+#include <bindings.dsl.h>
+
+module Bindings.WLC.Defines where
+#strict_import
+
+import Foreign.C.Types
+
+#synonym_t wlc_handle , CUIntPtr
diff --git a/src/Bindings/WLC/Geometry.hsc b/src/Bindings/WLC/Geometry.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC/Geometry.hsc
@@ -0,0 +1,36 @@
+#include <bindings.dsl.h>
+#include <wlc/geometry.h>
+
+{-|
+Module      : Bindings.WLC.Geometry
+Description : WLC Geometry
+Copyright   : (c) Ashley Towns 2016
+License     : BSD3
+Maintainer  : mail@ashleytowns.id.au
+Stability   : experimental
+Portability : POSIX
+
+Provides bindings to the geometry WLC data types.
+-}
+module Bindings.WLC.Geometry where
+#strict_import
+
+import Foreign.C.Types
+
+-- |Fixed 2D point
+#starttype struct wlc_point
+#field x, CInt
+#field y, CInt
+#stoptype
+
+-- |Fixed 2D size
+#starttype struct wlc_size
+#field w, CUInt
+#field h, CUInt
+#stoptype
+
+-- |Fixed 2D point, size pair
+#starttype struct wlc_geometry
+#field origin, <wlc_point>
+#field size, <wlc_size>
+#stoptype
diff --git a/src/Bindings/WLC/WLC.hsc b/src/Bindings/WLC/WLC.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC/WLC.hsc
@@ -0,0 +1,324 @@
+#include <bindings.dsl.h>
+#include <wlc/wlc.h>
+
+{-|
+Module      : Bindings.WLC.WLC
+Description : Core WLC
+Copyright   : (c) Ashley Towns 2016
+License     : BSD3
+Maintainer  : mail@ashleytowns.id.au
+Stability   : experimental
+Portability : POSIX
+
+Provides bindings to the core WLC API.
+-}
+module Bindings.WLC.WLC where
+#strict_import
+
+import Bindings.WLC.Defines
+import Bindings.WLC.Geometry
+
+#opaque_t wlc_event_source
+#opaque_t xkb_state
+#opaque_t xkb_keymap
+#opaque_t libinput_device
+
+-- |wlc_log(), wlc_vlog();
+#integral_t enum wlc_log_type
+#num WLC_LOG_INFO
+#num WLC_LOG_WARN
+#num WLC_LOG_ERROR
+#num WLC_LOG_WAYLAND
+
+-- |wlc_get_backend_type();
+#integral_t enum wlc_backend_type
+#num WLC_BACKEND_NONE
+#num WLC_BACKEND_DRM
+#num WLC_BACKEND_X11
+
+-- |mask in wlc_event_loop_add_fd();
+#integral_t enum wlc_event_bit
+#num WLC_EVENT_READABLE
+#num WLC_EVENT_WRITABLE
+#num WLC_EVENT_HANGUP
+#num WLC_EVENT_ERROR
+
+-- |wlc_view_get_state();
+#integral_t enum wlc_view_state_bit
+#num WLC_BIT_MAXIMIZED
+#num WLC_BIT_FULLSCREEN
+#num WLC_BIT_RESIZING
+#num WLC_BIT_MOVING
+#num WLC_BIT_ACTIVATED
+
+-- |wlc_view_get_type();
+#integral_t enum wlc_view_type_bit
+-- |Override redirect (x11)
+#num WLC_BIT_OVERRIDE_REDIRECT
+-- |Tooltips, DnD's, menus (x11)
+#num WLC_BIT_UNMANAGED
+-- |Splash screens (x11)
+#num WLC_BIT_SPLASH
+-- |Modal windows (x11)
+#num WLC_BIT_MODAL
+-- |xdg-shell, wl-shell popups
+#num WLC_BIT_POPUP
+
+-- |wlc_view_set_geometry(); Edges in interface interface.view.request.resize function.
+#integral_t enum wlc_resize_edge
+#num WLC_RESIZE_EDGE_NONE
+#num WLC_RESIZE_EDGE_TOP
+#num WLC_RESIZE_EDGE_BOTTOM
+#num WLC_RESIZE_EDGE_LEFT
+#num WLC_RESIZE_EDGE_TOP_LEFT
+#num WLC_RESIZE_EDGE_BOTTOM_LEFT
+#num WLC_RESIZE_EDGE_RIGHT
+#num WLC_RESIZE_EDGE_TOP_RIGHT
+#num WLC_RESIZE_EDGE_BOTTOM_RIGHT
+
+-- |Mods in interface.keyboard.key function.
+#integral_t enum wlc_modifier_bit
+#num WLC_BIT_MOD_SHIFT
+#num WLC_BIT_MOD_CAPS
+#num WLC_BIT_MOD_CTRL
+#num WLC_BIT_MOD_ALT
+#num WLC_BIT_MOD_MOD2
+#num WLC_BIT_MOD_MOD3
+#num WLC_BIT_MOD_LOGO
+#num WLC_BIT_MOD_MOD5
+
+-- |Leds in interface.keyboard.key function.
+#integral_t enum wlc_led_bit
+#num WLC_BIT_LED_NUM
+#num WLC_BIT_LED_CAPS
+#num WLC_BIT_LED_SCROLL
+
+-- |State in interface.keyboard.key function.
+#integral_t enum wlc_key_state
+#num WLC_KEY_STATE_RELEASED
+#num WLC_KEY_STATE_PRESSED
+
+-- |State in interface.pointer.button function.
+#integral_t enum wlc_button_state
+#num WLC_BUTTON_STATE_RELEASED
+#num WLC_BUTTON_STATE_PRESSED
+
+-- |Axis in interface.pointer.scroll function.
+#integral_t enum wlc_scroll_axis_bit
+#num WLC_SCROLL_AXIS_VERTICAL
+#num WLC_SCROLL_AXIS_HORIZONTAL
+
+-- |Type in interface.touch.touch function
+#integral_t enum wlc_touch_type
+#num WLC_TOUCH_DOWN
+#num WLC_TOUCH_UP
+#num WLC_TOUCH_MOTION
+#num WLC_TOUCH_FRAME
+#num WLC_TOUCH_CANCEL
+
+-- |State of keyboard modifiers in various functions.
+#starttype struct wlc_modifiers
+#field leds, CUInt
+#field mods, CUInt
+#stoptype
+
+-- * Callback API
+-- ** Types
+-- *** Output
+#callback_t output_created_cb , <wlc_handle> -> IO Bool
+#callback_t output_destroyed_cb , <wlc_handle> -> IO ()
+#callback_t output_focus_cb , <wlc_handle> -> Bool -> IO ()
+#callback_t output_resolution_cb , <wlc_handle> -> Ptr <wlc_size> -> Ptr <wlc_size> -> IO ()
+#callback_t output_render_pre_cb , <wlc_handle> -> IO ()
+#callback_t output_render_post_cb , <wlc_handle> -> IO ()
+-- *** View
+#callback_t view_created_cb , <wlc_handle> -> IO Bool
+#callback_t view_destroyed_cb , <wlc_handle> -> IO ()
+#callback_t view_focus_cb , <wlc_handle> -> Bool -> IO ()
+#callback_t view_move_to_output_cb , <wlc_handle> -> <wlc_handle> -> <wlc_handle> -> IO ()
+#callback_t view_request_geometry_cb , <wlc_handle> -> Ptr <wlc_geometry> -> IO ()
+#callback_t view_request_state_cb , <wlc_handle> -> <wlc_view_state_bit> -> Bool -> IO ()
+#callback_t view_request_move_cb , <wlc_handle> -> Ptr <wlc_point> -> IO ()
+#callback_t view_request_resize_cb , <wlc_handle> -> CUInt -> Ptr <wlc_point> -> IO ()
+#callback_t view_render_pre_cb , <wlc_handle> -> IO ()
+#callback_t view_render_post_cb , <wlc_handle> -> IO ()
+-- *** Input
+#callback_t keyboard_key_cb , <wlc_handle> -> CUInt -> Ptr <wlc_modifiers> -> CUInt -> <wlc_key_state> -> IO Bool
+#callback_t pointer_button_cb , <wlc_handle> -> CUInt -> Ptr <wlc_modifiers> -> CUInt -> <wlc_button_state> -> Ptr <wlc_point> -> IO Bool
+#callback_t pointer_scroll_cb , <wlc_handle> -> CUInt -> Ptr <wlc_modifiers> -> Int8 -> CDouble -> IO Bool
+#callback_t pointer_motion_cb , <wlc_handle> -> CUInt -> Ptr <wlc_point> -> IO Bool
+#callback_t touch_cb , <wlc_handle> -> CUInt -> Ptr <wlc_modifiers> -> <wlc_touch_type> -> CInt -> Ptr <wlc_point> -> IO Bool
+-- *** Other
+#callback_t compositor_ready_cb , IO ()
+#callback_t compositor_terminate_cb , IO ()
+
+-- ** Functions
+-- *** Output
+-- |Output was created. Return false if you want to destroy the output. (e.g. failed to allocate data related to view)
+#ccall wlc_set_output_created_cb , <output_created_cb> -> IO ()
+-- |Output was destroyed.
+#ccall wlc_set_output_destroyed_cb , <output_destroyed_cb> -> IO ()
+-- |Output got or lost focus.
+#ccall wlc_set_output_focus_cb , <output_focus_cb> -> IO ()
+-- |Output resolution changed.
+#ccall wlc_set_output_resolution_cb , <output_resolution_cb> -> IO ()
+-- |Output pre render hook.
+#ccall wlc_set_output_render_pre_cb , <output_render_pre_cb> -> IO ()
+-- |Output post render hook.
+#ccall wlc_set_output_render_post_cb , <output_render_post_cb> -> IO ()
+-- *** View
+-- |View was created. Return false if you want to destroy the view. (e.g. failed to allocate data related to view)
+#ccall wlc_set_view_created_cb , <view_created_cb> -> IO ()
+-- |View was destroyed.
+#ccall wlc_set_view_destroyed_cb , <view_destroyed_cb> -> IO ()
+-- |View got or lost focus.
+#ccall wlc_set_view_focus_cb , <view_focus_cb> -> IO ()
+-- |View was moved to output.
+#ccall wlc_set_view_move_to_output_cb , <view_move_to_output_cb> -> IO ()
+-- |Request to set given geometry for view. Apply using wlc_view_set_geometry to agree.
+#ccall wlc_set_view_request_geometry_cb , <view_request_geometry_cb> -> IO ()
+-- |Request to disable or enable the given state for view. Apply using wlc_view_set_state to agree.
+#ccall wlc_set_view_request_state_cb , <view_request_state_cb> -> IO ()
+-- |Request to move itself. Start a interactive move to agree.
+#ccall wlc_set_view_request_move_cb , <view_request_move_cb> -> IO ()
+-- |Request to resize itself with the given edges. Start a interactive resize to agree.
+#ccall wlc_set_view_request_resize_cb , <view_request_resize_cb> -> IO ()
+-- |View pre render hook.
+#ccall wlc_set_view_render_pre_cb , <view_render_pre_cb> -> IO ()
+-- |View post render hook.
+#ccall wlc_set_view_render_post_cb , <view_render_post_cb> -> IO ()
+-- *** Input
+-- |Key event was triggered, view handle will be zero if there was no focus. Return true to prevent sending the
+-- event to clients.
+#ccall wlc_set_keyboard_key_cb , <keyboard_key_cb> -> IO ()
+-- |Button event was triggered, view handle will be zero if there was no focus. Return true to prevent sending the
+-- event to clients.
+#ccall wlc_set_pointer_button_cb , <pointer_button_cb> -> IO ()
+-- |Scroll event was triggered, view handle will be zero if there was no focus. Return true to prevent sending the
+-- event to clients.
+#ccall wlc_set_pointer_scroll_cb , <pointer_scroll_cb> -> IO ()
+-- |Motion event was triggered, view handle will be zero if there was no focus. Apply with wlc_pointer_set_position to
+-- agree. Return true to prevent sending the event to clients.
+#ccall wlc_set_pointer_motion_cb , <pointer_motion_cb> -> IO ()
+-- |Touch event was triggered, view handle will be zero if there was no focus. Return true to prevent sending the
+-- event to clients.
+#ccall wlc_set_touch_cb , <touch_cb> -> IO ()
+-- *** Other
+-- |Compositor is ready to accept clients.
+#ccall wlc_set_compositor_ready_cb , <compositor_ready_cb> -> IO ()
+-- |Compositor is about to terminate
+#ccall wlc_set_compositor_terminate_cb , <compositor_terminate_cb> -> IO ()
+
+-- * Core API
+
+-- |Creates a log handler callback
+#callback_t log_handler_cb , <wlc_log_type> -> CString -> IO ()
+
+-- |Set log handler. Can be set before wlc_init.
+#ccall wlc_log_set_handler , <log_handler_cb> -> IO ()
+
+-- |Initialize wlc. Returns false on failure.
+--
+-- Avoid running unverified code before wlc_init as wlc compositor may be run with higher
+-- privileges on non logind systems where compositor binary needs to be suid.
+--
+-- wlc_init's purpose is to initialize and drop privileges as soon as possible.
+--
+-- Callbacks should be set using wlc_set_*_cb functions before calling wlc_init2,
+-- failing to do so will cause any callback the init may trigger to not be called.
+#ccall wlc_init2 , IO Bool
+-- |Terminate wlc.
+#ccall wlc_terminate , IO ()
+-- |Query backend wlc is using.
+#ccall wlc_get_backend_type , IO <wlc_backend_type>
+-- |Exec program.
+#ccall wlc_exec , CString -> Ptr CString -> IO ()
+-- |Run event loop.
+#ccall wlc_run , IO ()
+-- |Link custom data to handle.
+#ccall wlc_handle_set_user_data , <wlc_handle> -> Ptr () -> IO ()
+-- |Get linked custom data from handle.
+#ccall wlc_handle_get_user_data , <wlc_handle> -> IO (Ptr ())
+
+-- * Output API
+
+-- |Get outputs. Returned array is a direct reference, careful when moving and destroying handles.
+#ccall wlc_get_outputs , Ptr CSize -> IO <wlc_handle>
+-- |Get focused output.
+#ccall wlc_get_focused_output , IO <wlc_handle>
+-- |Get output name.
+#ccall wlc_output_get_name , <wlc_handle> -> IO CString
+-- |Get sleep state.
+#ccall wlc_output_get_sleep , <wlc_handle> -> IO Bool
+-- |Wake up / sleep.
+#ccall wlc_output_set_sleep , <wlc_handle> -> Bool -> IO ()
+-- |Get resolution.
+#ccall wlc_output_get_resolution , <wlc_handle> -> IO (Ptr <wlc_size>)
+-- |Set resolution.
+#ccall wlc_output_set_resolution , <wlc_handle> -> Ptr <wlc_size> -> IO ()
+-- |Get current visibility bitmask.
+#ccall wlc_output_get_mask , <wlc_handle> -> IO CUInt
+-- |Set visibility bitmask.
+#ccall wlc_output_set_mask , <wlc_handle> -> CUInt -> IO ()
+-- |Get views in stack order. Returned array is a direct reference, careful when moving and destroying handles.
+#ccall wlc_output_get_views , <wlc_handle> -> Ptr CSize -> IO (Ptr wlc_handle)
+-- |Focus output. Pass zero for no focus.
+#ccall wlc_output_focus , <wlc_handle> -> IO ()
+
+-- * View API
+-- |Focus view. Pass zero for no focus.
+#ccall wlc_view_focus , <wlc_handle> -> IO ()
+-- |Close view.
+#ccall wlc_view_close , <wlc_handle> -> IO ()
+-- |Get current output.
+#ccall wlc_view_get_output , <wlc_handle> -> IO <wlc_handle>
+-- |Set output. Alternatively you can wlc_output_set_views.
+#ccall wlc_view_set_output , <wlc_handle> -> <wlc_handle> -> IO ()
+-- |Send behind everything.
+#ccall wlc_view_send_to_back , <wlc_handle> -> IO ()
+-- |Send below another view.
+#ccall wlc_view_send_below , <wlc_handle> -> <wlc_handle> -> IO ()
+-- |Send above another view.
+#ccall wlc_view_bring_above , <wlc_handle> -> <wlc_handle> -> IO ()
+-- |Bring to front of everything.
+#ccall wlc_view_bring_to_front , <wlc_handle> -> IO ()
+-- |Get current visibility bitmask.
+#ccall wlc_view_get_mask , <wlc_handle> -> IO CUInt
+-- |Set visibility bitmask.
+#ccall wlc_view_set_mask , <wlc_handle> -> CUInt -> IO ()
+-- |Get current geometry. (what client sees)
+#ccall wlc_view_get_geometry , <wlc_handle> -> IO (Ptr <wlc_geometry>)
+-- |Get visible geometry. (what wlc displays)
+#ccall wlc_view_get_visible_geometry , <wlc_handle> -> Ptr <wlc_geometry> -> IO ()
+-- |Set geometry. Set edges if the geometry change is caused by interactive resize.
+#ccall wlc_view_set_geometry , <wlc_handle> -> CUInt -> Ptr <wlc_geometry> -> IO ()
+-- |Get type bitfield.
+#ccall wlc_view_get_type , <wlc_handle> -> IO CUInt
+-- |Set type bit. Toggle indicates whether it is set or not.
+#ccall wlc_view_set_type , <wlc_handle> -> <wlc_view_type_bit> -> Bool -> IO ()
+-- |Get current state bitfield.
+#ccall wlc_view_get_state , <wlc_handle> -> IO CUInt
+-- |Set state bit. Toggle indicates whether it is set or not.
+#ccall wlc_view_set_state , <wlc_handle> -> <wlc_view_state_bit> -> Bool -> IO ()
+-- |Get parent view.
+#ccall wlc_view_get_parent , <wlc_handle> -> IO <wlc_handle>
+-- |Set parent view.
+#ccall wlc_view_set_parent , <wlc_handle> -> <wlc_handle> -> IO ()
+-- |Get title.
+#ccall wlc_view_get_title , <wlc_handle> -> IO CString
+-- |Get class. (shell-surface only)
+#ccall wlc_view_get_class , <wlc_handle> -> IO CString
+-- |Get app id. (xdg-surface only)
+#ccall wlc_view_get_app_id , <wlc_handle> -> IO CString
+
+-- * Input API
+-- |Get currently held keys.
+#ccall wlc_keyboard_get_current_keys , Ptr CSize -> IO (Ptr CUInt)
+-- |Utility function to convert raw keycode to keysym. Passed modifiers may transform the key.
+#ccall wlc_keyboard_get_keysym_for_key , CUInt -> Ptr <wlc_modifiers> -> IO CUInt
+-- |Utility function to convert raw keycode to Unicode/UTF-32 codepoint. Passed modifiers may transform the key.
+#ccall wlc_keyboard_get_utf32_for_key , CUInt -> Ptr <wlc_modifiers> -> IO CUInt
+-- |Get current pointer position.
+#ccall wlc_pointer_get_position , Ptr <wlc_point> -> IO ()
+-- |Set current pointer position.
+#ccall wlc_pointer_set_position , Ptr <wlc_point> -> IO ()
diff --git a/src/Bindings/WLC/WLCRender.hsc b/src/Bindings/WLC/WLCRender.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC/WLCRender.hsc
@@ -0,0 +1,67 @@
+#include <bindings.dsl.h>
+#include <wlc/wlc-render.h>
+
+{-|
+Module      : Bindings.WLC.WLCRender
+Description : WLC Render
+Copyright   : (c) Ashley Towns 2016
+License     : BSD3
+Maintainer  : mail@ashleytowns.id.au
+Stability   : experimental
+Portability : POSIX
+
+The functions in this file provide some basic rendering capabilities.
+*_render(), *_read(), *_write() functions should only be called during post/pre render callbacks.
+wlc_output_schedule_render() is exception and may be used to force wlc to render new frame (causing callbacks to trigger).
+
+For more advanced drawing you should directly use GLES2.
+This is not documented as it's currently relying on the implementation details of wlc.
+-}
+module Bindings.WLC.WLCRender where
+#strict_import
+
+import Bindings.WLC.Defines
+import Bindings.WLC.Geometry
+import Bindings.WLC.WLCWayland
+
+-- |Allowed pixel formats.
+#integral_t enum wlc_pixel_format
+#num WLC_RGBA8888
+
+-- |Write pixel data with the specific format to output's framebuffer.
+-- If the geometry is out of bounds, it will be automaticall clamped.
+#ccall wlc_pixels_write , <wlc_pixel_format> -> Ptr <wlc_geometry> -> Ptr () -> IO ()
+
+-- |Read pixel data from output's framebuffer.
+-- If the geometry is out of bounds, it will be automatically clamped.
+-- Potentially clamped geometry will be stored in out_geometry, to indicate width / height of the returned data.
+#ccall wlc_pixels_read , <wlc_pixel_format> -> Ptr <wlc_geometry> -> Ptr <wlc_geometry> -> Ptr () -> IO ()
+
+-- |Renders surface.
+#ccall wlc_surface_render , <wlc_resource> -> Ptr <wlc_geometry> -> IO ()
+
+-- |Schedules output for rendering next frame. If output was already scheduled this is no-op,
+-- if output is currently rendering, it will render immediately after.
+#ccall wlc_output_schedule_render , <wlc_handle> -> IO ()
+
+-- |Adds frame callbacks of the given surface for the next output frame.
+-- It applies recursively to all subsurfaces.
+-- Useful when the compositor creates custom animations which require disabling internal rendering,
+-- but still need to update the surface textures (for ex. video players).
+#ccall wlc_surface_flush_frame_callbacks , <wlc_resource> -> IO ()
+
+-- |Enabled renderers
+#integral_t enum wlc_renderer
+#num WLC_RENDERER_GLES2
+#num WLC_NO_RENDERER
+
+-- |Returns currently active renderer on the given output
+#ccall wlc_output_get_renderer , <wlc_handle> -> IO <wlc_renderer>
+
+#integral_t enum wlc_surface_format
+#num SURFACE_RGB
+#num SURFACE_RGBA
+#num SURFACE_EGL
+#num SURFACE_Y_UV
+#num SURFACE_Y_U_V
+#num SURFACE_Y_XUXV
diff --git a/src/Bindings/WLC/WLCWayland.hsc b/src/Bindings/WLC/WLCWayland.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/WLC/WLCWayland.hsc
@@ -0,0 +1,53 @@
+#include <bindings.dsl.h>
+#include <wlc/wlc-render.h>
+
+{-|
+Module      : Bindings.WLC.WLCWayland
+Description : WLC Wayland
+Copyright   : (c) Ashley Towns 2016
+License     : BSD3
+Maintainer  : mail@ashleytowns.id.au
+Stability   : experimental
+Portability : POSIX
+-}
+module Bindings.WLC.WLCWayland where
+#strict_import
+
+import Bindings.WLC.Defines
+import Bindings.WLC.Geometry
+
+#synonym_t wlc_resource , CUIntPtr
+
+#opaque_t wl_resource
+#opaque_t wl_display
+
+#opaque_t wl_client
+#opaque_t wl_interface
+
+-- |Returns Wayland display.
+#ccall wlc_get_wl_display , IO (Ptr <wl_display>)
+-- |Returns view handle from wl_surface resource.
+#ccall wlc_handle_from_wl_surface_resource , Ptr <wl_resource> -> IO <wlc_handle>
+-- |Returns output handle from wl_output resource.
+#ccall wlc_handle_from_wl_output_resource , Ptr <wl_resource> -> IO <wlc_handle>
+-- |Returns internal wlc surface from wl_surface resource.
+#ccall wlc_resource_from_wl_surface_resource , Ptr <wl_resource> -> IO <wlc_resource>
+-- |Get surface size.
+#ccall wlc_surface_get_size , <wlc_resource> -> IO (Ptr <wlc_size>)
+-- |Return wl_surface resource from internal wlc surface.
+#ccall wlc_surface_get_wl_resource , <wlc_resource> -> IO (Ptr <wl_resource>)
+-- |Turns wl_surface into a wlc view. Returns 0 on failure. This will also trigger view.created callback as any view would.
+-- For the extra arguments see details of wl_resource_create and wl_resource_set_implementation.
+-- The extra arguments may be set NULL, if you are not implementing Wayland interface for the surface role.
+#ccall wlc_view_from_surface , <wlc_resource> -> Ptr <wl_client> -> Ptr <wl_interface> -> Ptr () -> CUInt -> CUInt -> Ptr () -> IO <wlc_handle>
+-- |Returns internal wlc surface from view handle
+#ccall wlc_view_get_surface , <wlc_handle> -> IO <wlc_resource>
+-- |Returns a list of the subsurfaces of the given surface
+#ccall wlc_surface_get_subsurfaces , <wlc_resource> -> Ptr CSize -> IO (Ptr <wlc_resource>)
+-- |Returns the size of a subsurface and its position relative to parent
+#ccall wlc_get_subsurface_geometry , <wlc_resource> -> Ptr <wlc_geometry> -> IO ()
+-- |Returns wl_client from view handle
+#ccall wlc_view_get_wl_client , <wlc_handle> -> IO (Ptr <wl_client>)
+-- |Returns surface role resource from view handle. Return value will be NULL if the view was not assigned role
+-- or created with wlc_view_create_from_surface().
+#ccall wlc_view_get_role , <wlc_handle> -> IO (Ptr <wl_resource>)
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
