diff --git a/Graphics/X11/Types.hsc b/Graphics/X11/Types.hsc
--- a/Graphics/X11/Types.hsc
+++ b/Graphics/X11/Types.hsc
@@ -28,6 +28,12 @@
         Colormap,
         GContext,
         KeyCode,
+        SizeID,
+        SubpixelOrder,
+        Connection,
+        RROutput,
+        RRCrtc,
+        RRMode,
 
         -- * Enumeration types
         -- | These types were introduced to make function types clearer.
@@ -423,6 +429,10 @@
         propertyChangeMask,
         colormapChangeMask,
         ownerGrabButtonMask,
+        rrScreenChangeNotifyMask,
+        rrCrtcChangeNotifyMask,
+        rrOutputChangeNotifyMask,
+        rrOutputPropertyNotifyMask,
 
         -- ** Event types
         EventType,
@@ -459,6 +469,11 @@
         colormapNotify,
         clientMessage,
         mappingNotify,
+        rrScreenChangeNotify,
+        rrNotify,
+        rrNotifyCrtcChange,
+        rrNotifyOutputChange,
+        rrNotifyOutputProperty,
         lASTEvent,
 
         -- ** Modifiers
@@ -475,6 +490,7 @@
 
         -- ** Key masks
         KeyMask,
+        noModMask,
         shiftMask,
         lockMask,
         controlMask,
@@ -799,7 +815,17 @@
         ImageFormat,
         xyBitmap,
         xyPixmap,
-        zPixmap
+        zPixmap,
+
+        -- ** Reflection and Rotation
+        Rotation,
+        Reflection,
+        xRR_Rotate_0,
+        xRR_Rotate_90,
+        xRR_Rotate_180,
+        xRR_Rotate_270,
+        xRR_Reflect_X,
+        xRR_Reflect_Y
         ) where
 
 -- import Data.Int
@@ -1254,6 +1280,10 @@
  , propertyChangeMask           = PropertyChangeMask
  , colormapChangeMask           = ColormapChangeMask
  , ownerGrabButtonMask          = OwnerGrabButtonMask
+ , rrScreenChangeNotifyMask     = RRScreenChangeNotifyMask
+ , rrCrtcChangeNotifyMask       = RRCrtcChangeNotifyMask
+ , rrOutputChangeNotifyMask     = RROutputChangeNotifyMask
+ , rrOutputPropertyNotifyMask   = RROutputPropertyNotifyMask
  }
 
 type EventType          = Word32
@@ -1291,6 +1321,11 @@
  , colormapNotify       = ColormapNotify
  , clientMessage        = ClientMessage
  , mappingNotify        = MappingNotify
+ , rrScreenChangeNotify = RRScreenChangeNotify
+ , rrNotify             = RRNotify
+ , rrNotifyCrtcChange   = RRNotify_CrtcChange
+ , rrNotifyOutputChange = RRNotify_OutputChange
+ , rrNotifyOutputProperty=RRNotify_OutputProperty
  , lASTEvent            = LASTEvent
  }
 
@@ -1309,6 +1344,7 @@
 
 type KeyMask            = Modifier
 #{enum KeyMask,
+ , noModMask            = 0
  , shiftMask            = ShiftMask
  , lockMask             = LockMask
  , controlMask          = ControlMask
@@ -1718,3 +1754,26 @@
  , xyPixmap     = XYPixmap
  , zPixmap      = ZPixmap
  }
+
+-- Xrandr types
+type Rotation      = #{type Rotation}
+type Reflection    = #{type Rotation}
+type SizeID        = #{type SizeID}
+type SubpixelOrder = #{type SubpixelOrder}
+type Connection    = #{type Connection}
+type RROutput      = #{type RROutput}
+type RRCrtc        = #{type RRCrtc}
+type RRMode        = #{type RRMode}
+
+#{enum Rotation,
+  , xRR_Rotate_0   = RR_Rotate_0
+  , xRR_Rotate_90  = RR_Rotate_90
+  , xRR_Rotate_180 = RR_Rotate_180
+  , xRR_Rotate_270 = RR_Rotate_270
+  }
+
+#{enum Reflection,
+  , xRR_Reflect_X = RR_Reflect_X
+  , xRR_Reflect_Y = RR_Reflect_Y
+  }
+
diff --git a/Graphics/X11/Xlib/Event.hsc b/Graphics/X11/Xlib/Event.hsc
--- a/Graphics/X11/Xlib/Event.hsc
+++ b/Graphics/X11/Xlib/Event.hsc
@@ -388,6 +388,7 @@
 -- -- getSelectionClearEvent omitted
 -- -- getSelectionRequestEvent omitted
 -- -- getSelectionEvent omitted
+-- -- xrrScreenChangeNotifyEvent omitted
 
 -- functions
 
diff --git a/Graphics/X11/Xlib/Extras.hsc b/Graphics/X11/Xlib/Extras.hsc
--- a/Graphics/X11/Xlib/Extras.hsc
+++ b/Graphics/X11/Xlib/Extras.hsc
@@ -13,7 +13,9 @@
 
 module Graphics.X11.Xlib.Extras where
 
+import Data.Maybe
 import Data.Typeable ( Typeable )
+import Graphics.X11.Xrandr
 import Graphics.X11.Xlib
 import Graphics.X11.Xlib.Types
 import Graphics.X11.Xlib.Misc
@@ -212,6 +214,72 @@
         , ev_message_type          :: !Atom
         , ev_data                  :: ![CInt]
         }
+    | RRScreenChangeNotifyEvent
+        { ev_event_type            :: !EventType
+        , ev_serial                :: !CULong
+        , ev_send_event            :: !Bool
+        , ev_event_display         :: Display
+        , ev_window                :: !Window
+        , ev_root                  :: !Window
+        , ev_timestamp             :: !Time
+        , ev_config_timestamp      :: !Time
+        , ev_size_index            :: !SizeID
+        , ev_subpixel_order        :: !SubpixelOrder
+        , ev_rotation              :: !Rotation
+        , ev_width                 :: !CInt
+        , ev_height                :: !CInt
+        , ev_mwidth                :: !CInt
+        , ev_mheight               :: !CInt
+        }
+    | RRNotifyEvent
+        { ev_event_type            :: !EventType
+        , ev_serial                :: !CULong
+        , ev_send_event            :: !Bool
+        , ev_event_display         :: Display
+        , ev_window                :: !Window
+        , ev_subtype               :: !CInt
+        }
+    | RRCrtcChangeNotifyEvent
+        { ev_event_type            :: !EventType
+        , ev_serial                :: !CULong
+        , ev_send_event            :: !Bool
+        , ev_event_display         :: Display
+        , ev_window                :: !Window
+        , ev_subtype               :: !CInt
+        , ev_crtc                  :: !RRCrtc
+        , ev_rr_mode               :: !RRMode
+        , ev_rotation              :: !Rotation
+        , ev_x                     :: !CInt
+        , ev_y                     :: !CInt
+        , ev_rr_width              :: !CUInt
+        , ev_rr_height             :: !CUInt
+        }
+    | RROutputChangeNotifyEvent
+        { ev_event_type            :: !EventType
+        , ev_serial                :: !CULong
+        , ev_send_event            :: !Bool
+        , ev_event_display         :: Display
+        , ev_window                :: !Window
+        , ev_subtype               :: !CInt
+        , ev_output                :: !RROutput
+        , ev_crtc                  :: !RRCrtc
+        , ev_rr_mode               :: !RRMode
+        , ev_rotation              :: !Rotation
+        , ev_connection            :: !Connection
+        , ev_subpixel_order        :: !SubpixelOrder
+        }
+    | RROutputPropertyNotifyEvent
+        { ev_event_type            :: !EventType
+        , ev_serial                :: !CULong
+        , ev_send_event            :: !Bool
+        , ev_event_display         :: Display
+        , ev_window                :: !Window
+        , ev_subtype               :: !CInt
+        , ev_output                :: !RROutput
+        , ev_property              :: !Atom
+        , ev_timestamp             :: !Time
+        , ev_rr_state              :: !CInt
+        }
 
     deriving ( Show, Typeable )
 
@@ -265,6 +333,9 @@
     serial     <- #{peek XAnyEvent, serial} p
     send_event <- #{peek XAnyEvent, send_event} p
     display    <- fmap Display (#{peek XAnyEvent, display} p)
+    rrData     <- xrrQueryExtension display
+    let rrHasExtension = isJust rrData
+    let rrEventBase    = fromIntegral $ fst $ fromMaybe (0, 0) rrData
     case () of
 
         -------------------------
@@ -601,7 +672,7 @@
                         16 -> do a <- peekArray 10 datPtr
                                  return $ map fromIntegral (a::[Word16])
                         32 -> do a <- peekArray 5 datPtr
-                                 return $ map fromIntegral (a::[Word32])
+                                 return $ map fromIntegral (a::[CLong])
                         _  -> error "X11.Extras.clientMessage: illegal value"
             return $ ClientMessageEvent
                         { ev_event_type    = type_
@@ -613,6 +684,125 @@
                         , ev_data          = dat
                         }
 
+          -------------------------
+          -- RRScreenChangeNotify
+          -------------------------
+          | rrHasExtension &&
+            type_ == rrEventBase + rrScreenChangeNotify -> do
+            window           <- #{peek XRRScreenChangeNotifyEvent, window           } p
+            root             <- #{peek XRRScreenChangeNotifyEvent, root             } p
+            timestamp        <- #{peek XRRScreenChangeNotifyEvent, timestamp        } p
+            config_timestamp <- #{peek XRRScreenChangeNotifyEvent, config_timestamp } p
+            size_index       <- #{peek XRRScreenChangeNotifyEvent, config_timestamp } p
+            subpixel_order   <- #{peek XRRScreenChangeNotifyEvent, subpixel_order   } p
+            rotation         <- #{peek XRRScreenChangeNotifyEvent, rotation         } p
+            width            <- #{peek XRRScreenChangeNotifyEvent, width            } p
+            height           <- #{peek XRRScreenChangeNotifyEvent, height           } p
+            mwidth           <- #{peek XRRScreenChangeNotifyEvent, mwidth           } p
+            mheight          <- #{peek XRRScreenChangeNotifyEvent, mheight          } p
+            return $ RRScreenChangeNotifyEvent
+                        { ev_event_type       = type_
+                        , ev_serial           = serial
+                        , ev_send_event       = send_event
+                        , ev_event_display    = display
+                        , ev_window           = window
+                        , ev_root             = root
+                        , ev_timestamp        = timestamp
+                        , ev_config_timestamp = config_timestamp
+                        , ev_size_index       = size_index
+                        , ev_subpixel_order   = subpixel_order
+                        , ev_rotation         = rotation
+                        , ev_width            = width
+                        , ev_height           = height
+                        , ev_mwidth           = mwidth
+                        , ev_mheight          = mheight
+                        }
+
+          -------------------------
+          -- RRNotify
+          -------------------------
+          | rrHasExtension &&
+            type_ == rrEventBase + rrNotify -> do
+            window   <- #{peek XRRNotifyEvent, window  } p
+            subtype  <- #{peek XRRNotifyEvent, subtype } p
+            let subtype_ = fromIntegral subtype_
+            case () of
+                _ | subtype_ == rrNotifyCrtcChange -> do
+                    crtc           <- #{peek XRRCrtcChangeNotifyEvent, crtc     } p
+                    mode           <- #{peek XRRCrtcChangeNotifyEvent, mode     } p
+                    rotation       <- #{peek XRRCrtcChangeNotifyEvent, rotation } p
+                    x              <- #{peek XRRCrtcChangeNotifyEvent, x        } p
+                    y              <- #{peek XRRCrtcChangeNotifyEvent, y        } p
+                    width          <- #{peek XRRCrtcChangeNotifyEvent, width    } p
+                    height         <- #{peek XRRCrtcChangeNotifyEvent, height   } p
+                    return $ RRCrtcChangeNotifyEvent
+                             { ev_event_type    = type_
+                             , ev_serial        = serial
+                             , ev_send_event    = send_event
+                             , ev_event_display = display
+                             , ev_window        = window
+                             , ev_subtype       = subtype
+                             , ev_crtc          = crtc
+                             , ev_rr_mode       = mode
+                             , ev_rotation      = rotation
+                             , ev_x             = x
+                             , ev_y             = y
+                             , ev_rr_width      = width
+                             , ev_rr_height     = height
+                             }
+
+                  | subtype_ == rrNotifyOutputChange -> do
+                    output         <- #{peek XRROutputChangeNotifyEvent, output         } p
+                    crtc           <- #{peek XRROutputChangeNotifyEvent, crtc           } p
+                    mode           <- #{peek XRROutputChangeNotifyEvent, mode           } p
+                    rotation       <- #{peek XRROutputChangeNotifyEvent, rotation       } p
+                    connection     <- #{peek XRROutputChangeNotifyEvent, connection     } p
+                    subpixel_order <- #{peek XRROutputChangeNotifyEvent, subpixel_order } p
+                    return $ RROutputChangeNotifyEvent
+                             { ev_event_type     = type_
+                             , ev_serial         = serial
+                             , ev_send_event     = send_event
+                             , ev_event_display  = display
+                             , ev_window         = window
+                             , ev_subtype        = subtype
+                             , ev_output         = output
+                             , ev_crtc           = crtc
+                             , ev_rr_mode        = mode
+                             , ev_rotation       = rotation
+                             , ev_connection     = connection
+                             , ev_subpixel_order = subpixel_order
+                             }
+
+                  | subtype_ == rrNotifyOutputProperty -> do
+                    output         <- #{peek XRROutputPropertyNotifyEvent, output    } p
+                    property       <- #{peek XRROutputPropertyNotifyEvent, property  } p
+                    timestamp      <- #{peek XRROutputPropertyNotifyEvent, timestamp } p
+                    state          <- #{peek XRROutputPropertyNotifyEvent, state     } p
+                    return $ RROutputPropertyNotifyEvent
+                             { ev_event_type    = type_
+                             , ev_serial        = serial
+                             , ev_send_event    = send_event
+                             , ev_event_display = display
+                             , ev_window        = window
+                             , ev_subtype       = subtype
+                             , ev_output        = output
+                             , ev_property      = property
+                             , ev_timestamp     = timestamp
+                             , ev_rr_state      = state
+                             }
+
+                  -- We don't handle this event specifically, so return the generic
+                  -- RRNotifyEvent.
+                  | otherwise -> do
+                    return $ RRNotifyEvent
+                                { ev_event_type    = type_
+                                , ev_serial        = serial
+                                , ev_send_event    = send_event
+                                , ev_event_display = display
+                                , ev_window        = window
+                                , ev_subtype       = subtype
+                                }
+
           -- We don't handle this event specifically, so return the generic
           -- AnyEvent.
           | otherwise -> do
@@ -1224,8 +1414,10 @@
     = alloca $ \sh -> do
         alloca $ \supplied_return -> do
           -- what's the purpose of supplied_return?
-          xGetWMNormalHints d w sh supplied_return
-          peek sh
+          status <- xGetWMNormalHints d w sh supplied_return
+          case status of
+            0 -> return (SizeHints Nothing Nothing Nothing Nothing Nothing Nothing)
+            _ -> peek sh
 
 
 data ClassHint = ClassHint
diff --git a/Graphics/X11/Xrandr.hsc b/Graphics/X11/Xrandr.hsc
new file mode 100644
--- /dev/null
+++ b/Graphics/X11/Xrandr.hsc
@@ -0,0 +1,268 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+--------------------------------------------------------------------
+-- |
+-- Module    : Graphics.X11.Xrandr
+-- Copyright : (c) Haskell.org, 2012
+-- License   : BSD3
+--
+-- Maintainer: Ben Boeckel <mathstuf@gmail.com>
+-- Stability : provisional
+-- Portability: portable
+--
+--------------------------------------------------------------------
+--
+-- Interface to Xrandr API
+--
+
+module Graphics.X11.Xrandr (
+  XRRScreenSize(..),
+  compiledWithXrandr,
+  Rotation,
+  Reflection,
+  SizeID,
+  XRRScreenConfiguration,
+  xrrQueryExtension,
+  xrrQueryVersion,
+  xrrGetScreenInfo,
+  xrrFreeScreenConfigInfo,
+  xrrSetScreenConfig,
+  xrrSetScreenConfigAndRate,
+  xrrConfigRotations,
+  xrrConfigTimes,
+  xrrConfigSizes,
+  xrrConfigRates,
+  xrrConfigCurrentConfiguration,
+  xrrConfigCurrentRate,
+  xrrRootToScreen,
+  xrrSelectInput,
+  xrrUpdateConfiguration,
+  xrrRotations,
+  xrrSizes,
+  xrrRates,
+  xrrTimes
+ ) where
+
+import Foreign
+import Foreign.C.Types
+import Control.Monad
+
+import Graphics.X11.Xlib.Event
+import Graphics.X11.Xlib.Types
+import Graphics.X11.Types
+
+#if __GLASGOW_HASKELL__
+import Data.Generics
+#endif
+
+-- | Representation of the XRRScreenSize struct
+data XRRScreenSize = XRRScreenSize
+                     { xrr_ss_width   :: !CInt,
+                       xrr_ss_height  :: !CInt,
+                       xrr_ss_mwidth  :: !CInt,
+                       xrr_ss_mheight :: !CInt }
+                       deriving (Show)
+
+-- We have Xinerama, so the library will actually work
+compiledWithXrandr :: Bool
+compiledWithXrandr = True
+
+#include "HsXlib.h"
+
+newtype XRRScreenConfiguration = XRRScreenConfiguration (Ptr XRRScreenConfiguration)
+#if __GLASGOW_HASKELL__
+        deriving (Eq, Ord, Show, Typeable, Data)
+#else
+        deriving (Eq, Ord, Show)
+#endif
+
+instance Storable XRRScreenSize where
+  sizeOf _ = #{size XRRScreenSize}
+  -- FIXME: Is this right?
+  alignment _ = alignment (undefined :: CInt)
+
+  poke p xrr_ss = do
+    #{poke XRRScreenSize, width   } p $ xrr_ss_width xrr_ss
+    #{poke XRRScreenSize, height  } p $ xrr_ss_height xrr_ss
+    #{poke XRRScreenSize, mwidth  } p $ xrr_ss_mwidth xrr_ss
+    #{poke XRRScreenSize, mheight } p $ xrr_ss_mheight xrr_ss
+
+  peek p = return XRRScreenSize
+            `ap` (#{peek XRRScreenSize, width} p)
+            `ap` (#{peek XRRScreenSize, height} p)
+            `ap` (#{peek XRRScreenSize, mwidth} p)
+            `ap` (#{peek XRRScreenSize, mheight} p)
+
+xrrQueryExtension :: Display -> IO (Maybe (CInt, CInt))
+xrrQueryExtension dpy = wrapPtr2 (cXRRQueryExtension dpy) go
+  where go False _ _                = Nothing
+        go True eventbase errorbase = Just (fromIntegral eventbase, fromIntegral errorbase)
+foreign import ccall "XRRQueryExtension"
+  cXRRQueryExtension :: Display -> Ptr CInt -> Ptr CInt -> IO Bool
+
+xrrQueryVersion :: Display -> IO (Maybe (CInt, CInt))
+xrrQueryVersion dpy = wrapPtr2 (cXRRQueryVersion dpy) go
+  where go False _ _        = Nothing
+        go True major minor = Just (fromIntegral major, fromIntegral minor)
+foreign import ccall "XRRQueryVersion"
+  cXRRQueryVersion :: Display -> Ptr CInt -> Ptr CInt -> IO Bool
+
+xrrGetScreenInfo :: Display -> Drawable -> IO (Maybe XRRScreenConfiguration)
+xrrGetScreenInfo dpy draw = do
+  p <- cXRRGetScreenInfo dpy draw
+  if p == nullPtr
+     then return Nothing
+     else return (Just (XRRScreenConfiguration p))
+foreign import ccall "XRRGetScreenInfo"
+  cXRRGetScreenInfo :: Display -> Drawable -> IO (Ptr XRRScreenConfiguration)
+
+xrrFreeScreenConfigInfo :: XRRScreenConfiguration -> IO ()
+xrrFreeScreenConfigInfo = cXRRFreeScreenConfigInfo
+foreign import ccall "XRRFreeScreenConfigInfo"
+  cXRRFreeScreenConfigInfo :: XRRScreenConfiguration -> IO ()
+
+xrrSetScreenConfig :: Display -> XRRScreenConfiguration -> Drawable -> CInt -> Rotation -> Time -> IO Status
+xrrSetScreenConfig = cXRRSetScreenConfig
+foreign import ccall "XRRSetScreenConfig"
+  cXRRSetScreenConfig :: Display -> XRRScreenConfiguration -> Drawable -> CInt -> Rotation -> Time -> IO Status
+
+xrrSetScreenConfigAndRate :: Display -> XRRScreenConfiguration -> Drawable -> CInt -> Rotation -> CShort -> Time -> IO Status
+xrrSetScreenConfigAndRate = cXRRSetScreenConfigAndRate
+foreign import ccall "XRRSetScreenConfigAndRate"
+  cXRRSetScreenConfigAndRate :: Display -> XRRScreenConfiguration -> Drawable -> CInt -> Rotation -> CShort -> Time -> IO Status
+
+xrrConfigRotations :: XRRScreenConfiguration -> IO (Rotation, Rotation)
+xrrConfigRotations config =
+  withPool $ \pool -> do rptr <- pooledMalloc pool
+                         rotations <- cXRRConfigRotations config rptr
+                         cur_rotation <- peek rptr
+                         return (rotations, cur_rotation)
+foreign import ccall "XRRConfigRotations"
+  cXRRConfigRotations :: XRRScreenConfiguration -> Ptr Rotation -> IO Rotation
+
+xrrConfigTimes :: XRRScreenConfiguration -> IO (Time, Time)
+xrrConfigTimes config =
+  withPool $ \pool -> do tptr <- pooledMalloc pool
+                         time <- cXRRConfigTimes config tptr
+                         cur_time <- peek tptr
+                         return (time, cur_time)
+foreign import ccall "XRRConfigTimes"
+  cXRRConfigTimes :: XRRScreenConfiguration -> Ptr Time -> IO Time
+
+xrrConfigSizes :: XRRScreenConfiguration -> IO (Maybe [XRRScreenSize])
+xrrConfigSizes config =
+  withPool $ \pool -> do intp <- pooledMalloc pool
+                         p <- cXRRConfigSizes config intp
+                         if p == nullPtr
+                            then return Nothing
+                            else do nsizes <- peek intp
+                                    sizes <- if nsizes == 0
+                                                then return Nothing
+                                                else peekArray (fromIntegral nsizes) p >>= return . Just
+                                    cXFree p
+                                    return sizes
+foreign import ccall "XRRConfigSizes"
+  cXRRConfigSizes :: XRRScreenConfiguration -> Ptr CInt -> IO (Ptr XRRScreenSize)
+
+xrrConfigRates :: XRRScreenConfiguration -> CInt -> IO (Maybe [CShort])
+xrrConfigRates config size_index =
+  withPool $ \pool -> do intp <- pooledMalloc pool
+                         p <- cXRRConfigRates config size_index intp
+                         if p == nullPtr
+                            then return Nothing
+                            else do nrates <- peek intp
+                                    rates <- if nrates == 0
+                                                then return Nothing
+                                                else peekArray (fromIntegral nrates) p >>= return . Just
+                                    cXFree p
+                                    return rates
+foreign import ccall "XRRConfigRates"
+  cXRRConfigRates :: XRRScreenConfiguration -> CInt -> Ptr CInt -> IO (Ptr CShort)
+
+xrrConfigCurrentConfiguration :: XRRScreenConfiguration -> IO (Rotation, SizeID)
+xrrConfigCurrentConfiguration config =
+  withPool $ \pool -> do rptr <- pooledMalloc pool
+                         sizeid <- cXRRConfigCurrentConfiguration config rptr
+                         rotation <- peek rptr
+                         return (rotation, sizeid)
+foreign import ccall "XRRConfigCurrentConfiguration"
+  cXRRConfigCurrentConfiguration :: XRRScreenConfiguration -> Ptr Rotation -> IO SizeID
+
+xrrConfigCurrentRate :: XRRScreenConfiguration -> IO CShort
+xrrConfigCurrentRate = cXRRConfigCurrentRate
+foreign import ccall "XRRConfigCurrentRate"
+  cXRRConfigCurrentRate :: XRRScreenConfiguration -> IO CShort
+
+xrrRootToScreen :: Display -> Window -> IO CInt
+xrrRootToScreen = cXRRRootToScreen
+foreign import ccall "XRRRootToScreen"
+  cXRRRootToScreen :: Display -> Window -> IO CInt
+
+xrrSelectInput :: Display -> Window -> EventMask -> IO ()
+xrrSelectInput dpy window mask = cXRRSelectInput dpy window (fromIntegral mask)
+foreign import ccall "XRRSelectInput"
+  cXRRSelectInput :: Display -> Window -> CInt -> IO ()
+
+xrrUpdateConfiguration :: XEvent -> IO CInt
+xrrUpdateConfiguration = cXRRUpdateConfiguration
+foreign import ccall "XRRUpdateConfiguration"
+  cXRRUpdateConfiguration :: XEvent -> IO CInt
+
+xrrRotations :: Display -> CInt -> IO (Rotation, Rotation)
+xrrRotations dpy screen =
+  withPool $ \pool -> do rptr <- pooledMalloc pool
+                         rotations <- cXRRRotations dpy screen rptr
+                         cur_rotation <- peek rptr
+                         return (rotations, cur_rotation)
+foreign import ccall "XRRRotations"
+  cXRRRotations :: Display -> CInt -> Ptr Rotation -> IO Rotation
+
+xrrSizes :: Display -> CInt -> IO (Maybe [XRRScreenSize])
+xrrSizes dpy screen =
+  withPool $ \pool -> do intp <- pooledMalloc pool
+                         p <- cXRRSizes dpy screen intp
+                         if p == nullPtr
+                            then return Nothing
+                            else do nsizes <- peek intp
+                                    sizes <- if nsizes == 0
+                                                then return Nothing
+                                                else peekArray (fromIntegral nsizes) p >>= return . Just
+                                    cXFree p
+                                    return sizes
+foreign import ccall "XRRSizes"
+  cXRRSizes :: Display -> CInt -> Ptr CInt -> IO (Ptr XRRScreenSize)
+
+xrrRates :: Display -> CInt -> CInt -> IO (Maybe [CShort])
+xrrRates dpy screen size_index =
+  withPool $ \pool -> do intp <- pooledMalloc pool
+                         p <- cXRRRates dpy screen size_index intp
+                         if p == nullPtr
+                            then return Nothing
+                            else do nrates <- peek intp
+                                    rates <- if nrates == 0
+                                                then return Nothing
+                                                else peekArray (fromIntegral nrates) p >>= return . Just
+                                    cXFree p
+                                    return rates
+foreign import ccall "XRRRates"
+  cXRRRates :: Display -> CInt -> CInt -> Ptr CInt -> IO (Ptr CShort)
+
+xrrTimes :: Display -> CInt -> IO (Time, Time)
+xrrTimes dpy screen =
+  withPool $ \pool -> do tptr <- pooledMalloc pool
+                         time <- cXRRTimes dpy screen tptr
+                         config_time <- peek tptr
+                         return (time, config_time)
+foreign import ccall "XRRTimes"
+  cXRRTimes :: Display -> CInt -> Ptr Time -> IO Time
+
+foreign import ccall "XFree"
+  cXFree :: Ptr a -> IO CInt
+
+wrapPtr2 :: (Storable a, Storable b) => (Ptr a -> Ptr b -> IO c) -> (c -> a -> b -> d) -> IO d
+wrapPtr2 cfun f =
+  withPool $ \pool -> do aptr <- pooledMalloc pool
+                         bptr <- pooledMalloc pool
+                         ret <- cfun aptr bptr
+                         a <- peek aptr
+                         b <- peek bptr
+                         return (f ret a b)
diff --git a/X11.cabal b/X11.cabal
--- a/X11.cabal
+++ b/X11.cabal
@@ -1,8 +1,8 @@
 name:               X11
-version:            1.5.0.1
+version:            1.6.0
 license:            BSD3
 license-file:       LICENSE
-copyright:          Alastair Reid, 1999-2003, libraries@haskell.org 2003-2007, Don Stewart 2007-2009, Spencer Janssen 2007-2009.
+copyright:          Alastair Reid, 1999-2003, libraries@haskell.org 2003-2007, Don Stewart 2007-2009, Spencer Janssen 2007-2009, Daniel Wagner 2009-2011.
 maintainer:         Daniel Wagner <daniel@wagner-home.com>
 homepage:           https://github.com/haskell-pkg-janitors/X11
 category:           Graphics
@@ -46,6 +46,7 @@
       Graphics.X11.Xlib.Image,
       Graphics.X11.Xlib.Extras,
       Graphics.X11.Xinerama
+      Graphics.X11.Xrandr
       Graphics.X11.ExtraTypes,
       Graphics.X11.ExtraTypes.AP,
       Graphics.X11.ExtraTypes.DEC,
@@ -58,7 +59,7 @@
       cbits/auxiliaries.c,
       cbits/XUtils.c
   extensions:         ForeignFunctionInterface, CPP
-  extra-libraries:    "X11"
+  extra-libraries:    "X11", "Xrandr", "Xext"
   include-dirs:       include
   includes:           HsXlib.h, HsAllKeysyms.h
   install-includes:   HsXlib.h, XlibExtras.h, HsAllKeysyms.h
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,11 @@
     echo "WARNING: Building without Xinerama support per user request"
 fi
 
+AC_CHECK_HEADERS([X11/extensions/Xrandr.h], [have_xrandr=yes])
+if ! test "$have_xrandr" = yes; then
+    AC_MSG_ERROR([X11/extensions/Xrandr.h (from libXrandr) is required])
+fi
+
 AC_MSG_CHECKING([whether to include X.org keysyms])
 AC_ARG_WITH(xorg-keysym,
             AS_HELP_STRING([--without-xorg-keysym], [do not build X.org keysym support]),
diff --git a/include/HsXlib.h b/include/HsXlib.h
--- a/include/HsXlib.h
+++ b/include/HsXlib.h
@@ -18,6 +18,8 @@
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
 
+#include <X11/extensions/Xrandr.h>
+
 /* Xutil.h overrides some functions with macros.
  * In recent versions of X this can be turned off with
  *
diff --git a/include/XlibExtras.h b/include/XlibExtras.h
--- a/include/XlibExtras.h
+++ b/include/XlibExtras.h
@@ -17,6 +17,8 @@
 #include <X11/Xutil.h>
 #include <X11/Xproto.h>
 
+#include <X11/extensions/Xrandr.h>
+
 /* Xutil.h overrides some functions with macros.
  * In recent versions of X this can be turned off with
  *      #define XUTIL_DEFINE_FUNCTIONS
