diff --git a/Graphics/Rendering/Cairo.hs b/Graphics/Rendering/Cairo.hs
--- a/Graphics/Rendering/Cairo.hs
+++ b/Graphics/Rendering/Cairo.hs
@@ -243,6 +243,31 @@
   , withSVGSurface
 #endif
 
+#if CAIRO_CHECK_VERSION(1,10,0)
+  -- * Regions
+  , regionCreate
+  , regionCreateRectangle
+  , regionCreateRectangles
+  , regionCopy
+  , regionGetExtents
+  , regionNumRectangles
+  , regionGetRectangle
+  , regionIsEmpty
+  , regionContainsPoint
+  , regionContainsRectangle
+  , regionEqual
+  , regionTranslate
+  , regionIntersect
+  , regionIntersectRectangle
+  , regionSubtract
+  , regionSubtractRectangle
+  , regionUnion
+  , regionUnionRectangle
+  , regionXor
+  , regionXorRectangle
+
+#endif
+
   -- * Utilities
 
   , liftIO
@@ -273,6 +298,11 @@
   , HintMetrics(..)
   , FontOptions
   , Path
+#if CAIRO_CHECK_VERSION(1,10,0)
+  , RectangleInt(..)
+  , RegionOverlap(..)
+  , Region
+#endif
   , Content(..)
   , Format(..)
   , Extend(..)
@@ -1787,9 +1817,9 @@
 --   big-endian machine, the first pixel is in the uppermost bit, on a
 --   little-endian machine the first pixel is in the least-significant bit.
 --
--- * To read or write a specific pixel use the formula:
---   @p = y * (rowstride `div` 4) + x@ for the pixel and force the array to
---   have 32-bit words or integers.
+-- * To read or write a specific pixel (and assuming 'FormatARGB32' or
+--   'FormatRGB24'), use the formula: @p = y * (rowstride `div` 4) + x@ for the
+--   pixel and force the array to have 32-bit words or integers.
 --
 -- * Calling this function without explicitly giving it a type will often lead
 --   to a compiler error since the type parameter @e@ is underspecified. If
@@ -1801,28 +1831,20 @@
 --   the same type signatures as 'readArray' and 'writeArray'. Note that these
 --   are internal functions that might change with GHC.
 --
--- * After each write access to the array, you need to inform Cairo that
+-- * After each write access to the array, you need to inform Cairo
 --   about the area that has changed using 'surfaceMarkDirty'.
 --
 -- * The function will return an error if the surface is not an image
---   surface of if 'surfaceFinish' has been called on the surface.
+--   surface or if 'surfaceFinish' has been called on the surface.
 -- 
 imageSurfaceGetPixels :: Storable e => Surface -> IO (SurfaceData Int e)
 imageSurfaceGetPixels pb = do
-  pixPtr_ <- Internal.imageSurfaceGetData pb
-  when (pixPtr_==nullPtr) $ do
+  pixPtr <- Internal.imageSurfaceGetData pb
+  when (pixPtr==nullPtr) $ do
     fail "imageSurfaceGetPixels: image surface not available"
-  fmt <- imageSurfaceGetFormat pb
-  let bits = case fmt of
-               FormatARGB32 -> 32
-               FormatRGB24 -> 32
-               FormatA8 -> 8
-               FormatA1 -> 1
   h <- imageSurfaceGetHeight pb
   r <- imageSurfaceGetStride pb
-  let pixPtr = castPtr pixPtr_
-  let bytes = h*((r*bits)+7) `div` 8
-  return (mkSurfaceData pb pixPtr bytes)
+  return (mkSurfaceData pb (castPtr pixPtr) (h*r))
 
 -- | An array that stores the raw pixel data of an image 'Surface'.
 --
@@ -1833,7 +1855,7 @@
 
 mkSurfaceData :: Storable e => Surface -> Ptr e -> Int -> SurfaceData Int e
 mkSurfaceData pb (ptr :: Ptr e) size =
-  SurfaceData pb ptr (0, count) count
+  SurfaceData pb ptr (0, count-1) count
   where count = fromIntegral (size `div` sizeOf (undefined :: e))
 
 #if __GLASGOW_HASKELL__ < 605
@@ -1983,6 +2005,208 @@
                           unless (status == StatusSuccess) $
                             Internal.statusToString status >>= fail)
           (\surface -> f surface)
+#endif
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+-- | Allocates a new empty region object.
+--
+regionCreate :: MonadIO m => m Region
+regionCreate = liftIO $ Internal.regionCreate
+
+-- | Allocates a new region object containing @rectangle@.
+--
+regionCreateRectangle ::
+     MonadIO m =>
+     RectangleInt -- ^ @rectangle@
+  -> m Region
+regionCreateRectangle a = liftIO $ Internal.regionCreateRectangle a
+
+-- | Allocates a new region object containing the union of all given @rects@.
+--
+regionCreateRectangles ::
+     MonadIO m =>
+     [RectangleInt] -- ^ @rects@
+  -> m Region
+regionCreateRectangles a = liftIO $ Internal.regionCreateRectangles a
+
+-- | Allocates a new region object copying the area from @original@.
+--
+regionCopy ::
+     MonadIO m =>
+     Region -- ^ @original@
+  -> m Region
+regionCopy a = liftIO $ Internal.regionCopy a
+
+-- | Gets the bounding rectangle of @region@ as a RectanglInt.
+--
+regionGetExtents ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> m RectangleInt
+regionGetExtents a = liftIO $ Internal.regionGetExtents a
+
+-- | Returns the number of rectangles contained in @region@.
+--
+regionNumRectangles ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> m Int
+regionNumRectangles a = liftIO $ Internal.regionNumRectangles a
+
+-- | Gets the @nth@ rectangle from the @region@.
+--
+regionGetRectangle ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> Int    -- ^ @nth@
+  -> m RectangleInt
+regionGetRectangle a n = liftIO $ Internal.regionGetRectangle a n
+
+-- | Checks whether @region@ is empty.
+--
+regionIsEmpty ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> m Bool
+regionIsEmpty a = liftIO $ Internal.regionIsEmpty a
+
+-- | Checks whether (@x@, @y@) is contained in @region@.
+--
+regionContainsPoint ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> Int    -- ^ @x@
+  -> Int    -- ^ @y@
+  -> m Bool
+regionContainsPoint a x y = liftIO $ Internal.regionContainsPoint a x y
+
+-- | Checks whether @rectangle@ is inside, outside or partially contained in @region@.
+--
+regionContainsRectangle ::
+     MonadIO m =>
+     Region       -- ^ @region@
+  -> RectangleInt -- ^ @rectangle@
+  -> m RegionOverlap
+regionContainsRectangle a rect = liftIO $ Internal.regionContainsRectangle a rect
+
+-- | Compares whether @region_a@ is equivalent to @region_b@.
+--
+regionEqual ::
+     MonadIO m =>
+     Region -- ^ @region_a@
+  -> Region -- ^ @region_b@
+  -> m Bool
+regionEqual a b = liftIO $ Internal.regionEqual a b
+
+-- | Translates @region@ by (@dx@, @dy@).
+--
+regionTranslate ::
+     MonadIO m =>
+     Region -- ^ @region@
+  -> Int    -- ^ @dx@
+  -> Int    -- ^ @dy@
+  -> m ()
+regionTranslate a dx dy = liftIO $ Internal.regionTranslate a dx dy
+
+-- | Computes the intersection of @dst@ with @other@ and places the result in @dst@.
+--
+regionIntersect ::
+     MonadIO m =>
+     Region -- ^ @dst@
+  -> Region -- ^ @other@
+  -> m ()
+regionIntersect a b = liftIO $ do
+  status <- Internal.regionIntersect a b
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Computes the intersection of @dst@ with @rectangle@ and places the result in @dst@.
+--
+regionIntersectRectangle ::
+     MonadIO m =>
+     Region       -- ^ @dst@
+  -> RectangleInt -- ^ @rectangle@
+  -> m ()
+regionIntersectRectangle a rect = liftIO $ do
+  status <- Internal.regionIntersectRectangle a rect
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Subtracts @other@ from @dst@ and places the result in @dst@.
+--
+regionSubtract ::
+     MonadIO m =>
+     Region -- ^ @dst@
+  -> Region -- ^ @other@
+  -> m ()
+regionSubtract a b = liftIO $ do
+  status <- Internal.regionSubtract a b
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Subtracts @rectangle@ from @dst@ and places the result in @dst@.
+--
+regionSubtractRectangle ::
+     MonadIO m =>
+     Region       -- ^ @dst@
+  -> RectangleInt -- ^ @rectangle@
+  -> m ()
+regionSubtractRectangle a rect = liftIO $ do
+  status <- Internal.regionSubtractRectangle a rect
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Computes the union of @dst@ with @other@ and places the result in @dst@.
+--
+regionUnion ::
+     MonadIO m =>
+     Region -- ^ @dst@
+  -> Region -- ^ @other@
+  -> m ()
+regionUnion a b = liftIO $ do
+  status <- Internal.regionUnion a b
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Computes the union of @dst@ with @rectangle@ and places the result in @dst@.
+--
+regionUnionRectangle ::
+     MonadIO m =>
+     Region       -- ^ @dst@
+  -> RectangleInt -- ^ @rectangle@
+  -> m ()
+regionUnionRectangle a rect = liftIO $ do
+  status <- Internal.regionUnionRectangle a rect
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Computes the exclusive difference of @dst@ with @other@ and places the result in @dst@.
+-- That is, @dst@ will be set to contain all areas that are either in @dst@ or in @other@, but not in both.
+--
+regionXor ::
+     MonadIO m =>
+     Region -- ^ @dst@
+  -> Region -- ^ @other@
+  -> m ()
+regionXor a b = liftIO $ do
+  status <- Internal.regionXor a b
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
+-- | Computes the exclusive difference of @dst@ with @rectangle@ and places the result in @dst@.
+-- That is, @dst@ will be set to contain all areas that are either in @dst@ or in @rectangle@, but not in both
+--
+regionXorRectangle ::
+     MonadIO m =>
+     Region       -- ^ @dst@
+  -> RectangleInt -- ^ @rectangle@
+  -> m ()
+regionXorRectangle a rect = liftIO $ do
+  status <- Internal.regionXorRectangle a rect
+  unless (status == StatusSuccess) $
+    Internal.statusToString status >>= fail
+
 #endif
 
 -- | Returns the version of the cairo library encoded in a single integer.
diff --git a/Graphics/Rendering/Cairo/Internal.hs b/Graphics/Rendering/Cairo/Internal.hs
--- a/Graphics/Rendering/Cairo/Internal.hs
+++ b/Graphics/Rendering/Cairo/Internal.hs
@@ -29,6 +29,7 @@
   , module Graphics.Rendering.Cairo.Internal.Surfaces.PS
   , module Graphics.Rendering.Cairo.Internal.Surfaces.SVG
   , module Graphics.Rendering.Cairo.Internal.Surfaces.Surface
+  , module Graphics.Rendering.Cairo.Internal.Region
   , module Graphics.Rendering.Cairo.Internal.Utilities
 
   ) where
@@ -46,6 +47,7 @@
 import Graphics.Rendering.Cairo.Internal.Surfaces.PS
 import Graphics.Rendering.Cairo.Internal.Surfaces.SVG
 import Graphics.Rendering.Cairo.Internal.Surfaces.Surface
+import Graphics.Rendering.Cairo.Internal.Region
 import Graphics.Rendering.Cairo.Internal.Utilities
 
 import Control.Monad.Reader
diff --git a/Graphics/Rendering/Cairo/Internal/Region.chs b/Graphics/Rendering/Cairo/Internal/Region.chs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/Cairo/Internal/Region.chs
@@ -0,0 +1,52 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.Cairo.Internal.Region
+-- Copyright   :  (c) Hamish Mackenzie 2013
+-- License     :  BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer  :
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Region functions.
+-----------------------------------------------------------------------------
+
+module Graphics.Rendering.Cairo.Internal.Region where
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+{#import Graphics.Rendering.Cairo.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+regionCreateRectangles rects =
+    withArrayLen rects $ \ n ptr ->
+        {#call region_create_rectangles#} ptr (fromIntegral n) >>= mkRegion
+
+{#fun region_create                 as regionCreate             {} -> `Region' mkRegion*#}
+{#fun region_create_rectangle       as regionCreateRectangle    { `RectangleInt' } -> `Region' mkRegion*#}
+{#fun region_copy                   as regionCopy               { withRegion* `Region' } -> `Region' mkRegion*#}
+{#fun region_destroy                as regionDestroy            { withRegion* `Region' } -> `()'#}
+{#fun region_reference              as regionReference          { withRegion* `Region' } -> `()'#}
+{#fun region_status                 as regionStatus             { withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_get_extents            as regionGetExtents         { withRegion* `Region', alloca- `RectangleInt' peek* } -> `()'#}
+{#fun region_num_rectangles         as regionNumRectangles      { withRegion* `Region' } -> `Int' fromIntegral#}
+{#fun region_get_rectangle          as regionGetRectangle       { withRegion* `Region', fromIntegral `Int', alloca- `RectangleInt' peek* } -> `()'#}
+{#fun region_is_empty               as regionIsEmpty            { withRegion* `Region' } -> `Bool' cToBool#}
+{#fun region_contains_point         as regionContainsPoint      { withRegion* `Region', fromIntegral `Int', fromIntegral `Int' } -> `Bool' cToBool#}
+{#fun region_contains_rectangle     as regionContainsRectangle  { withRegion* `Region', `RectangleInt' } -> `RegionOverlap' cToEnum#}
+{#fun region_equal                  as regionEqual              { withRegion* `Region', withRegion* `Region' } -> `Bool' cToBool#}
+{#fun region_translate              as regionTranslate          { withRegion* `Region', fromIntegral `Int', fromIntegral `Int' } -> `()'#}
+{#fun region_intersect              as regionIntersect          { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_intersect_rectangle    as regionIntersectRectangle { withRegion* `Region', `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_subtract               as regionSubtract           { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_subtract_rectangle     as regionSubtractRectangle  { withRegion* `Region', `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_union                  as regionUnion              { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_union_rectangle        as regionUnionRectangle     { withRegion* `Region', `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_xor                    as regionXor                { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_xor_rectangle          as regionXorRectangle       { withRegion* `Region', `RectangleInt' } -> `Status' cToEnum#}
+
+#endif
diff --git a/Graphics/Rendering/Cairo/Internal/Utilities.chs b/Graphics/Rendering/Cairo/Internal/Utilities.chs
--- a/Graphics/Rendering/Cairo/Internal/Utilities.chs
+++ b/Graphics/Rendering/Cairo/Internal/Utilities.chs
@@ -17,7 +17,11 @@
 
 import Foreign
 import Foreign.C
+#if __GLASGOW_HASKELL__ >= 707
+import System.IO.Unsafe (unsafePerformIO)
+#endif
 
+import Codec.Binary.UTF8.String
 import Data.Char (ord, chr)
 
 {#context lib="cairo" prefix="cairo"#}
@@ -26,23 +30,5 @@
 {#fun pure version        as version        {} -> `Int'#}
 {#fun pure version_string as versionString  {} -> `String'#}
 
--- These functions taken from System/Glib/UTFString.hs
--- Copyright (c) 1999..2002 Axel Simon
-
--- Define withUTFString to emit UTF-8.
---
 withUTFString :: String -> (CString -> IO a) -> IO a
-withUTFString hsStr = withCAString (toUTF hsStr)
- where
-    -- Convert Unicode characters to UTF-8.
-    --
-    toUTF :: String -> String
-    toUTF [] = []
-    toUTF (x:xs) | ord x<=0x007F = x:toUTF xs
-                 | ord x<=0x07FF = chr (0xC0 .|. ((ord x `shift` (-6)) .&. 0x1F)):
-                                   chr (0x80 .|. (ord x .&. 0x3F)):
-                                   toUTF xs
-                 | otherwise     = chr (0xE0 .|. ((ord x `shift` (-12)) .&. 0x0F)):
-                                   chr (0x80 .|. ((ord x `shift` (-6)) .&. 0x3F)):
-                                   chr (0x80 .|. (ord x .&. 0x3F)):
-                                   toUTF xs
+withUTFString = withCAString . encodeString
diff --git a/Graphics/Rendering/Cairo/Types.chs b/Graphics/Rendering/Cairo/Types.chs
--- a/Graphics/Rendering/Cairo/Types.chs
+++ b/Graphics/Rendering/Cairo/Types.chs
@@ -1,3 +1,4 @@
+{-# LANGUAGE RecordWildCards #-}
 {-# OPTIONS_HADDOCK hide #-}
 -----------------------------------------------------------------------------
 -- |
@@ -39,6 +40,11 @@
   , HintMetrics(..)
   , FontOptions(..), withFontOptions, mkFontOptions
   , Path(..), unPath
+#if CAIRO_CHECK_VERSION(1,10,0)
+  , RectangleInt(..)
+  , RegionOverlap(..)
+  , Region(..), withRegion, mkRegion
+#endif
   , Content(..)
   , Format(..)
   , Extend(..)
@@ -334,6 +340,54 @@
 --
 {#pointer *path_t as Path newtype#}
 unPath (Path x) = x
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+{#pointer *rectangle_int_t as RectangleIntPtr -> RectangleInt#}
+
+-- | A data structure for holding a rectangle with integer coordinates.
+data RectangleInt = RectangleInt {
+    x      :: Int
+  , y      :: Int
+  , width  :: Int
+  , height :: Int
+  }
+
+instance Storable RectangleInt where
+  sizeOf _ = {#sizeof rectangle_int_t#}
+  alignment _ = alignment (undefined :: CInt)
+  peek p = do
+    x      <- {#get rectangle_int_t->x#}      p
+    y      <- {#get rectangle_int_t->y#}      p
+    width  <- {#get rectangle_int_t->width#}  p
+    height <- {#get rectangle_int_t->height#} p
+    return $ RectangleInt (fromIntegral x) (fromIntegral y) (fromIntegral width) (fromIntegral height)
+  poke p (RectangleInt {..}) = do
+    {#set rectangle_int_t->x#}      p (fromIntegral x)
+    {#set rectangle_int_t->y#}      p (fromIntegral y)
+    {#set rectangle_int_t->width#}  p (fromIntegral width)
+    {#set rectangle_int_t->height#} p (fromIntegral height)
+    return ()
+
+-- | Used as the return value for regionContainsRectangle.
+{#enum cairo_region_overlap_t as RegionOverlap {underscoreToCase} deriving(Eq,Show)#}
+
+-- | A Cairo region. Represents a set of integer-aligned rectangles.
+--
+-- It allows set-theoretical operations like regionUnion and regionIntersect to be performed on them.
+{#pointer *region_t as Region foreign newtype#}
+
+withRegion (Region fptr) = withForeignPtr fptr
+
+mkRegion :: Ptr Region -> IO Region
+mkRegion regionPtr = do
+  regionForeignPtr <- newForeignPtr regionDestroy regionPtr
+  return (Region regionForeignPtr)
+
+foreign import ccall unsafe "&cairo_region_destroy"
+  regionDestroy :: FinalizerPtr Region
+
+#endif
 
 {#enum content_t as Content {underscoreToCase} deriving(Eq,Show)#}
 
diff --git a/Gtk2HsSetup.hs b/Gtk2HsSetup.hs
--- a/Gtk2HsSetup.hs
+++ b/Gtk2HsSetup.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP, ViewPatterns #-}
 
 #ifndef CABAL_VERSION_CHECK
 #error This module has to be compiled via the Setup.hs program which generates the gtk2hs-macros.h file
@@ -29,7 +29,7 @@
                                                emptyBuildInfo, allBuildInfo,
                                                Library(..),
                                                libModules, hasLibs)
-import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..),
+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(withPackageDB, buildDir, localPkgDescr, installedPkgs, withPrograms),
                                            InstallDirs(..),
                                            componentPackageDeps,
                                            absoluteInstallDirs)
@@ -56,14 +56,27 @@
 import Distribution.Verbosity
 import Control.Monad (when, unless, filterM, liftM, forM, forM_)
 import Data.Maybe ( isJust, isNothing, fromMaybe, maybeToList )
-import Data.List (isPrefixOf, isSuffixOf, nub, minimumBy)
+import Data.List (isPrefixOf, isSuffixOf, nub, minimumBy, stripPrefix)
 import Data.Ord as Ord (comparing)
-import Data.Char (isAlpha)
+import Data.Char (isAlpha, isNumber)
 import qualified Data.Map as M
 import qualified Data.Set as S
+import qualified Distribution.Simple.LocalBuildInfo as LBI
+import Distribution.Simple.Compiler (compilerVersion)
 
 import Control.Applicative ((<$>))
 
+#if CABAL_VERSION_CHECK(1,17,0)
+import Distribution.Simple.Program.Find ( defaultProgramSearchPath )
+onDefaultSearchPath f a b = f a b defaultProgramSearchPath
+libraryConfig lbi = case [clbi | (LBI.CLibName, clbi, _) <- LBI.componentsConfigs lbi] of
+  [clbi] -> Just clbi
+  _ -> Nothing
+#else
+onDefaultSearchPath = id
+libraryConfig = LBI.libraryConfig
+#endif
+
 -- the name of the c2hs pre-compiled header file
 precompFile = "precompchs.bin"
 
@@ -100,7 +113,7 @@
 
 fixLibs :: [FilePath] -> [String] -> [String]
 fixLibs dlls = concatMap $ \ lib ->
-    case filter (("lib" ++ lib) `isPrefixOf`) dlls of
+    case filter (isLib lib) dlls of
                 dlls@(_:_) -> [dropExtension (pickDll dlls)]
                 _          -> if lib == "z" then [] else [lib]
   where
@@ -111,7 +124,12 @@
     -- Yes this is a hack but the proper solution is hard: we would need to
     -- parse the .a file and see which .dll file(s) it needed to link to.
     pickDll = minimumBy (Ord.comparing length)
-
+    isLib lib dll =
+        case stripPrefix ("lib"++lib) dll of
+            Just ('.':_)                -> True
+            Just ('-':n:_) | isNumber n -> True
+            _                           -> False
+        
 -- The following code is a big copy-and-paste job from the sources of
 -- Cabal 1.8 just to be able to fix a field in the package file. Yuck.
 
@@ -144,8 +162,8 @@
 register :: PackageDescription -> LocalBuildInfo
          -> RegisterFlags -- ^Install in the user's database?; verbose
          -> IO ()
-register pkg@PackageDescription { library       = Just lib  }
-         lbi@LocalBuildInfo     { libraryConfig = Just clbi } regFlags
+register pkg@(library       -> Just lib )
+         lbi@(libraryConfig -> Just clbi) regFlags
   = do
 
     installedPkgInfoRaw <- generateRegistrationInfo
@@ -237,6 +255,10 @@
     = nub $
       ["-I" ++ dir | dir <- PD.includeDirs bi]
    ++ [opt | opt@('-':c:_) <- PD.cppOptions bi ++ PD.ccOptions bi, c `elem` "DIU"]
+   ++ ["-D__GLASGOW_HASKELL__="++show (ghcDefine . versionBranch . compilerVersion $ LBI.compiler lbi)]
+ where
+  ghcDefine (v1:v2:_) = v1 * 100 + v2
+  ghcDefine _ = __GLASGOW_HASKELL__
 
 installCHI :: PackageDescription -- ^information from the .cabal file
         -> LocalBuildInfo -- ^information from the configure step
@@ -426,7 +448,7 @@
 checkGtk2hsBuildtools :: [Program] -> IO ()
 checkGtk2hsBuildtools programs = do
   programInfos <- mapM (\ prog -> do
-                         location <- programFindLocation prog normal
+                         location <- onDefaultSearchPath programFindLocation prog normal
                          return (programName prog, location)
                       ) programs
   let printError name = do
diff --git a/SetupWrapper.hs b/SetupWrapper.hs
--- a/SetupWrapper.hs
+++ b/SetupWrapper.hs
@@ -29,6 +29,24 @@
 import Control.Monad
 
 
+-- moreRecentFile is implemented in Distribution.Simple.Utils, but only in
+-- Cabal >= 1.18. For backwards-compatibility, we implement a copy with a new
+-- name here. Some desirable alternate strategies don't work:
+-- * We can't use CPP to check which version of Cabal we're up against because
+--   this is the file that's generating the macros for doing that.
+-- * We can't use the name moreRecentFiles and use
+--   import D.S.U hiding (moreRecentFiles)
+--   because on old GHC's (and according to the Report) hiding a name that
+--   doesn't exist is an error.
+moreRecentFile' :: FilePath -> FilePath -> IO Bool
+moreRecentFile' a b = do
+  exists <- doesFileExist b
+  if not exists
+    then return True
+    else do tb <- getModificationTime b
+            ta <- getModificationTime a
+            return (ta > tb)
+
 setupWrapper :: FilePath -> IO ()
 setupWrapper setupHsFile = do
   args <- getArgs
@@ -91,8 +109,8 @@
     -- Currently this is GHC only. It should really be generalised.
     --
     compileSetupExecutable = do
-      setupHsNewer      <- setupHsFile      `moreRecentFile` setupProgFile
-      cabalVersionNewer <- setupVersionFile `moreRecentFile` setupProgFile
+      setupHsNewer      <- setupHsFile      `moreRecentFile'` setupProgFile
+      cabalVersionNewer <- setupVersionFile `moreRecentFile'` setupProgFile
       let outOfDate = setupHsNewer || cabalVersionNewer
       when outOfDate $ do
         debug verbosity "Setup script is out of date, compiling..."
@@ -144,12 +162,3 @@
                    Nothing Nothing Nothing
       exitCode <- waitForProcess process
       unless (exitCode == ExitSuccess) $ exitWith exitCode
-
-moreRecentFile :: FilePath -> FilePath -> IO Bool
-moreRecentFile a b = do
-  exists <- doesFileExist b
-  if not exists
-    then return True
-    else do tb <- getModificationTime b
-            ta <- getModificationTime a
-            return (ta > tb)
diff --git a/cairo.cabal b/cairo.cabal
--- a/cairo.cabal
+++ b/cairo.cabal
@@ -1,5 +1,5 @@
 Name:           cairo
-Version:        0.12.4
+Version:        0.12.5.0
 License:        BSD3
 License-file:   COPYRIGHT
 Copyright:      (c) 2001-2010 The Gtk2Hs Team, (c) Paolo Martini 2005, (c) Abraham Egnor 2003, 2004, (c) Aetion Technologies LLC 2004
@@ -31,8 +31,8 @@
                 Text.hs
 				
 Source-Repository head
-  type:         darcs
-  location:     http://code.haskell.org/gtk2hs/
+  type:         git
+  location:     https://github.com/gtk2hs/gtk2hs
   subdir:       cairo
 
 Flag cairo_pdf
@@ -46,8 +46,9 @@
   
 Library
         build-depends:  base >= 4 && < 5,
+                        utf8-string >= 0.2 && < 0.4,
                         bytestring, mtl, array
-        build-tools:    gtk2hsC2hs >= 0.13.5
+        build-tools:    gtk2hsC2hs >= 0.13.8
         exposed-modules:  Graphics.Rendering.Cairo
                           Graphics.Rendering.Cairo.Matrix
                           Graphics.Rendering.Cairo.Types
@@ -68,6 +69,7 @@
                           Graphics.Rendering.Cairo.Internal.Surfaces.PDF
                           Graphics.Rendering.Cairo.Internal.Surfaces.PS
                           Graphics.Rendering.Cairo.Internal.Surfaces.SVG
+                          Graphics.Rendering.Cairo.Internal.Region
         extensions:     ForeignFunctionInterface
         Include-dirs: .
         x-c2hs-Header:  cairo-gtk2hs.h
