diff --git a/Graphics/Imlib.hs b/Graphics/Imlib.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Imlib.hs
@@ -0,0 +1,1197 @@
+{-# OPTIONS -fffi -fglasgow-exts #-}
+
+{- 
+* Haskell Binding for Imlib 2
+* Copyright (c) 2004-2007, Cale Gibbard
+* 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 Cale Gibbard nor the
+*       names of his contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY CALE GIBBARD ``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 CALE GIBBARD 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.
+
+-}
+
+{-
+New exported calls (not in Imlib 2):
+withImageBits
+withImage
+imageWithData
+colorToBits
+createImageUsingList
+createImageUsingArray
+-}
+
+{-
+TODO: Convenience wrappers for reading in proper Haskell arrays/lists
+      in the case of:
+      image_get_data, image_get_data_for_reading_only,
+      image_put_back_data and image_with_data
+
+      This was really written for the most part back in 2004, and only
+      lightly touched since then. It could be better integrated with
+      the standard bindings to X now, and there are various design issues
+      which might be considered. For example, Imlib is very stateful
+      and it might be nice to try to capture that state in a particular
+      monad, though there might be some tricky module-loading issues with
+      that.
+-}
+
+{- -- List of what is not imported --
+
+ -- This list contains anything that interfaces with X (i.e. uses Display/Visual/Drawable/Colormap/Pixmap)
+ 
+ -- Apart from that, the only thing that is in this list is imlib_apply_filter (which is rather unfortunate,
+ -- since it's a cool feature). It uses va_args, so perhaps some Template Haskell is in order.
+
+int imlib_get_visual_depth(Display *display, Visual *visual);
+Visual *imlib_get_best_visual(Display *display, int screen, int *depth_return);
+
+void imlib_context_set_display(Display *display);
+void imlib_context_set_visual(Visual *visual);
+void imlib_context_set_colormap(Colormap colormap);
+void imlib_context_set_drawable(Drawable drawable);
+void imlib_context_set_mask(Pixmap mask);
+
+Display *imlib_context_get_display(void);
+Visual *imlib_context_get_visual(void);
+Colormap imlib_context_get_colormap(void);
+Drawable imlib_context_get_drawable(void);
+Pixmap imlib_context_get_mask(void);
+
+void imlib_render_pixmaps_for_whole_image(Pixmap *pixmap_return, Pixmap *mask_return);
+void imlib_render_pixmaps_for_whole_image_at_size(Pixmap *pixmap_return, Pixmap *mask_return, int width, int height);
+void imlib_free_pixmap_and_mask(Pixmap pixmap);
+void imlib_render_image_on_drawable(int x, int y);
+void imlib_render_image_on_drawable_at_size(int x, int y, int width, int height);
+void imlib_render_image_part_on_drawable_at_size(int source_x, int source_y, int source_width, int source_height, int x, int y, int width, int height);
+
+Imlib_Image imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width, int height, char need_to_grab_x);
+Imlib_Image imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x, int source_y, int source_width, int source_height, int destination_width, int destination_height, char need_to_grab_x, char get_mask_from_shape);
+char imlib_copy_drawable_to_image(Pixmap mask, int x, int y, int width, int height, int destination_x, int destination_y, char need_to_grab_x);
+
+void imlib_render_image_updates_on_drawable(Imlib_updates updates, int x, int y);
+
+void imlib_render_image_on_drawable_skewed(int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int h_angle_x, int h_angle_y, int v_angle_x, int v_angle_y);
+void imlib_render_image_on_drawable_at_angle(int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int angle_x, int angle_y);
+
+void imlib_apply_filter( char *script, ... );
+-}
+
+module Graphics.Imlib (
+    ImlibProgressFunction, ImlibDataDestructorFunction, 
+    ImlibTTFEncoding (..), ImlibLoadError (..), ImlibTextDirection (..),
+    ImlibOperation (..), ImlibColor (..), ImlibBorder (..), ImlibPolygon, 
+    ImlibFilter, ImlibColorRange, ImlibFont, ImlibUpdates, 
+    ImlibColorModifier, ImlibImage, ImlibContext,
+    contextSetDitherMask, contextSetAntiAlias, contextSetDither, 
+    contextSetBlend, contextSetColorModifier, contextSetOperation,
+    contextSetFont, contextSetDirection, contextSetAngle, contextSetColor, 
+    contextSetColorCmya, contextSetColorHsva, contextSetColorHlsa, 
+    contextSetColorRange, contextSetProgressFunction, 
+    contextSetProgressGranularity, contextSetFilter, contextSetImage, 
+    contextGetDitherMask, contextGetAntiAlias, contextGetDither, 
+    contextGetBlend, contextGetColorModifier, contextGetOperation, 
+    contextGetFont, contextGetAngle, contextGetDirection, contextGetColor, 
+    contextGetColorCmya, contextGetColorHsva, contextGetColorHlsa, 
+    contextGetImlibColor, contextGetColorRange, contextGetProgressFunction,
+    contextGetProgressGranularity, contextGetImage, contextGetFilter, 
+    getCacheSize, setCacheSize, getColorUsage, setColorUsage, 
+    flushLoaders, loadImage, loadImageImmediately, loadImageWithoutCache,
+    loadImageImmediatelyWithoutCache, loadImageWithErrorReturn, freeImage,
+    freeImageAndDecache, imageGetWidth, imageGetHeight, imageGetFilename, 
+    imageGetData, imageGetDataForReadingOnly, imagePutBackData, 
+    imageWithData, imageHasAlpha, imageSetChangesOnDisk, imageGetBorder,
+    imageSetBorder, imageSetFormat, imageSetIrrelevantFormat, 
+    imageSetIrrelevantBorder, imageSetIrrelevantAlpha, imageFormat, 
+    imageSetHasAlpha, blendImageOntoImage, createImage, 
+    createImageUsingData, createImageUsingCopiedData, cloneImage,
+    createCroppedImage, createCroppedScaledImage, updatesClone, 
+    updateAppendRect, updatesMerge, updatesMergeForRendering,
+    updatesFree, updatesGetNext, updatesGetCoordinates, 
+    updatesSetCoordinates, updatesInit, updatesAppendUpdates, 
+    imageFlipHorizontal, imageFlipVertical, imageFlipDiagonal, 
+    imageOrientate, imageBlur, imageSharpen, imageTileHorizontal, 
+    imageTileVertical, imageTile, loadFont, freeFont, textDraw, 
+    textDrawWithReturnMetrics, getTextSize, getTextAdvance, getTextInset,
+    addPathToFontPath, removePathFromFontPath, listFontPath, 
+    textGetIndexAndLocation, textGetLocationAtIndex, listFonts,
+    getFontCacheSize, setFontCacheSize, flushFontCache, getFontAscent, 
+    getFontDescent, getMaximumFontAscent, getMaximumFontDescent,
+    createColorModifier, freeColorModifier, modifyColorModifierGamma, 
+    modifyColorModifierBrightness, modifyColorModifierContrast,
+    setColorModifierTables, getColorModifierTables, resetColorModifier, 
+    applyColorModifier, applyColorModifierToRectangle, imageDrawLine, 
+    imageDrawRectangle, imageFillRectangle, imageCopyAlphaToImage, 
+    imageCopyAlphaRectangleToImage, imageScrollRect, imageCopyRect, 
+    createColorRange, freeColorRange, addColorToColorRange, 
+    imageFillColorRangeRectangle, imageFillHsvaColorRangeRectangle, 
+    imageQueryPixel, imageQueryPixelCmya, imageQueryPixelHsva, 
+    imageQueryPixelHlsa, imageAttachDataValue, imageGetAttachedData, 
+    imageGetAttachedValue, imageRemoveAttachedDataValue, 
+    imageRemoveAndFreeAttachedDataValue, saveImage, 
+    saveImageWithErrorReturn, createRotatedImage, 
+    blendImageOntoImageAtAngle, blendImageOntoImageSkewed, 
+    contextSetCliprect, {-clipLine,-} polygonNew, polygonFree, 
+    polygonAddPoint, imageDrawPolygon, imageFillPolygon, polygonGetBounds, 
+    polygonContainsPoint, imageDrawEllipse, imageFillEllipse, imageFilter, 
+    createFilter, freeFilter, filterSet, filterSetAlpha, filterSetRed, 
+    filterSetGreen, filterSetBlue, filterConstants, filterDivisors,
+    createImageUsingArray, withImageBits, withImage
+)
+where
+
+import Foreign
+import Foreign.C
+import Data.Bits
+import Data.Array
+import Control.Monad
+
+{- Types from the Imlib 2 header
+typedef void *ImlibContext;
+typedef void *ImlibImage;
+typedef void *ImlibColorModifier;
+typedef void *ImlibUpdates;
+typedef void *ImlibFont;
+typedef void *ImlibColorRange;
+typedef void *ImlibFilter;
+typedef struct ImlibBorder ImlibBorder;
+typedef struct ImlibColor ImlibColor;
+typedef void *ImlibPolygon;
+-}
+
+----- Utility Calls
+
+nmalloc :: Storable a => Int -> IO [Ptr a]
+nmalloc n = replicateM n malloc
+
+nmallocArray :: Storable a => Int -> Int -> IO [Ptr a]
+nmallocArray n m = replicateM n (mallocArray m)
+
+-----
+
+newtype ImlibContext = ImlibContext (Ptr ImlibContext)
+newtype ImlibImage = ImlibImage (Ptr ImlibImage)
+newtype ImlibColorModifier = ImlibColorModifier (Ptr ImlibColorModifier)
+newtype ImlibUpdates = ImlibUpdates (Ptr ImlibUpdates)
+newtype ImlibFont = ImlibFont (Ptr ImlibFont)
+newtype ImlibColorRange = ImlibColorRange (Ptr ImlibColorRange)
+newtype ImlibFilter = ImlibFilter (Ptr ImlibFilter)
+newtype ImlibPolygon = ImlibPolygon (Ptr ImlibPolygon)
+
+data ImlibBorder = ImlibBorder Int Int Int Int deriving (Show, Eq) -- left, right, top, bottom
+instance Storable ImlibBorder where
+    sizeOf x = 16 
+    alignment x = 4
+    peek p = do
+        [a,b,c,d] <- peekArray 4 (castPtr p)
+        return (ImlibBorder a b c d)
+        where
+    poke p (ImlibBorder a b c d) = do
+        pokeArray (castPtr p) [a,b,c,d]
+
+data ImlibColor = ImlibColor Word32 Word32 Word32 Word32 deriving (Show, Eq) -- alpha, red, green, blue
+instance Storable ImlibColor where
+    sizeOf x = 16
+    alignment x = 4
+    peek p = do
+        [a,b,c,d] <- peekArray 4 (castPtr p)
+        return (ImlibColor a b c d)
+        where
+    poke p (ImlibColor a b c d) = do
+        pokeArray (castPtr p) [a,b,c,d]
+
+data ImlibOperation = ImlibOpCopy     -- 0
+                    | ImlibOpAdd      -- 1
+                    | ImlibOpSubtract -- 2
+                    | ImlibOpReshade  -- 3
+    deriving (Enum, Show, Eq)
+                     
+data ImlibTextDirection = ImlibTextToRight -- 0
+                        | ImlibTextToLeft  -- 1
+                        | ImlibTextToDown  -- 2
+                        | ImlibTextToUp    -- 3
+                        | ImlibTextToAngle -- 4
+    deriving (Enum, Show, Eq)
+                          
+data ImlibLoadError = ImlibLoadErrorNone                           -- 0
+                    | ImlibLoadErrorFileDoesNotExist               -- 1
+                    | ImlibLoadErrorFileIsDirectory                -- 2
+                    | ImlibLoadErrorPermissionDeniedToRead         -- 3
+                    | ImlibLoadErrorNoLoaderForFileFormat          -- 4
+                    | ImlibLoadErrorPathTooLong                    -- 5
+                    | ImlibLoadErrorPathComponentNonExistant       -- 6
+                    | ImlibLoadErrorPathComponentNotDirectory      -- 7
+                    | ImlibLoadErrorPathPointsOutsideAddressSpace  -- 8
+                    | ImlibLoadErrorTooManySymbolicLinks           -- 9
+                    | ImlibLoadErrorOutOfMemory                    -- 10
+                    | ImlibLoadErrorOutOfFileDescriptors           -- 11
+                    | ImlibLoadErrorPermissionDeniedToWrite        -- 12
+                    | ImlibLoadErrorOutOfDiskSpace                 -- 13
+                    | ImlibLoadErrorUnknown                        -- 14
+    deriving (Show, Enum, Eq)
+
+data ImlibTTFEncoding = ImlibTTFEncodingISO88591 -- 0
+                      | ImlibTTFEncodingISO88592 -- 1
+                      | ImlibTTFEncodingISO88593 -- 2
+                      | ImlibTTFEncodingISO88594 -- 3
+                      | ImlibTTFEncodingISO88595 -- 4
+    deriving (Enum, Show, Eq)
+
+type ImlibProgressFunction = ImlibImage -- image
+                            -> Word8    -- percent
+                            -> Int      -- update x
+                            -> Int      -- update y
+                            -> Int      -- update w
+                            -> Int      -- update h
+                            -> IO Int   -- return value (not sure what this means)
+foreign import ccall "wrapper" mkProgressFunction :: ImlibProgressFunction -> IO (FunPtr ImlibProgressFunction)
+
+colorToBits :: ImlibColor -> Word32
+colorToBits (ImlibColor a r g b) = fromIntegral (b + (g `shift` 8) + (r `shift` 16) + (a `shift` 24))
+
+colorFromBits :: Word32 -> ImlibColor
+colorFromBits n = ImlibColor a r g b
+    where
+        b = fromIntegral $ n                 `mod` 256
+        g = fromIntegral $ (n `shift` (-8))  `mod` 256
+        r = fromIntegral $ (n `shift` (-16)) `mod` 256
+        a = fromIntegral $ (n `shift` (-24)) `mod` 256
+
+--typedef void (*ImlibDataDestructorFunction) (ImlibImage im, void *data);
+type ImlibDataDestructorFunction = ImlibImage -> Ptr () -> IO ()
+foreign import ccall "wrapper" mkDestructorFunction :: ImlibDataDestructorFunction -> IO (FunPtr ImlibDataDestructorFunction)
+
+--void imlib_context_set_dither_mask(char dither_mask);
+foreign import ccall "static Imlib2.h imlib_context_set_dither_mask" imlibContextSetDitherMask :: Bool -> IO ()
+contextSetDitherMask = imlibContextSetDitherMask
+
+--void imlib_context_set_anti_alias(char anti_alias);
+foreign import ccall "static Imlib2.h imlib_context_set_anti_alias" imlibContextSetAntiAlias :: Bool -> IO ()
+contextSetAntiAlias = imlibContextSetAntiAlias
+
+--void imlib_context_set_dither(char dither);
+foreign import ccall "static Imlib2.h imlib_context_set_dither" imlibContextSetDither :: Bool -> IO ()
+contextSetDither = imlibContextSetDither
+
+--void imlib_context_set_blend(char blend);
+foreign import ccall "static Imlib2.h imlib_context_set_blend" imlibContextSetBlend :: Bool -> IO ()
+contextSetBlend = imlibContextSetBlend
+
+--void imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier);
+foreign import ccall "static Imlib2.h imlib_context_set_color_modifier" imlibContextSetColorModifier :: ImlibColorModifier -> IO ()
+contextSetColorModifier = imlibContextSetColorModifier
+
+--void imlib_context_set_operation(Imlib_Operation operation);
+foreign import ccall "static Imlib2.h imlib_context_set_operation" imlibContextSetOperation :: Int -> IO ()
+contextSetOperation :: ImlibOperation -> IO ()
+contextSetOperation op = imlibContextSetOperation (fromEnum op)
+
+--void imlib_context_set_font(Imlib_Font font);
+foreign import ccall "static Imlib2.h imlib_context_set_font" imlibContextSetFont :: ImlibFont -> IO ()
+contextSetFont = imlibContextSetFont
+
+--void imlib_context_set_direction(Imlib_Text_Direction direction);
+foreign import ccall "static Imlib2.h imlib_context_set_direction" imlibContextSetDirection :: Int -> IO ()
+contextSetDirection :: ImlibTextDirection -> IO ()
+contextSetDirection dir = imlibContextSetDirection (fromEnum dir)
+
+--void imlib_context_set_angle(double angle);
+foreign import ccall "static Imlib2.h imlib_context_set_angle" imlibContextSetAngle :: Double -> IO ()
+contextSetAngle = imlibContextSetAngle
+
+--void imlib_context_set_color(int red, int green, int blue, int alpha);
+foreign import ccall "static Imlib2.h imlib_context_set_color" imlibContextSetColor :: Int -> Int -> Int -> Int -> IO ()
+contextSetColor = imlibContextSetColor
+
+--void imlib_context_set_color_cmya(int cyan, magenta, int yellow, int alpha);
+foreign import ccall "static Imlib2.h imlib_context_set_color_cmya" imlibContextSetColorCmya :: Int -> Int -> Int -> Int -> IO ()
+contextSetColorCmya = imlibContextSetColorCmya
+
+--void imlib_context_set_color_hsva(float hue, float saturation, float value, int alpha);
+foreign import ccall "static Imlib2.h imlib_context_set_color_hsva" imlibContextSetColorHsva :: Int -> Int -> Int -> Int -> IO ()
+contextSetColorHsva = imlibContextSetColorHsva
+
+--void imlib_context_set_color_hlsa(float hue, float lightness, float saturation, int alpha);
+foreign import ccall "static Imlib2.h imlib_context_set_color_hlsa" imlibContextSetColorHlsa :: Int -> Int -> Int -> Int -> IO ()
+contextSetColorHlsa = imlibContextSetColorHlsa
+
+--void imlib_context_set_color_range(Imlib_Color_Range color_range);
+foreign import ccall "static Imlib2.h imlib_context_set_color_range" imlibContextSetColorRange :: ImlibColorRange -> IO ()
+contextSetColorRange = imlibContextSetColorRange
+
+--void imlib_context_set_progress_function(Imlib_Progress_Function progress_function);
+foreign import ccall "static Imlib2.h imlib_context_set_progress_function" imlibContextSetProgressFunction :: FunPtr(ImlibProgressFunction) -> IO ()
+contextSetProgressFunction f = do
+    fn <- mkProgressFunction f
+    imlibContextSetProgressFunction fn
+
+--void imlib_context_set_progress_granularity(char progress_granularity);
+foreign import ccall "static Imlib2.h imlib_context_set_progress_granularity" imlibContextSetProgressGranularity :: Word8 -> IO ()
+contextSetProgressGranularity = imlibContextSetProgressGranularity
+
+--void imlib_context_set_filter(Imlib_Filter filter);
+foreign import ccall "static Imlib2.h imlib_context_set_filter" imlibContextSetFilter :: ImlibFilter -> IO ()
+contextSetFilter = imlibContextSetFilter
+
+-- void imlib_context_set_image(Imlib_Image image);
+foreign import ccall "static Imlib2.h imlib_context_set_image" imlibContextSetImage :: ImlibImage -> IO ()
+contextSetImage = imlibContextSetImage
+
+-- char imlib_context_get_dither_mask(void);
+foreign import ccall "static Imlib2.h imlib_context_get_dither_mask" imlibContextGetDitherMask :: IO Bool 
+contextGetDitherMask = imlibContextGetDitherMask
+
+-- char imlib_context_get_anti_alias(void);
+foreign import ccall "static Imlib2.h imlib_context_get_anti_alias" imlibContextGetAntiAlias :: IO Bool 
+contextGetAntiAlias = imlibContextGetAntiAlias
+
+-- char imlib_context_get_dither(void);
+foreign import ccall "static Imlib2.h imlib_context_get_dither" imlibContextGetDither :: IO Bool 
+contextGetDither = imlibContextGetDither
+
+-- char imlib_context_get_blend(void);
+foreign import ccall "static Imlib2.h imlib_context_get_blend" imlibContextGetBlend :: IO Bool 
+contextGetBlend = imlibContextGetBlend
+
+-- Imlib_Color_Modifier imlib_context_get_color_modifier(void);
+foreign import ccall "static Imlib2.h imlib_context_get_color_modifier" imlibContextGetColorModifier :: IO ImlibColorModifier
+contextGetColorModifier = imlibContextGetColorModifier
+
+-- Imlib_Operation imlib_context_get_operation(void);
+foreign import ccall "static Imlib2.h imlib_context_get_operation" imlibContextGetOperation :: IO Int 
+contextGetOperation :: IO ImlibOperation 
+contextGetOperation = do
+    i <- imlibContextGetOperation
+    return (toEnum i)
+
+-- Imlib_Font imlib_context_get_font(void);
+foreign import ccall "static Imlib2.h imlib_context_get_font" imlibContextGetFont :: IO ImlibFont
+contextGetFont = imlibContextGetFont
+
+-- double imlib_context_get_angle(void);
+foreign import ccall "static Imlib2.h imlib_context_get_angle" imlibContextGetAngle :: IO Double 
+contextGetAngle = imlibContextGetAngle
+
+-- Imlib_Text_Direction imlib_context_get_direction(void);
+foreign import ccall "static Imlib2.h imlib_context_get_direction" imlibContextGetDirection :: IO Int 
+contextGetDirection :: IO ImlibTextDirection
+contextGetDirection = do
+    d <- imlibContextGetDirection
+    return (toEnum d)
+
+-- void imlib_context_get_color(int *red, int *green, int *blue, int *alpha);
+foreign import ccall "static Imlib2.h imlib_context_get_color" imlibContextGetColor :: Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+contextGetColor :: IO (Int, Int, Int, Int)
+contextGetColor = do
+    [r,g,b,a] <- nmalloc 4
+    imlibContextGetColor r g b a
+    [rr,gg,bb,aa] <- mapM peek [r,g,b,a]
+    mapM free [r,g,b,a]
+    return (rr,gg,bb,aa) 
+
+-- void imlib_context_get_color_cmya(int *cyan, int *magenta, int *yellow, int *alpha);
+foreign import ccall "static Imlib2.h imlib_context_get_color_cmya" imlibContextGetColorCmya :: Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+contextGetColorCmya :: IO (Int, Int, Int, Int)
+contextGetColorCmya = do
+    [c,m,y,a] <- nmalloc 4
+    imlibContextGetColorCmya c m y a
+    [cc,mm,yy,aa] <- mapM peek [c,m,y,a]
+    mapM free [c,m,y,a]
+    return (cc,mm,yy,aa) 
+
+-- void imlib_context_get_color_hsva(float *hue, float *saturation, float *value, int *alpha);
+foreign import ccall "static Imlib2.h imlib_context_get_color_hsva" imlibContextGetColorHsva :: Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+contextGetColorHsva :: IO (Int, Int, Int, Int)
+contextGetColorHsva = do
+    [h,s,v,a] <- nmalloc 4
+    imlibContextGetColorHsva h s v a
+    [hh,ss,vv,aa] <- mapM peek [h,s,v,a]
+    mapM free [h,s,v,a]
+    return (hh,ss,vv,aa) 
+
+-- void imlib_context_get_color_hlsa(float *hue, float * lightness, float *saturation, int *alpha);
+foreign import ccall "static Imlib2.h imlib_context_get_color_hlsa" imlibContextGetColorHlsa :: Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+contextGetColorHlsa :: IO (Int, Int, Int, Int)
+contextGetColorHlsa = do
+    [h,l,s,a] <- nmalloc 4
+    imlibContextGetColorHlsa h l s a
+    [hh,ll,ss,aa] <- mapM peek [h,l,s,a]
+    mapM free [h,l,s,a]
+    return (hh,ll,ss,aa) 
+
+-- Imlib_Color *imlib_context_get_imlib_color(void);
+foreign import ccall "static Imlib2.h imlib_context_get_imlib_color" imlibContextGetImlibColor :: IO (Ptr ImlibColor)
+contextGetImlibColor :: IO ImlibColor
+contextGetImlibColor = do
+    c <- imlibContextGetImlibColor
+    cc <- peek c
+    free c
+    return cc
+
+-- Imlib_Color_Range imlib_context_get_color_range(void);
+foreign import ccall "static Imlib2.h imlib_context_get_color_range" imlibContextGetColorRange :: IO ImlibColorRange
+contextGetColorRange = imlibContextGetColorRange
+
+-- Imlib_Progress_Function imlib_context_get_progress_function(void);
+foreign import ccall "static Imlib2.h imlib_context_get_progress_function" imlibContextGetProgressFunction :: IO (FunPtr ImlibProgressFunction)
+contextGetProgressFunction = imlibContextGetProgressFunction 
+    
+-- char imlib_context_get_progress_granularity(void);
+foreign import ccall "static Imlib2.h imlib_context_get_progress_granularity" imlibContextGetProgressGranularity :: IO Word8 
+contextGetProgressGranularity = imlibContextGetProgressGranularity
+
+-- Imlib_Image imlib_context_get_image(void);
+foreign import ccall "static Imlib2.h imlib_context_get_image" imlibContextGetImage :: IO ImlibImage
+contextGetImage = imlibContextGetImage
+
+-- Imlib_Filter imlib_context_get_filter(void);
+foreign import ccall "static Imlib2.h imlib_context_get_filter" imlibContextGetFilter :: IO ImlibFilter
+contextGetFilter = imlibContextGetFilter
+
+-- int imlib_get_cache_size(void);
+foreign import ccall "static Imlib2.h imlib_get_cache_size" imlibGetCacheSize :: IO Int
+getCacheSize = imlibGetCacheSize
+
+-- void imlib_set_cache_size(int bytes);
+foreign import ccall "static Imlib2.h imlib_set_cache_size" imlibSetCacheSize :: Int -> IO ()
+setCacheSize = imlibSetCacheSize
+
+-- int imlib_get_color_usage(void);
+foreign import ccall "static Imlib2.h imlib_get_color_usage" imlibGetColorUsage :: IO Int
+getColorUsage = imlibGetColorUsage
+
+-- void imlib_set_color_usage(int max);
+foreign import ccall "static Imlib2.h imlib_set_color_usage" imlibSetColorUsage :: Int -> IO ()
+setColorUsage = imlibSetColorUsage
+
+-- void imlib_flush_loaders(void);
+foreign import ccall "static Imlib2.h imlib_flush_loaders" imlibFlushLoaders :: IO ()
+flushLoaders = imlibFlushLoaders
+
+-- Imlib_Image imlib_load_image(const char *file);
+foreign import ccall "static Imlib2.h imlib_load_image" imlibLoadImage :: CString -> IO ImlibImage
+loadImage str = withCString str imlibLoadImage
+
+--Imlib_Image imlib_load_image_immediately(const char *file);
+foreign import ccall "static Imlib2.h imlib_load_image_immediately" imlibLoadImageImmediately :: CString -> IO ImlibImage
+loadImageImmediately str = withCString str imlibLoadImageImmediately
+
+--Imlib_Image imlib_load_image_without_cache(const char *file);
+foreign import ccall "static Imlib2.h imlib_load_image_without_cache" imlibLoadImageWithoutCache :: CString -> IO ImlibImage
+loadImageWithoutCache str = withCString str imlibLoadImageWithoutCache
+
+--Imlib_Image imlib_load_image_immediately_without_cache(const char *file);
+foreign import ccall "static Imlib2.h imlib_load_image_immediately_without_cache" imlibLoadImageImmediatelyWithoutCache :: CString -> IO ImlibImage
+loadImageImmediatelyWithoutCache str = withCString str imlibLoadImageImmediatelyWithoutCache
+
+--Imlib_Image imlib_load_image_with_error_return(const char *file, Imlib_Load_Error *error_return);
+foreign import ccall "static Imlib2.h imlib_load_image_with_error_return" imlibLoadImageWithErrorReturn :: CString -> Ptr Int -> IO ImlibImage
+loadImageWithErrorReturn :: String -> IO (ImlibImage, ImlibLoadError)
+loadImageWithErrorReturn str = do
+    pe <- malloc
+    im <- withCString str (\s -> imlibLoadImageWithErrorReturn s pe)
+    e <- peek pe
+    free pe
+    return (im, toEnum e)
+
+--void imlib_free_image(void);
+foreign import ccall "static Imlib2.h imlib_free_image" imlibFreeImage :: IO ()
+freeImage = imlibFreeImage
+
+--void imlib_free_image_and_decache(void);
+foreign import ccall "static Imlib2.h imlib_free_image_and_decache" imlibFreeImageAndDecache :: IO ()
+freeImageAndDecache = imlibFreeImageAndDecache
+
+--int imlib_image_get_width(void);
+foreign import ccall "static Imlib2.h imlib_image_get_width" imlibImageGetWidth :: IO Int
+imageGetWidth = imlibImageGetWidth
+
+--int imlib_image_get_height(void);
+foreign import ccall "static Imlib2.h imlib_image_get_height" imlibImageGetHeight :: IO Int
+imageGetHeight = imlibImageGetHeight
+
+--const char *imlib_image_get_filename(void);
+foreign import ccall "static Imlib2.h imlib_image_get_filename" imlibImageGetFilename :: IO CString
+imageGetFilename = do
+    b <- imlibImageGetFilename
+    peekCString b
+
+--DATA32 *imlib_image_get_data(void);
+foreign import ccall "static Imlib2.h imlib_image_get_data" imlibImageGetData :: IO (Ptr Word32)
+imageGetData = imlibImageGetData
+
+--DATA32 *imlib_image_get_data_for_reading_only(void);
+foreign import ccall "static Imlib2.h imlib_image_get_data_for_reading_only" imlibImageGetDataForReadingOnly :: IO (Ptr Word32)
+imageGetDataForReadingOnly = imlibImageGetDataForReadingOnly
+
+--void imlib_image_put_back_data(DATA32 *data);
+foreign import ccall "static Imlib2.h imlib_image_put_back_data" imlibImagePutBackData :: Ptr Word32 -> IO ()
+imagePutBackData = imlibImagePutBackData
+
+-- Convenience "control structure" for working with getting and putting image data back, since you must always return the data that you get.
+imageWithData :: (Ptr Word32 -> IO a) -> IO a
+imageWithData f = do
+    p <- imageGetData
+    r <- f p
+    imagePutBackData p
+    return r
+
+withImageBits :: (Int -> Int -> [Word32] -> [Word32]) -> IO ()
+withImageBits f = do
+    w <- imageGetWidth
+    h <- imageGetHeight
+    p <- imageGetData
+    arr <- peekArray (w*h) p
+    -- turn the [Word32] into a [Imlib_Color] and pass it to the function along with the
+    -- width and height, then poke the array with the new image returned.
+    pokeArray p $ f w h arr
+    imagePutBackData p
+
+-- Takes a function which gets the image width and height and image data and transforms it,
+-- and returns an action performing that transformation.
+withImage :: (Int -> Int -> [ImlibColor] -> [ImlibColor]) -> IO ()
+withImage f = do
+    w <- imageGetWidth
+    h <- imageGetHeight
+    p <- imageGetData
+    arr <- peekArray (w*h) p
+    -- turn the [Word32] into a [Imlib_Color] and pass it to the function along with the
+    -- width and height, then poke the array with the new image returned.
+    pokeArray p . map colorToBits . f w h . map colorFromBits $ arr
+    imagePutBackData p
+
+--char imlib_image_has_alpha(void);
+foreign import ccall "static Imlib2.h imlib_image_has_alpha" imlibImageHasAlpha :: IO Bool
+imageHasAlpha = imlibImageHasAlpha
+
+--void imlib_image_set_changes_on_disk(void);
+foreign import ccall "static Imlib2.h imlib_image_set_changes_on_disk" imlibImageSetChangesOnDisk :: IO ()
+imageSetChangesOnDisk = imlibImageSetChangesOnDisk
+
+--void imlib_image_get_border(Imlib_Border *border);
+foreign import ccall "static Imlib2.h imlib_image_get_border" imlibImageGetBorder :: Ptr ImlibBorder -> IO ()
+imageGetBorder :: IO ImlibBorder
+imageGetBorder = do
+    b <- malloc
+    imlibImageGetBorder b
+    bb <- peek b
+    free b
+    return bb
+    
+--void imlib_image_set_border(Imlib_Border *border);
+foreign import ccall "static Imlib2.h imlib_image_set_border" imlibImageSetBorder :: Ptr ImlibBorder -> IO ()
+imageSetBorder :: ImlibBorder -> IO ()
+imageSetBorder b = do
+    p <- malloc
+    poke p b
+    imlibImageSetBorder p
+    free p
+
+--void imlib_image_set_format(const char *format);
+foreign import ccall "static Imlib2.h imlib_image_set_format" imlibImageSetFormat :: CString -> IO ()
+imageSetFormat str = withCString str imlibImageSetFormat
+
+--void imlib_image_set_irrelevant_format(char irrelevant);
+foreign import ccall "static Imlib2.h imlib_image_set_irrelevant_format" imlibImageSetIrrelevantFormat :: Bool -> IO ()
+imageSetIrrelevantFormat = imlibImageSetIrrelevantFormat
+
+--void imlib_image_set_irrelevant_border(char irrelevant);
+foreign import ccall "static Imlib2.h imlib_image_set_irrelevant_border" imlibImageSetIrrelevantBorder :: Bool -> IO ()
+imageSetIrrelevantBorder = imlibImageSetIrrelevantBorder
+
+--void imlib_image_set_irrelevant_alpha(char irrelevant);
+foreign import ccall "static Imlib2.h imlib_image_set_irrelevant_alpha" imlibImageSetIrrelevantAlpha :: Bool -> IO ()
+imageSetIrrelevantAlpha = imlibImageSetIrrelevantAlpha
+
+--char *imlib_image_format(void);
+foreign import ccall "static Imlib2.h imlib_image_format" imlibImageFormat :: IO CString
+imageFormat :: IO String
+imageFormat = imlibImageFormat >>= peekCString
+
+--void imlib_image_set_has_alpha(char has_alpha);
+foreign import ccall "static Imlib2.h imlib_image_set_has_alpha" imlibImageSetHasAlpha :: Bool -> IO ()
+imageSetHasAlpha = imlibImageSetHasAlpha
+
+
+--void imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int destination_width, int destination_height);
+foreign import ccall "static Imlib2.h imlib_blend_image_onto_image" imlibBlendImageOntoImage 
+    :: ImlibImage
+    -> Bool  -- merge alpha
+    -> Int   -- source x
+    -> Int   -- source y
+    -> Int   -- source width
+    -> Int   -- source height
+    -> Int   -- dest x
+    -> Int   -- dest y
+    -> Int   -- dest width
+    -> Int   -- dest height
+    -> IO ()
+blendImageOntoImage mergeAlpha (sx, sy, sw, sh) (dx, dy, dw, dh) = imlibBlendImageOntoImage mergeAlpha sx sy sw sh dx dy dw dh
+
+--Imlib_Image imlib_create_image(int width, int height);
+foreign import ccall "static Imlib2.h imlib_create_image" imlibCreateImage :: Int -> Int -> IO ImlibImage
+createImage = imlibCreateImage
+
+--Imlib_Image imlib_create_image_using_data(int width, int height, DATA32 *data);
+foreign import ccall "static Imlib2.h imlib_create_image_using_data" imlibCreateImageUsingData :: Int -> Int -> Ptr Word32 -> IO ImlibImage
+createImageUsingData = imlibCreateImageUsingData
+
+--Imlib_Image imlib_create_image_using_copied_data(int width, int height, DATA32 *data);
+foreign import ccall "static Imlib2.h imlib_create_image_using_copied_data" imlibCreateImageUsingCopiedData :: Int -> Int -> Ptr(Word32) -> IO ImlibImage
+createImageUsingCopiedData = imlibCreateImageUsingCopiedData
+
+createImageUsingList :: Int -> Int -> [ImlibColor] -> IO ImlibImage
+createImageUsingList w h xs = withArray (map colorToBits xs) (createImageUsingCopiedData w h)
+
+createImageUsingArray :: Array (Int, Int) ImlibColor -> IO ImlibImage
+createImageUsingArray a = createImageUsingList (b-t+1) (r-l+1) (elems a)
+    where ((t,l),(b,r)) = bounds a
+
+--Imlib_Image imlib_clone_image(void);
+foreign import ccall "static Imlib2.h imlib_clone_image" imlibCloneImage :: IO ImlibImage
+cloneImage = imlibCloneImage
+
+--Imlib_Image imlib_create_cropped_image(int x, int y, int width, int height);
+foreign import ccall "static Imlib2.h imlib_create_cropped_image" imlibCreateCroppedImage :: Int -> Int -> Int -> Int -> IO ImlibImage
+createCroppedImage = imlibCreateCroppedImage
+
+--Imlib_Image imlib_create_cropped_scaled_image(int source_x, int source_y, int source_width, int source_height, int destination_width, int destination_height);
+foreign import ccall "static Imlib2.h imlib_create_cropped_scaled_image" imlibCreateCroppedScaledImage :: Int -> Int -> Int -> Int -> Int -> Int -> IO ImlibImage
+createCroppedScaledImage = imlibCreateCroppedScaledImage
+
+--Imlib_Updates imlib_updates_clone(Imlib_Updates updates);
+foreign import ccall "static Imlib2.h imlib_updates_clone" imlibUpdatesClone :: ImlibUpdates -> IO ImlibUpdates
+updatesClone = imlibUpdatesClone
+
+--Imlib_Updates imlib_update_append_rect(Imlib_Updates updates, int x, int y, int w, int h);
+foreign import ccall "static Imlib2.h imlib_update_append_rect" imlibUpdateAppendRect :: ImlibUpdates -> Int -> Int -> Int -> Int -> IO ImlibUpdates
+updateAppendRect = imlibUpdateAppendRect
+
+--Imlib_Updates imlib_updates_merge(Imlib_Updates updates, int w, int h);
+foreign import ccall "static Imlib2.h imlib_updates_merge" imlibUpdatesMerge :: ImlibUpdates -> Int -> Int -> IO ImlibUpdates
+updatesMerge = imlibUpdatesMerge
+
+--Imlib_Updates imlib_updates_merge_for_rendering(Imlib_Updates updates, int w, int h);
+foreign import ccall "static Imlib2.h imlib_updates_merge_for_rendering" imlibUpdatesMergeForRendering :: ImlibUpdates -> Int -> Int -> IO ImlibUpdates
+updatesMergeForRendering = imlibUpdatesMergeForRendering
+
+--void imlib_updates_free(Imlib_Updates updates);
+foreign import ccall "static Imlib2.h imlib_updates_free" imlibUpdatesFree :: ImlibUpdates -> IO ()
+updatesFree = imlibUpdatesFree
+
+--Imlib_Updates imlib_updates_get_next(Imlib_Updates updates);
+foreign import ccall "static Imlib2.h imlib_updates_get_next" imlibUpdatesGetNext :: ImlibUpdates -> IO ImlibUpdates
+updatesGetNext = imlibUpdatesGetNext
+
+--void imlib_updates_get_coordinates(Imlib_Updates updates, int *x_return, int *y_return, int *width_return, int *height_return);
+foreign import ccall "static Imlib2.h imlib_updates_get_coordinates" imlibUpdatesGetCoordinates :: ImlibUpdates -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+updatesGetCoordinates :: ImlibUpdates -> IO (Int, Int, Int, Int)
+updatesGetCoordinates u = do
+    [x,y,w,h] <- nmalloc 4
+    imlibUpdatesGetCoordinates u x y w h
+    [xx,yy,ww,hh] <- mapM peek [x,y,w,h]
+    mapM free [x,y,w,h]
+    return (xx,yy,ww,hh) 
+
+--void imlib_updates_set_coordinates(Imlib_Updates updates, int x, int y, int width, int height);
+foreign import ccall "static Imlib2.h imlib_updates_set_coordinates" imlibUpdatesSetCoordinates :: ImlibUpdates -> Int -> Int -> Int -> Int -> IO ()
+updatesSetCoordinates = imlibUpdatesSetCoordinates
+
+--Imlib_Updates imlib_updates_init(void);
+foreign import ccall "static Imlib2.h imlib_updates_init" imlibUpdatesInit :: IO ImlibUpdates
+updatesInit = imlibUpdatesInit
+
+--Imlib_Updates imlib_updates_append_updates(Imlib_Updates updates, Imlib_Updates appended_updates);
+foreign import ccall "static Imlib2.h imlib_updates_append_updates" imlibUpdatesAppendUpdates :: ImlibUpdates -> ImlibUpdates -> IO ImlibUpdates
+updatesAppendUpdates = imlibUpdatesAppendUpdates
+
+--void imlib_image_flip_horizontal(void);
+foreign import ccall "static Imlib2.h imlib_image_flip_horizontal" imlibImageFlipHorizontal :: IO ()
+imageFlipHorizontal = imlibImageFlipHorizontal
+
+--void imlib_image_flip_vertical(void);
+foreign import ccall "static Imlib2.h imlib_image_flip_vertical" imlibImageFlipVertical :: IO ()
+imageFlipVertical = imlibImageFlipVertical
+
+--void imlib_image_flip_diagonal(void);
+foreign import ccall "static Imlib2.h imlib_image_flip_diagonal" imlibImageFlipDiagonal :: IO ()
+imageFlipDiagonal = imlibImageFlipDiagonal
+
+--void imlib_image_orientate(int orientation);
+foreign import ccall "static Imlib2.h imlib_image_orientate" imlibImageOrientate :: Int -> IO ()
+imageOrientate = imlibImageOrientate
+
+--void imlib_image_blur(int radius);
+foreign import ccall "static Imlib2.h imlib_image_blur" imlibImageBlur :: Int -> IO ()
+imageBlur = imlibImageBlur
+
+--void imlib_image_sharpen(int radius);
+foreign import ccall "static Imlib2.h imlib_image_sharpen" imlibImageSharpen :: Int -> IO ()
+imageSharpen = imlibImageSharpen
+
+--void imlib_image_tile_horizontal(void);
+foreign import ccall "static Imlib2.h imlib_image_tile_horizontal" imlibImageTileHorizontal :: IO ()
+imageTileHorizontal = imlibImageTileHorizontal
+
+--void imlib_image_tile_vertical(void);
+foreign import ccall "static Imlib2.h imlib_image_tile_vertical" imlibImageTileVertical :: IO ()
+imageTileVertical = imlibImageTileVertical
+
+--void imlib_image_tile(void);
+foreign import ccall "static Imlib2.h imlib_image_tile" imlibImageTile :: IO ()
+imageTile = imlibImageTile
+
+--Imlib_Font imlib_load_font(const char *font_name);
+foreign import ccall "static Imlib2.h imlib_load_font" imlibLoadFont :: CString -> IO ImlibFont
+loadFont str = withCString str imlibLoadFont
+
+--void imlib_free_font(void);
+foreign import ccall "static Imlib2.h imlib_free_font" imlibFreeFont :: IO ()
+freeFont str = imlibFreeFont
+
+
+--void imlib_text_draw(int x, int y, const char *text);
+foreign import ccall "static Imlib2.h imlib_text_draw" imlibTextDraw :: Int -> Int -> CString -> IO ()
+textDraw x y str = withCString str (imlibTextDraw x y)
+
+--void imlib_text_draw_with_return_metrics(int x, int y, const char *text, int *width_return, int *height_return, int *horizontal_advance_return, int *vertical_advance_return);
+foreign import ccall "static Imlib2.h imlib_text_draw_with_return_metrics" imlibTextDrawWithReturnMetrics :: Int -> Int -> CString -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+textDrawWithReturnMetrics x y str = do
+    [w,h,ah,av] <- nmalloc 4
+    withCString str (\s -> imlibTextDrawWithReturnMetrics x y s w h ah av)
+    [rw,rh,rah,rav] <- mapM peek [w,h,ah,av]
+    mapM free [w,h,ah,av]
+    return (rw,rh,rah,rav) 
+
+--void imlib_get_text_size(const char *text, int *width_return, int *height_return);
+foreign import ccall "static Imlib2.h imlib_get_text_size" imlibGetTextSize :: CString -> Ptr Int -> Ptr Int -> IO ()
+getTextSize str = do
+    [w,h] <- nmalloc 4
+    withCString str (\s -> imlibGetTextSize s w h)
+    [rw,rh] <- mapM peek [w,h]
+    mapM free [w,h]
+    return (rw,rh) 
+
+--void imlib_get_text_advance(const char *text, int *horizontal_advance_return, int *vertical_advance_return);
+foreign import ccall "static Imlib2.h imlib_get_text_advance" imlibGetTextAdvance :: CString -> Ptr Int -> Ptr Int -> IO ()
+getTextAdvance str = do
+    [h,v] <- nmalloc 4
+    withCString str (\s -> imlibGetTextAdvance s h v)
+    [rh,rv] <- mapM peek [h,v]
+    mapM free [h,v]
+    return (rh,rv) 
+
+--int imlib_get_text_inset(const char *text);
+foreign import ccall "static Imlib2.h imlib_get_text_inset" imlibGetTextInset :: CString -> IO Int
+getTextInset str = withCString str imlibGetTextInset
+
+--void imlib_add_path_to_font_path(const char *path);
+foreign import ccall "static Imlib2.h imlib_add_path_to_font_path" imlibAddPathToFontPath :: CString -> IO ()
+addPathToFontPath str = withCString str imlibAddPathToFontPath
+
+--void imlib_remove_path_from_font_path(const char *path);
+foreign import ccall "static Imlib2.h imlib_remove_path_from_font_path" imlibRemovePathFromFontPath :: CString -> IO ()
+removePathFromFontPath str = withCString str imlibRemovePathFromFontPath
+
+--char **imlib_list_font_path(int *number_return);
+foreign import ccall "static Imlib2.h imlib_list_font_path" imlibListFontPath :: Ptr Int -> IO (Ptr CString)
+listFontPath = do
+    pn <- malloc
+    pxs <- imlibListFontPath pn
+    n <- peek pn
+    free pn
+    xs <- peekArray n pxs
+    xs <- mapM peekCString xs
+    return xs
+
+--int imlib_text_get_index_and_location(const char *text, int x, int y, int *char_x_return, int *char_y_return, int *char_width_return, int *char_height_return);
+foreign import ccall "static Imlib2.h imlib_text_get_index_and_location" imlibTextGetIndexAndLocation :: CString -> Int -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO Int
+textGetIndexAndLocation str x y = do
+    [xp,yp,wp,hp] <- nmalloc 4
+    n <- withCString str (\s -> imlibTextGetIndexAndLocation s x y xp yp wp hp)
+    [xr,yr,wr,hr] <- mapM peek [xp,yp,wp,hp]
+    mapM free [xp,yp,wp,hp]
+    return (n,xr,yr,wr,hr) 
+
+
+--void imlib_text_get_location_at_index(const char *text, int index, int *char_x_return, int *char_y_return, int *char_width_return, int *char_height_return);
+foreign import ccall "static Imlib2.h imlib_text_get_location_at_index" imlibTextGetLocationAtIndex :: CString -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+textGetLocationAtIndex str k = do
+    [xp,yp,wp,hp] <- nmalloc 4
+    withCString str (\s -> imlibTextGetLocationAtIndex s k xp yp wp hp)
+    [xr,yr,wr,hr] <- mapM peek [xp,yp,wp,hp]
+    mapM free [xp,yp,wp,hp]
+    return (xr,yr,wr,hr) 
+
+--char **imlib_list_fonts(int *number_return);
+--void imlib_free_font_list(char **font_list, int number);
+foreign import ccall "static Imlib2.h imlib_list_fonts" imlibListFonts :: Ptr Int -> IO (Ptr CString)
+foreign import ccall "static Imlib2.h imlib_free_font_list" imlibFreeFontList :: Ptr (CString) -> Int -> IO ()
+listFonts = do
+    pn <- malloc
+    pxs <- imlibListFonts pn
+    n <- peek pn
+    free pn
+    xs <- peekArray n pxs
+    xs <- mapM peekCString xs
+    imlibFreeFontList pxs n
+    return xs
+
+--int imlib_get_font_cache_size(void);
+foreign import ccall "static Imlib2.h imlib_get_font_cache_size" imlibGetFontCacheSize :: IO Int
+getFontCacheSize = imlibGetFontCacheSize
+
+--void imlib_set_font_cache_size(int bytes);
+foreign import ccall "static Imlib2.h imlib_set_font_cache_size" imlibSetFontCacheSize :: Int -> IO ()
+setFontCacheSize = imlibSetFontCacheSize
+
+--void imlib_flush_font_cache(void);
+foreign import ccall "static Imlib2.h imlib_flush_font_cache" imlibFlushFontCache :: IO ()
+flushFontCache = imlibFlushFontCache
+
+--int imlib_get_font_ascent(void);
+foreign import ccall "static Imlib2.h imlib_get_font_ascent" imlibGetFontAscent :: IO Int
+getFontAscent = imlibGetFontAscent
+
+--int imlib_get_font_descent(void);
+foreign import ccall "static Imlib2.h imlib_get_font_descent" imlibGetFontDescent :: IO Int
+getFontDescent = imlibGetFontDescent
+
+--int imlib_get_maximum_font_ascent(void);
+foreign import ccall "static Imlib2.h imlib_get_maximum_font_ascent" imlibGetMaximumFontAscent :: IO Int
+getMaximumFontAscent = imlibGetMaximumFontAscent
+
+--int imlib_get_maximum_font_descent(void);
+foreign import ccall "static Imlib2.h imlib_get_maximum_font_descent" imlibGetMaximumFontDescent :: IO Int
+getMaximumFontDescent = imlibGetMaximumFontDescent
+
+--Imlib_Color_Modifier imlib_create_color_modifier(void);
+foreign import ccall "static Imlib2.h imlib_create_color_modifier" imlibCreateColorModifier :: IO ImlibColorModifier
+createColorModifier = imlibCreateColorModifier
+
+--void imlib_free_color_modifier(void);
+foreign import ccall "static Imlib2.h imlib_free_color_modifier" imlibFreeColorModifier :: IO ()
+freeColorModifier = imlibFreeColorModifier
+
+--void imlib_modify_color_modifier_gamma(double gamma_value);
+foreign import ccall "static Imlib2.h imlib_modify_color_modifier_gamma" imlibModifyColorModifierGamma :: Double -> IO ()
+modifyColorModifierGamma = imlibModifyColorModifierGamma
+
+--void imlib_modify_color_modifier_brightness(double brightness_value);
+foreign import ccall "static Imlib2.h imlib_modify_color_modifier_brightness" imlibModifyColorModifierBrightness :: Double -> IO ()
+modifyColorModifierBrightness = imlibModifyColorModifierBrightness
+
+--void imlib_modify_color_modifier_contrast(double contrast_value);
+foreign import ccall "static Imlib2.h imlib_modify_color_modifier_contrast" imlibModifyColorModifierContrast :: Double -> IO ()
+modifyColorModifierContrast = imlibModifyColorModifierContrast
+
+--void imlib_set_color_modifier_tables(DATA8 *red_table, DATA8 *green_table, DATA8 *blue_table, DATA8 *alpha_table);
+foreign import ccall "static Imlib2.h imlib_set_color_modifier_tables" imlibSetColorModifierTables :: (Ptr Word8) -> (Ptr Word8) -> (Ptr Word8) -> (Ptr Word8) -> IO ()
+setColorModifierTables r g b a = do
+    withArray rs (\ra ->
+        withArray gs (\ga ->
+            withArray bs (\ba ->
+                withArray as (\aa -> imlibSetColorModifierTables ra ga ba aa))))
+    where
+        padLeft n a xs | l >  n = take n xs
+                       | l <  n = (replicate (n-l) a) ++ xs
+                       | l == n = xs
+            where l = length xs
+        rs = padLeft 256 0 r
+        gs = padLeft 256 0 g
+        bs = padLeft 256 0 b
+        as = padLeft 256 0 a
+
+--void imlib_get_color_modifier_tables(DATA8 *red_table, DATA8 *green_table, DATA8 *blue_table, DATA8 *alpha_table);
+foreign import ccall "static Imlib2.h imlib_get_color_modifier_tables" imlibGetColorModifierTables :: (Ptr Word8) -> (Ptr Word8) -> (Ptr Word8) -> (Ptr Word8) -> IO ()
+getColorModifierTables = do
+    [ra,ga,ba,aa] <- nmallocArray 4 256
+    imlibGetColorModifierTables ra ga ba aa
+    [rs,gs,bs,as] <- mapM (peekArray 256) [ra,ga,ba,aa]
+    mapM free [ra,ga,ba,aa]
+    return (rs,gs,bs,as)
+
+--void imlib_reset_color_modifier(void);
+foreign import ccall "static Imlib2.h imlib_reset_color_modifier" imlibResetColorModifier :: IO ()
+resetColorModifier = imlibResetColorModifier
+
+--void imlib_apply_color_modifier(void);
+foreign import ccall "static Imlib2.h imlib_apply_color_modifier" imlibApplyColorModifier :: IO ()
+applyColorModifier = imlibApplyColorModifier
+
+--void imlib_apply_color_modifier_to_rectangle(int x, int y, int width, int height);
+foreign import ccall "static Imlib2.h imlib_apply_color_modifier_to_rectangle" imlibApplyColorModifierToRectangle :: Int -> Int -> Int -> Int -> IO ()
+applyColorModifierToRectangle = imlibApplyColorModifierToRectangle
+
+--Imlib_Updates imlib_image_draw_line(int x1, int y1, int x2, int y2, char make_updates);
+foreign import ccall "static Imlib2.h imlib_image_draw_line" imlibImageDrawLine :: Int -> Int -> Int -> Int -> Bool -> IO ImlibUpdates
+imageDrawLine = imlibImageDrawLine
+
+--void imlib_image_draw_rectangle(int x, int y, int width, int height);
+foreign import ccall "static Imlib2.h imlib_image_draw_rectangle" imlibImageDrawRectangle :: Int -> Int -> Int -> Int -> IO ()
+imageDrawRectangle = imlibImageDrawRectangle
+
+--void imlib_image_fill_rectangle(int x, int y, int width, int height);
+foreign import ccall "static Imlib2.h imlib_image_fill_rectangle" imlibImageFillRectangle :: Int -> Int -> Int -> Int -> IO ()
+imageFillRectangle = imlibImageFillRectangle
+
+--void imlib_image_copy_alpha_to_image(Imlib_Image image_source, int x, int y);
+foreign import ccall "static Imlib2.h imlib_image_copy_alpha_to_image" imlibImageCopyAlphaToImage :: ImlibImage -> Int -> Int -> IO ()
+imageCopyAlphaToImage = imlibImageCopyAlphaToImage
+
+--void imlib_image_copy_alpha_rectangle_to_image(Imlib_Image image_source, int x, int y, int width, int height, int destination_x, int destination_y);
+foreign import ccall "static Imlib2.h imlib_image_copy_alpha_rectangle_to_image" imlibImageCopyAlphaRectangleToImage :: ImlibImage -> Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+imageCopyAlphaRectangleToImage = imlibImageCopyAlphaRectangleToImage
+
+--void imlib_image_scroll_rect(int x, int y, int width, int height, int delta_x, int delta_y);
+foreign import ccall "static Imlib2.h imlib_image_scroll_rect" imlibImageScrollRect :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+imageScrollRect = imlibImageScrollRect
+
+--void imlib_image_copy_rect(int x, int y, int width, int height, int new_x, int new_y);
+foreign import ccall "static Imlib2.h imlib_image_copy_rect" imlibImageCopyRect :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+imageCopyRect = imlibImageCopyRect
+
+--Imlib_Color_Range imlib_create_color_range(void);
+foreign import ccall "static Imlib2.h imlib_create_color_range" imlibCreateColorRange :: IO ImlibColorRange
+createColorRange = imlibCreateColorRange
+
+--void imlib_free_color_range(void);
+foreign import ccall "static Imlib2.h imlib_free_color_range" imlibFreeColorRange :: IO ()
+freeColorRange = imlibFreeColorRange
+
+--void imlib_add_color_to_color_range(int distance_away);
+foreign import ccall "static Imlib2.h imlib_add_color_to_color_range" imlibAddColorToColorRange :: Int -> IO ()
+addColorToColorRange = imlibAddColorToColorRange
+
+--void imlib_image_fill_color_range_rectangle(int x, int y, int width, int height, double angle);
+foreign import ccall "static Imlib2.h imlib_image_fill_color_range_rectangle" imlibImageFillColorRangeRectangle :: Int -> Int -> Int -> Int -> Double -> IO ()
+imageFillColorRangeRectangle = imlibImageFillColorRangeRectangle
+
+--void imlib_image_fill_hsva_color_range_rectangle(int x, int y, int width, int height, double angle);
+foreign import ccall "static Imlib2.h imlib_image_fill_hsva_color_range_rectangle" imlibImageFillHsvaColorRangeRectangle :: Int -> Int -> Int -> Int -> Double -> IO ()
+imageFillHsvaColorRangeRectangle = imlibImageFillHsvaColorRangeRectangle
+
+--void imlib_image_query_pixel(int x, int y, Imlib_Color *color_return);
+foreign import ccall "static Imlib2.h imlib_image_query_pixel" imlibImageQueryPixel :: Int -> Int -> Ptr ImlibColor -> IO ()
+imageQueryPixel x y = do
+    c <- malloc
+    imlibImageQueryPixel x y c
+    r <- peek c
+    free c
+    return r
+
+--void imlib_image_query_pixel_cmya(int x, int y, int *cyan, int *magenta, int *yellow, int *alpha);
+foreign import ccall "static Imlib2.h imlib_image_query_pixel_cmya" imlibImageQueryPixelCmya :: Int -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+imageQueryPixelCmya :: Int -> Int -> IO (Int, Int, Int, Int)
+imageQueryPixelCmya cx cy = do
+    [c,m,y,a] <- nmalloc 4
+    imlibImageQueryPixelCmya cx cy c m y a
+    [cc,mm,yy,aa] <- mapM peek [c,m,y,a]
+    mapM free [c,m,y,a]
+    return (cc,mm,yy,aa) 
+
+--void imlib_image_query_pixel_hsva(int x, int y, float *hue, float *saturation, float *value, int *alpha);
+foreign import ccall "static Imlib2.h imlib_image_query_pixel_hsva" imlibImageQueryPixelHsva :: Int -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+imageQueryPixelHsva :: Int -> Int -> IO (Int, Int, Int, Int)
+imageQueryPixelHsva cx cy = do
+    [h,s,v,a] <- nmalloc 4
+    imlibImageQueryPixelCmya cx cy h s v a
+    [hh,ss,vv,aa] <- mapM peek [h,s,v,a]
+    mapM free [h,s,v,a]
+    return (hh,ss,vv,aa) 
+
+--void imlib_image_query_pixel_hlsa(int x, int y, float *hue, float *lightness, float *saturation, int *alpha);
+foreign import ccall "static Imlib2.h imlib_image_query_pixel_hlsa" imlibImageQueryPixelHlsa :: Int -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+imageQueryPixelHlsa :: Int -> Int -> IO (Int, Int, Int, Int)
+imageQueryPixelHlsa cx cy = do
+    [h,l,s,a] <- nmalloc 4
+    imlibImageQueryPixelHlsa cx cy h l s a
+    [hh,ll,ss,aa] <- mapM peek [h,l,s,a]
+    mapM free [h,l,s,a]
+    return (hh,ll,ss,aa) 
+
+--void imlib_image_attach_data_value(const char *key, void *data, int value, Imlib_Data_Destructor_Function destructor_function);
+foreign import ccall "static Imlib2.h imlib_image_attach_data_value" imlibImageAttachDataValue :: CString -> Ptr () -> Int -> FunPtr ImlibDataDestructorFunction -> IO () 
+imageAttachDataValue key d v dest = do
+    df <- mkDestructorFunction dest
+    withCString key (\k -> imlibImageAttachDataValue k d v df)
+
+--void *imlib_image_get_attached_data(const char *key);
+foreign import ccall "static Imlib2.h imlib_image_get_attached_data" imlibImageGetAttachedData :: CString -> IO (Ptr ()) 
+imageGetAttachedData key = withCString key imlibImageGetAttachedData
+
+--int imlib_image_get_attached_value(const char *key);
+foreign import ccall "static Imlib2.h imlib_image_get_attached_value" imlibImageGetAttachedValue :: CString -> IO Int 
+imageGetAttachedValue key = withCString key imlibImageGetAttachedValue
+
+--void imlib_image_remove_attached_data_value(const char *key);
+foreign import ccall "static Imlib2.h imlib_image_remove_attached_data_value" imlibImageRemoveAttachedDataValue :: CString -> IO () 
+imageRemoveAttachedDataValue key = withCString key imlibImageRemoveAttachedDataValue
+
+--void imlib_image_remove_and_free_attached_data_value(const char *key);
+foreign import ccall "static Imlib2.h imlib_image_remove_and_free_attached_data_value" imlibImageRemoveAndFreeAttachedDataValue :: CString -> IO () 
+imageRemoveAndFreeAttachedDataValue key = withCString key imlibImageRemoveAndFreeAttachedDataValue
+
+--void imlib_save_image(const char *filename);
+foreign import ccall "static Imlib2.h imlib_save_image" imlibSaveImage :: CString -> IO ()
+saveImage str = withCString str imlibSaveImage
+
+--void imlib_save_image_with_error_return(const char *filename, Imlib_Load_Error *error_return);
+foreign import ccall "static Imlib2.h imlib_save_image_with_error_return" imlibSaveImageWithErrorReturn :: CString -> Ptr Int -> IO ()
+saveImageWithErrorReturn :: String -> IO ImlibLoadError
+saveImageWithErrorReturn str = do
+    pe <- malloc
+    im <- withCString str (\s -> imlibSaveImageWithErrorReturn s pe)
+    e <- peek pe
+    free pe
+    return (toEnum e) 
+
+--Imlib_Image imlib_create_rotated_image(double angle);
+foreign import ccall "static Imlib2.h imlib_create_rotated_image" imlibCreateRotatedImage :: Double -> IO ImlibImage
+createRotatedImage = imlibCreateRotatedImage
+
+--void imlib_blend_image_onto_image_at_angle(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int angle_x, int angle_y);
+foreign import ccall "static Imlib2.h imlib_blend_image_onto_image_at_angle" imlibBlendImageOntoImageAtAngle :: Ptr(ImlibImage)
+                                                                             -> Bool  -- merge alpha
+                                                                             -> Int   -- source x
+                                                                             -> Int   -- source y
+                                                                             -> Int   -- source width
+                                                                             -> Int   -- source height
+                                                                             -> Int   -- dest x
+                                                                             -> Int   -- dest y
+                                                                             -> Int   -- angle x
+                                                                             -> Int   -- angle y
+                                                                             -> IO ()
+blendImageOntoImageAtAngle = imlibBlendImageOntoImageAtAngle
+
+--void imlib_blend_image_onto_image_skewed(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int h_angle_x, int h_angle_y, int v_angle_x, int v_angle_y);
+foreign import ccall "static Imlib2.h imlib_blend_image_onto_image_skewed" imlibBlendImageOntoImageSkewed :: Ptr(ImlibImage)
+                                                                           -> Bool  -- merge alpha
+                                                                           -> Int   -- source x
+                                                                           -> Int   -- source y
+                                                                           -> Int   -- source width
+                                                                           -> Int   -- source height
+                                                                           -> Int   -- dest x
+                                                                           -> Int   -- dest y
+                                                                           -> Int   -- h angle x
+                                                                           -> Int   -- h angle y
+                                                                           -> Int   -- v angle x
+                                                                           -> Int   -- v angle y
+                                                                           -> IO ()
+blendImageOntoImageSkewed = imlibBlendImageOntoImageSkewed
+
+--void imlib_context_set_cliprect(int x, int y, int w, int h);
+foreign import ccall "static Imlib2.h imlib_context_set_cliprect" imlibContextSetCliprect :: Int -> Int -> Int -> Int -> IO ()
+contextSetCliprect = imlibContextSetCliprect
+
+--int imlib_clip_line(int x0, int y0, int x1, int y1, int xmin, int xmax, int ymin, int ymax, int *clip_x0, int *clip_y0, int *clip_x1, int *clip_y1);
+{- -- Apparently this call no longer exists.
+foreign import ccall "static Imlib2.h imlib_clip_line" imlibClipLine :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO Int
+clipLine x0 y0 x1 y1 xmin xmax ymin ymax = do
+    [cx0,cy0,cx1,cy1] <- nmalloc 4
+    n <- imlibClipLine x0 y0 x1 y1 xmin xmax ymin ymax cx0 cy0 cx1 cy1
+    [rcx0,rcy0,rcx1,rcy1] <- mapM peek [cx0,cy0,cx1,cy1]
+    mapM free [cx0,cy0,cx1,cy1]
+    return (n,rcx0,rcy0,rcx1,rcy1)
+-}
+
+--void imlib_polygon_new(void);
+foreign import ccall "static Imlib2.h imlib_polygon_new" imlibPolygonNew :: IO ()
+polygonNew = imlibPolygonNew
+
+--void imlib_polygon_free(ImlibPolygon poly);
+foreign import ccall "static Imlib2.h imlib_polygon_free" imlibPolygonFree :: ImlibPolygon -> IO ()
+polygonFree = imlibPolygonFree
+
+--void imlib_polygon_add_point(ImlibPolygon poly, int x, int y);
+foreign import ccall "static Imlib2.h imlib_polygon_add_point" imlibPolygonAddPoint :: ImlibPolygon -> Int -> Int -> IO ()
+polygonAddPoint = imlibPolygonAddPoint
+
+--void imlib_image_draw_polygon(ImlibPolygon poly, unsigned char closed);
+foreign import ccall "static Imlib2.h imlib_image_draw_polygon" imlibImageDrawPolygon :: ImlibPolygon -> Bool -> IO ()
+imageDrawPolygon = imlibImageDrawPolygon
+
+--void imlib_image_fill_polygon(ImlibPolygon poly);
+foreign import ccall "static Imlib2.h imlib_image_fill_polygon" imlibImageFillPolygon :: ImlibPolygon -> IO ()
+imageFillPolygon = imlibImageFillPolygon
+
+--void imlib_polygon_get_bounds(ImlibPolygon poly, int *px1, int *py1, int *px2, int *py2);
+foreign import ccall "static Imlib2.h imlib_polygon_get_bounds" imlibPolygonGetBounds :: ImlibPolygon -> Ptr Int -> Ptr Int -> Ptr Int -> Ptr Int -> IO ()
+polygonGetBounds poly = do
+    [x1,y1,x2,y2] <- nmalloc 4
+    imlibPolygonGetBounds poly x1 y1 x2 y2
+    [rx1,ry1,rx2,ry2] <- mapM peek [x1,y1,x2,y2]
+    mapM free [x1,y1,x2,y2]
+    return (rx1,ry1,rx2,ry2)
+
+--unsigned char imlib_polygon_contains_point(ImlibPolygon poly, int x, int y);
+foreign import ccall "static Imlib2.h imlib_polygon_contains_point" imlibPolygonContainsPoint :: ImlibPolygon -> Int -> Int -> IO Bool
+polygonContainsPoint = imlibPolygonContainsPoint
+
+--void imlib_image_draw_ellipse(int xc, int yc, int a, int b);
+foreign import ccall "static Imlib2.h imlib_image_draw_ellipse" imlibImageDrawEllipse :: Int -> Int -> Int -> Int -> IO ()
+imageDrawEllipse = imlibImageDrawEllipse
+
+--void imlib_image_fill_ellipse(int xc, int yc, int a, int b);
+foreign import ccall "static Imlib2.h imlib_image_fill_ellipse" imlibImageFillEllipse :: Int -> Int -> Int -> Int -> IO ()
+imageFillEllipse = imlibImageFillEllipse
+
+--void imlib_image_filter(void);
+foreign import ccall "static Imlib2.h imlib_image_filter" imlibImageFilter :: IO ()
+imageFilter = imlibImageFilter
+
+--Imlib_Filter imlib_create_filter(int initsize);
+foreign import ccall "static Imlib2.h imlib_create_filter" imlibCreateFilter :: Int -> IO ImlibFilter
+createFilter = imlibCreateFilter
+
+--void imlib_free_filter(void);
+foreign import ccall "static Imlib2.h imlib_free_filter" imlibFreeFilter :: IO ()
+freeFilter = imlibFreeFilter
+
+--void imlib_filter_set(int xoff, int yoff, int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_set" imlibFilterSet :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+filterSet = imlibFilterSet
+
+--void imlib_filter_set_alpha(int xoff, int yoff, int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_set_alpha" imlibFilterSetAlpha :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+filterSetAlpha = imlibFilterSetAlpha
+
+--void imlib_filter_set_red(int xoff, int yoff, int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_set_red" imlibFilterSetRed :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+filterSetRed = imlibFilterSetRed
+
+--void imlib_filter_set_green(int xoff, int yoff, int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_set_green" imlibFilterSetGreen :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+filterSetGreen = imlibFilterSetGreen  
+
+--void imlib_filter_set_blue(int xoff, int yoff, int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_set_blue" imlibFilterSetBlue :: Int -> Int -> Int -> Int -> Int -> Int -> IO ()
+filterSetBlue = imlibFilterSetBlue
+
+--void imlib_filter_constants(int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_constants" imlibFilterConstants :: Int -> Int -> Int -> Int -> IO ()
+filterConstants = imlibFilterConstants
+
+--void imlib_filter_divisors(int a, int r, int g, int b);
+foreign import ccall "static Imlib2.h imlib_filter_divisors" imlibFilterDivisors :: Int -> Int -> Int -> Int -> IO ()
+filterDivisors = imlibFilterDivisors
+
+
diff --git a/Imlib.cabal b/Imlib.cabal
new file mode 100644
--- /dev/null
+++ b/Imlib.cabal
@@ -0,0 +1,13 @@
+Name:                Imlib
+Version:             0.1
+Description:         Haskell binding for Imlib 2
+Category:            Graphics
+License:             BSD3
+License-file:        LICENSE
+Author:              Cale Gibbard
+Maintainer:          cgibbard@gmail.com
+Build-Depends:       base
+Exposed-Modules:     Graphics.Imlib
+Extra-Libraries:     Imlib2
+Extra-Source-Files:  examples/value2alpha.hs examples/circle-inversion.hs
+ghc-options:         -O2
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+* Haskell Binding for Imlib 2
+* Copyright (c) 2004-2007, Cale Gibbard
+* 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 Cale Gibbard nor the
+*       names of his contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY CALE GIBBARD ``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 CALE GIBBARD 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/examples/circle-inversion.hs b/examples/circle-inversion.hs
new file mode 100644
--- /dev/null
+++ b/examples/circle-inversion.hs
@@ -0,0 +1,35 @@
+import Graphics.Imlib
+import Data.Array
+import System.Random
+
+data Point = Point {x :: Double, y :: Double} deriving (Show, Eq)
+
+data Circle = Circle { centre :: Point, radius :: Double } deriving (Show, Eq)
+
+data Frame = Frame { top :: Double, left :: Double, bottom :: Double, right :: Double }
+
+invert :: Circle -> Point -> Point
+invert (Circle (Point a b) r) (Point x y) = Point (a + q*(x-a)) (b + q*(y-b))
+      where q = r^2 / ((x-a)^2 + (y-b)^2)
+
+invertRandomly :: StdGen -> [Circle] -> Point -> [Point]
+invertRandomly g cs p = p : invertRandomly g' cs (invert (cs !! r) p)
+    where (r,g') = randomR (0,length cs - 1) g
+
+floorPoint :: Point -> (Int, Int)
+floorPoint (Point x y) = (floor x, floor y)
+
+main = do
+     g <- getStdGen
+     let cs = [Circle (Point (512+50) (512+50)) 50, Circle (Point 512 (512+50)) 50, Circle (Point (512+50) (512-1)) 50]
+         p = Point 450 212
+         ps = invertRandomly g cs p
+         psf = filter (\(Point x y) -> x >= 0 && x < 1024 && y >= 0 && y < 1024) ps
+         a = accumArray (\x y -> ImlibColor 0 255 255 255) 
+                        (ImlibColor 0 0 0 0) 
+                        ((0,0), (1024, 1024)) 
+                        (zip (map floorPoint (take 50000 psf)) (repeat 0))
+     buffer <- createImageUsingArray a
+     contextSetImage buffer
+     imageSetFormat "png"
+     saveImage "hello.png"
diff --git a/examples/value2alpha.hs b/examples/value2alpha.hs
new file mode 100644
--- /dev/null
+++ b/examples/value2alpha.hs
@@ -0,0 +1,24 @@
+import Graphics.Imlib
+import Data.Bits
+import System 
+
+valueToAlpha (ImlibColor a r g b) = ImlibColor a' r g b
+    where a' = round ((r' + g' + b') / 3)
+          r' = fromIntegral r
+          g' = fromIntegral g
+          b' = fromIntegral b
+
+usage = do 
+    putStrLn "value2alpha infile outfile"
+    exitFailure
+
+main = do
+    args <- getArgs
+    if (length args /= 2) then usage else return ()
+    let [file,newfile] = args
+    image <- loadImage file
+    contextSetImage image
+    imageSetFormat "png"
+    withImage (\w h xs -> map valueToAlpha xs)
+    imageSetHasAlpha True
+    saveImage newfile
