    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.HGL.Draw.Pen
    -- Copyright   :  (c) Alastair Reid, 1999-2003
    -- License     :  BSD-style (see the file libraries/base/LICENSE)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  provisional
    -- Portability :  non-portable (requires concurrency)
    --
    -- Pens, used for drawing lines.
    --
    -- Portability notes:
    --
    -- * On Win32, the pen is also used to draw a line round all the filled
    --   shapes --- so the pen color also affects how polygons, ellipses
    --   and regions are drawn.
    --
    -- * On Win32, the 'Style' is ignored (i.e. treated as 'Solid') for pens
    --   of width greater than 1.  This problem does not apply to X11.
    --
    -----------------------------------------------------------------------------

    module Graphics.HGL.Draw.Pen
    	( Pen
    	, Style(Solid, Dash, Dot, DashDot, DashDotDot, Null, InsideFrame)
    	, createPen	-- :: Style -> Int -> RGB -> IO Pen
    	, deletePen
    	, selectPen	-- :: Pen -> Draw Pen
    	, mkPen		-- :: Style -> Int -> RGB -> (Pen -> Draw a) -> Draw a
    	) where

    import Graphics.HGL.Draw.Text (RGB)
    import Graphics.HGL.Draw.Monad (Draw, ioToDraw)
    import Graphics.HGL.Internals.Types (Style(..))
    import Graphics.HGL.Internals.Draw (mkDraw)

    #if !X_DISPLAY_MISSING
    import Graphics.HGL.X11.Types
    import Graphics.HGL.X11.Display
    import qualified Graphics.X11.Xlib as X
    import Control.Concurrent (takeMVar, putMVar)
    #else
    import Graphics.HGL.Win32.Types
    import qualified Graphics.Win32 as Win32
    import Graphics.HGL.Draw.Monad (bracket)
    #endif

    ----------------------------------------------------------------
    #if X_DISPLAY_MISSING
    newtype Pen = Pen Win32.HPEN
    #endif

    -- | Create a 'Pen'.
    createPen :: Style -> Int -> RGB -> IO Pen

    -- | Destroy a 'Pen' created with 'createPen'.
    deletePen :: Pen -> IO ()

    -- | Set the 'Pen' for subsequent drawing, returning the previous setting.
    selectPen :: Pen -> Draw Pen

    -- | Create a 'Pen' locally to a drawing.
    mkPen     :: Style -> Int -> RGB -> (Pen -> Draw a) -> Draw a
    ----------------------------------------------------------------

    #if !X_DISPLAY_MISSING

    ----------------------------------------------------------------
    -- Pens
    --
    -- Used to draw lines and boundaries of filled shapes
    ----------------------------------------------------------------

    createPen style width col = do
      display <- getDisplay
      pixel <- lookupColor display col
      return (Pen style width pixel)

    deletePen _ = return ()

    -- ToDo: how do I set background colour for brush and pen?
    selectPen p@(Pen _ lwidth c) = mkDraw $ \ dc -> do
      bs <- takeMVar (ref_bits dc)
      putMVar (ref_bits dc) bs{pen=p}
      X.setForeground (disp dc) (paintGC dc) c
      X.setLineAttributes (disp dc) (paintGC dc) (fromIntegral lwidth) X.lineSolid X.capButt X.joinMiter
      return (pen bs)

    mkPen style width color g = do
      p <- ioToDraw $ createPen style width color
      g p

    #else /* X_DISPLAY_MISSING */

    style :: Style -> Win32.PenStyle
    style Solid       = Win32.pS_SOLID
    style Dash	  = Win32.pS_DASH
    style Dot	  = Win32.pS_DOT
    style DashDot	  = Win32.pS_DASHDOT
    style DashDotDot  = Win32.pS_DASHDOTDOT
    style Null	  = Win32.pS_NULL
    style InsideFrame = Win32.pS_INSIDEFRAME

    createPen sty width c =
      Win32.createPen (style sty) (fromIntegral width) (fromRGB c) >>= return . Pen

    deletePen (Pen pen) =
      Win32.deletePen pen

    selectPen (Pen p) = mkDraw (\hdc -> do
      p' <- Win32.selectPen hdc p
      return (Pen p'))

    mkPen sty width c =
      bracket (ioToDraw $ createPen sty width c)
              (ioToDraw . deletePen)

    #endif /* X_DISPLAY_MISSING */

    ----------------------------------------------------------------
    -- The end
    ----------------------------------------------------------------