    -- GENERATED by C->Haskell Compiler, version 0.28.1 Switcheroo, 1 April 2016 (Haskell)
    -- Edit the ORIGNAL .chs file instead!

    {-# LINE 1 "lib/UI/NCurses.chs" #-}
    {-# LANGUAGE ForeignFunctionInterface #-}

    -- Copyright (C) 2010 John Millikin <jmillikin@gmail.com>
    --
    -- This program is free software: you can redistribute it and/or modify
    -- it under the terms of the GNU General Public License as published by
    -- the Free Software Foundation, either version 3 of the License, or
    -- any later version.
    --
    -- This program is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -- GNU General Public License for more details.
    --
    -- You should have received a copy of the GNU General Public License
    -- along with this program.  If not, see <http://www.gnu.org/licenses/>.

    module UI.NCurses
    	(
    	-- * Primary types
    	  Curses
    	, Update
    	, Window
    	, CursesException

    	-- * Initialization
    	, runCurses
    	, defaultWindow

    	-- * Window management
    	, newWindow
    	, closeWindow
    	, cloneWindow
    	, moveWindow
    	, windowPosition
    	, resizeWindow
    	, windowSize
    	, updateWindow

    	-- ** Copying window content
    	, OverlayMode(..)
    	, overlay
    	, copyWindow

    	-- ** Virtual windows (pads)
    	, Pad
    	, newPad
    	, closePad
    	, updatePad

    	-- * The cursor
    	, moveCursor
    	, cursorPosition
    	, getCursor

    	-- * Drawing to the screen
    	, render
    	, setColor
    	, drawString
    	, drawText
    	, drawGlyph
    	, drawBorder
    	, drawBox
    	, drawLineH
    	, drawLineV
    	, clear
    	, clearLine
    	, setBackground

    	-- * Attributes
    	, Attribute (..)
    	, setAttribute
    	, setAttributes

    	-- * Colors
    	, Color (..)
    	, maxColor
    	, ColorID
    	, supportsColor
    	, canDefineColor
    	, defineColor
    	, queryColor
    	, defaultColorID
    	, newColorID
    	, setColorID
    	, maxColorID

    	-- * Glyphs
    	, Glyph (..)

    	-- ** VT100 drawing glyphs
    	, glyphCornerUL
    	, glyphCornerLL
    	, glyphCornerUR
    	, glyphCornerLR
    	, glyphTeeL
    	, glyphTeeR
    	, glyphTeeB
    	, glyphTeeT
    	, glyphLineH
    	, glyphLineV
    	, glyphPlus
    	, glyphScan1
    	, glyphScan9
    	, glyphDiamond
    	, glyphStipple
    	, glyphDegree
    	, glyphPlusMinus
    	, glyphBullet

    	-- ** Teletype 5410v1 symbols
    	, glyphArrowL
    	, glyphArrowR
    	, glyphArrowD
    	, glyphArrowU
    	, glyphBoard
    	, glyphLantern
    	, glyphBlock

    	-- ** Other glyphs
    	, glyphS3
    	, glyphS7
    	, glyphNE
    	, glyphLTE
    	, glyphGTE
    	, glyphPi
    	, glyphSterling

    	-- * Event handling
    	, Event (..)
    	, getEvent

    	-- ** Keyboard events
    	, Key (..)

    	-- ** Mouse events
    	, ButtonState (..)
    	, MouseState (..)

    	-- * Cursor mode
    	, CursorMode(CursorInvisible, CursorVisible, CursorVeryVisible)
    	, setCursorMode

    	-- * Error handling
    	, tryCurses
    	, catchCurses
    	, throwCurses

    	-- * misc
    	, setRaw
    	, setCBreak
    	, setEcho
    	, baudrate
    	, beep
    	, flash
    	, hasMouse
    	, enclosed
    	, screenSize
    	, setTouched
    	, setRowsTouched
    	, setKeypad
    	, resizeTerminal
    	) where
    import qualified Foreign.C.Types as C2HSImp
    import qualified Foreign.Ptr as C2HSImp
    import qualified Foreign.Storable as C2HSImp
    import qualified System.IO.Unsafe as C2HSImp

    import           Control.Exception (bracket_, catch, throwIO, try)
    import           Control.Monad (when, unless)
    import qualified Control.Monad.Trans.Reader as R
    import           Data.Char (chr, ord)
    import           Data.List (foldl')
    import           Data.Maybe (catMaybes)
    import qualified Data.Map as M
    import qualified Data.Text as T
    import           Foreign hiding (shift, void)
    import           Foreign.C

    import qualified UI.NCurses.Enums as E
    import           UI.NCurses.Compat
    import           UI.NCurses.Types

    -- Note: c2hs has a hard time with the ncurses macros, and will choke on
    -- waddwstr() if NCURSES_NOMACROS is not defined prior to including
    -- ncurses.h in this file.
    --
    -- Transitive includes from hsncurses-shim.h are not sufficient.

    {-# LINE 198 "lib/UI/NCurses.chs" #-}

    newtype CCharT = CCharT (C2HSImp.Ptr (CCharT))
    {-# LINE 199 "lib/UI/NCurses.chs" #-}

    {-# LINE 200 "lib/UI/NCurses.chs" #-}

    type AttrT = (C2HSImp.CULong)
    {-# LINE 202 "lib/UI/NCurses.chs" #-}

    type MMaskT = (C2HSImp.CULong)
    {-# LINE 203 "lib/UI/NCurses.chs" #-}

    -- | Put the terminal in graphical mode, including enabling special keys,
    -- colors, and mouse events (if supported).
    --
    -- After the 'Curses' block has finished running, the terminal is reset
    -- to text mode.
    runCurses :: Curses a -> IO a
    runCurses = bracket_ initCurses endwin . unCurses where
    	allEvents = fromInteger (E.fromEnum E.ALL_MOUSE_EVENTS)
    	initCurses = do
    		void initscr
    {-# LINE 214 "lib/UI/NCurses.chs" #-}

    		void cbreak
    {-# LINE 215 "lib/UI/NCurses.chs" #-}

    		void $ mousemask allEvents nullPtr
    		hasColor <- has_colors
    {-# LINE 217 "lib/UI/NCurses.chs" #-}

    		when (hasColor == 1) $ do
    			void start_color
    {-# LINE 219 "lib/UI/NCurses.chs" #-}

    			void use_default_colors
    {-# LINE 220 "lib/UI/NCurses.chs" #-}

    		stdscr <- peek c_stdscr
    		void $ keypad (Window stdscr) 1
    		void $ meta (Window stdscr) 1
    		wtimeout (Window stdscr) (- 1)

    -- | The default window created when @ncurses@ is initialized, also known
    -- as @stdscr@.
    defaultWindow :: Curses Window
    defaultWindow = Curses (Window `fmap` peek c_stdscr)

    foreign import ccall "static &stdscr"
    	c_stdscr :: Ptr (Ptr Window)

    -- | Create a new 'Window', with the given dimensions. To create a
    -- fullscreen window, use @'newWindow' 0 0 0 0@.
    --
    -- When the window is no longer needed, call 'closeWindow'. Windows are not
    -- garbage&#x2013;collected, because there&#x2019;s no way to know if
    -- they&#x2019;re still in use (as a background, or event source, etc).
    newWindow :: Integer -- ^ Rows
              -> Integer -- ^ Columns
              -> Integer -- ^ Begin Y
              -> Integer -- ^ Begin X
              -> Curses Window
    newWindow rows cols x y = Curses $ do
    	win <- newwin
    {-# LINE 246 "lib/UI/NCurses.chs" #-}

    		(fromInteger rows)
    		(fromInteger cols)
    		(fromInteger x)
    		(fromInteger y)
    	if windowPtr win == nullPtr
    		then throwIO (CursesException "newWindow: newwin() returned NULL")
    		else do
    			void $ keypad win 1
    			void $ meta win 1
    			wtimeout win (- 1)
    			return win

    -- | Close a window, and free all resources associated with it. Once a
    -- window has been closed, it is no longer safe to use.
    --
    -- Note: this computation will not automatically clear the window from the
    -- screen.
    closeWindow :: Window -> Curses ()
    closeWindow win = Curses (delwin win >>= checkRC "closeWindow")

    -- | Create a separate window, initialised with the state of an existing
    -- window.
    cloneWindow :: Window -> Curses Window
    cloneWindow old = Curses $ do
    	win <- dupwin old
    	if windowPtr win == nullPtr
    		then throwIO (CursesException "cloneWindow: dupwin() returned NULL")
    		else return win

    -- | Apply a window update to the window. After all of an
    -- application&#x2019;s windows have been updated, call 'render' to update
    -- the terminal&#x2019;s contents.
    updateWindow :: Window -> Update a -> Curses a
    updateWindow win (Update reader) = do
    	a <- R.runReaderT reader win
    	Curses (wnoutrefresh win >>= checkRC "updateWindow")
    	return a

    -- | Moves the window to the given (row,column) coordinate.
    moveWindow :: Integer -> Integer -> Update ()
    moveWindow row col = withWindow_ "moveWindow"  $ \win ->
    	mvwin win (fromInteger row) (fromInteger col)

    -- | Returns the current (row, column) coordinates of the window.
    windowPosition :: Update (Integer, Integer)
    windowPosition = withWindow $ \win -> do
    	row <- getbegy win
    	col <- getbegx win
    	return (toInteger row, toInteger col)

    -- | Resizes the window to the given row and column dimensions.
    resizeWindow :: Integer -> Integer -> Update ()
    resizeWindow rows cols = withWindow_ "resizeWindow"  $ \win ->
    	wresize win (fromInteger rows) (fromInteger cols)

    -- Returns the current (row, column) dimensions of the window.
    windowSize :: Update (Integer, Integer)
    windowSize = withWindow $ \win -> do
    	rows <- getmaxy win
    	cols <- getmaxx win
    	return (toInteger rows, toInteger cols)

    data OverlayMode
    	-- | Overlay only non-blank characters.
    	= OverlayMerge
    	-- | Overlay all characters, including blanks.
    	| OverlayReplace
    	deriving (Show, Eq)

    -- | Overlay the entire content of another window onto this window.
    --
    -- The overlay mode specifies whether to copy blank characters.
    --
    -- Use 'copyWindow' if precise control over coordinates is required.
    overlay :: Window -> OverlayMode -> Update ()
    overlay src mode = withWindow_ "overlay" $ \dst -> case mode of
    	OverlayMerge -> c_overlay src dst
    	OverlayReplace -> overwrite src dst

    -- | Overlay a region of another window onto this window.
    --
    -- Use 'overlay' for copying the entire area of a window.
    copyWindow :: Window
               -> OverlayMode -- Whether to copy blank characters.
               -> Integer -- Top-most row of the source window's overlay region (sminrow).
               -> Integer -- Left-most column of the source window's overlay region (smincol).
               -> Integer -- Top-most row of the destination window's overlay region (dminrow).
               -> Integer -- Left-most column of the destination window's overlay region (dmincol).
               -> Integer -- Bottom-most row of the destination window's overlay region (dmaxrow).
               -> Integer -- Right-most column of the destination window's overlay region (dmaxcol).
               -> Update ()
    copyWindow src mode sminrow smincol dminrow dmincol dmaxrow dmaxcol = withWindow_ "copyWindow" $ \dst -> do
    	copywin src dst
    		(fromInteger sminrow)
    		(fromInteger smincol)
    		(fromInteger dminrow)
    		(fromInteger dmincol)
    		(fromInteger dmaxrow)
    		(fromInteger dmaxcol)
    		(cFromBool (mode == OverlayReplace))

    -- | A Pad is a 'Window' that is not associated with the screen.
    newtype Pad = Pad Window

    -- | Create a new 'Pad' with the given dimensions.
    --
    -- When the pad is no longer needed, call 'closePad'. Pads are not
    -- garbage&#x2013;collected, because there&#x2019;s no way to know if
    -- they&#x2019;re still in use.
    newPad :: Integer -- ^ Rows
           -> Integer -- ^ Columns
           -> Curses Pad
    newPad rows cols = Curses $ do
    	win <- newpad
    {-# LINE 360 "lib/UI/NCurses.chs" #-}

    		(fromInteger rows)
    		(fromInteger cols)
    	if windowPtr win == nullPtr
    		then throwIO (CursesException "newPad: newpad() returned NULL")
    		else do
    			void $ keypad win 1
    			void $ meta win 1
    			wtimeout win (- 1)
    			return (Pad win)

    -- | Close a pad, and free all resources associated with it. Once a
    -- pad has been closed, it is no longer safe to use.
    closePad :: Pad -> Curses ()
    closePad (Pad win) = Curses (delwin win >>= checkRC "closePad")

    updatePad :: Pad
              -> Integer -- Top-most row of the pad's update region (pminrow).
              -> Integer -- Left-most column of the pad's update region (pmincol).
              -> Integer -- Top-most row of the screen's update region (sminrow).
              -> Integer -- Left-most column of the screen's update region (smincol).
              -> Integer -- Bottom-most row of the screen's update region (smaxrow).
              -> Integer -- Right-most column of the screen's update region (smaxcol).
              -> Update a
              -> Curses a
    updatePad (Pad win) pminrow pmincol sminrow smincol smaxrow smaxcol (Update reader) = do
    	a <- R.runReaderT reader win
    	Curses $
    		(pnoutrefresh win
    			(fromInteger pminrow)
    			(fromInteger pmincol)
    			(fromInteger sminrow)
    			(fromInteger smincol)
    			(fromInteger smaxrow)
    			(fromInteger smaxcol))
    		>>= checkRC "updatePad"
    	return a

    -- | Move the window&#x2019;s cursor position to the given row and column.
    moveCursor :: Integer -- ^ Row
               -> Integer -- ^ Column
               -> Update ()
    moveCursor row col = withWindow_ "moveCursor" $ \win ->
    	wmove win (fromInteger row) (fromInteger col)

    -- | Returns the current (row,column) coordinates of the cursor.
    --
    -- This is the same as 'getCursor', but is usable within an Update.
    cursorPosition :: Update (Integer, Integer)
    cursorPosition = withWindow $ \win -> do
    	row <- getcury win
    	col <- getcurx win
    	return (toInteger row, toInteger col)

    -- | Return current cursor position as (row, column).
    --
    -- This is the same as 'cursorPosition', but is usable outside
    -- of an Update.
    getCursor :: Window -> Curses (Integer, Integer)
    getCursor win = Curses $ do
    	row <- getcury win
    	col <- getcurx win
    	return (toInteger row, toInteger col)

    -- | Re&#x2013;draw any portions of the screen which have changed since the
    -- last render.
    render :: Curses ()
    render = Curses (doupdate >>= checkRC "render")

    -- | Set the current foreground and background colors. See 'newColorID'
    -- for how to create color IDs.
    setColor :: ColorID -> Update ()
    setColor (ColorID pair) = withWindow_ "setColor" $ \win ->
    	wcolor_set win pair nullPtr

    -- | Add some text to the window, at the current cursor position.
    drawString :: String -> Update ()
    drawString str = withWindow_ "drawString" $ \win ->
    	withCWString str (waddwstr win)

    -- | Add some text to the window, at the current cursor position.
    drawText :: T.Text -> Update ()
    drawText txt = withWindow_ "drawText" $ \win ->
    	withCWString (T.unpack txt) (waddwstr win)

    drawGlyph :: Glyph -> Update ()
    drawGlyph glyph = withWindow_ "drawGlyph" $ \win ->
    	withGlyph glyph $ \pGlyph ->
    	wadd_wch win pGlyph

    -- | Draw a border around the edge of the window. For any edge, passing
    -- 'Nothing' means to use the default glyph.
    drawBorder :: Maybe Glyph -- ^ Left edge
               -> Maybe Glyph -- ^ Right edge
               -> Maybe Glyph -- ^ Top edge
               -> Maybe Glyph -- ^ Bottom edge
               -> Maybe Glyph -- ^ Top left corner
               -> Maybe Glyph -- ^ Top right corner
               -> Maybe Glyph -- ^ Bottom left corner
               -> Maybe Glyph -- ^ Bottom right corner
               -> Update ()
    drawBorder le re te be tl tr bl br =
    	withWindow_ "drawBorder" $ \win ->
    	withMaybeGlyph le $ \pLE ->
    	withMaybeGlyph re $ \pRE ->
    	withMaybeGlyph te $ \pTE ->
    	withMaybeGlyph be $ \pBE ->
    	withMaybeGlyph tl $ \pTL ->
    	withMaybeGlyph tr $ \pTR ->
    	withMaybeGlyph bl $ \pBL ->
    	withMaybeGlyph br $ \pBR ->
    	wborder_set win pLE pRE pTE pBE pTL pTR pBL pBR

    -- | @drawBox v h = drawBorder v v h h Nothing Nothing Nothing Nothing@
    drawBox :: Maybe Glyph -> Maybe Glyph -> Update ()
    drawBox v h = drawBorder v v h h Nothing Nothing Nothing Nothing

    -- | Draw a horizontal line from left to right, using the given glyph and
    -- maximum character count. The cursor position is not changed.
    drawLineH :: Maybe Glyph -> Integer -> Update ()
    drawLineH g n = withWindow_ "drawLineH" $ \win ->
    	withMaybeGlyph g $ \pChar ->
    	whline_set win pChar (fromInteger n)

    -- | Draw a vertical line from top to bottom, using the given glyph and
    -- maximum character count. The cursor position is not changed.
    drawLineV :: Maybe Glyph -> Integer -> Update ()
    drawLineV g n = withWindow_ "drawLineV" $ \win ->
    	withMaybeGlyph g $ \pChar ->
    	wvline_set win pChar (fromInteger n)

    -- | Clear the window content by drawing blanks to every position.
    clear :: Update ()
    clear = withWindow_ "clear" wclear
    {-# LINE 493 "lib/UI/NCurses.chs" #-}

    -- | Clear the current line starting from the current cursor position
    -- (inclusive) to the end of the line.
    clearLine :: Update ()
    clearLine = withWindow_ "clear" wclrtoeol
    {-# LINE 498 "lib/UI/NCurses.chs" #-}

    -- | Set the window&#x2019;s background glyph. The glyph will be drawn in
    -- place of any blank characters, and the glyph&#x2019;s attributes will be
    -- combined with those of every character.
    setBackground :: Glyph -> Update ()
    setBackground g = withWindow_ "setBackground" $ \win ->
    	withMaybeGlyph (Just g) $ \pChar ->
    	wbkgrndset win pChar >> return 0

    data Attribute
    	= AttributeColor ColorID -- ^ A_COLOR
    	| AttributeStandout -- ^ A_STANDOUT
    	| AttributeUnderline -- ^ A_UNDERLINE
    	| AttributeReverse -- ^ A_REVERSE
    	| AttributeBlink -- ^ A_BLINK
    	| AttributeDim -- ^ A_DIM
    	| AttributeBold -- ^ A_BOLD
    	| AttributeAltCharset -- ^ A_ALTCHARSET
    	| AttributeInvisible -- ^ A_INVISIBLE
    	| AttributeProtect -- ^ A_PROTECT
    	| AttributeHorizontal -- ^ A_HORIZONTAL
    	| AttributeLeft -- ^ A_LEFT
    	| AttributeLow -- ^ A_LOW
    	| AttributeRight -- ^ A_RIGHT
    	| AttributeTop -- ^ A_TOP
    	| AttributeVertical -- ^ A_VERTICAL
    	deriving (Show, Eq)

    attrEnum :: E.Attribute -> AttrT
    attrEnum = fromInteger . E.fromEnum

    attrToInt :: Attribute -> AttrT
    attrToInt x = case x of
    	AttributeStandout    -> attrEnum E.WA_STANDOUT
    	AttributeUnderline   -> attrEnum E.WA_UNDERLINE
    	AttributeReverse     -> attrEnum E.WA_REVERSE
    	AttributeBlink       -> attrEnum E.WA_BLINK
    	AttributeDim         -> attrEnum E.WA_DIM
    	AttributeBold        -> attrEnum E.WA_BOLD
    	AttributeAltCharset  -> attrEnum E.WA_ALTCHARSET
    	AttributeInvisible   -> attrEnum E.WA_INVIS
    	AttributeProtect     -> attrEnum E.WA_PROTECT
    	AttributeHorizontal  -> attrEnum E.WA_HORIZONTAL
    	AttributeLeft        -> attrEnum E.WA_LEFT
    	AttributeLow         -> attrEnum E.WA_LOW
    	AttributeRight       -> attrEnum E.WA_RIGHT
    	AttributeTop         -> attrEnum E.WA_TOP
    	AttributeVertical    -> attrEnum E.WA_VERTICAL

    	-- Colors get special handling: the function COLOR_PAIR converts an
    	-- NCURSES_PAIRS_T to an attr_t.
    	AttributeColor (ColorID cid) -> fromIntegral ((\ x1 -> C2HSImp.unsafePerformIO (c_COLOR_PAIR x1)) (fromIntegral cid))

    -- | Set a single 'Attribute' on the current window. No other attributes
    -- are modified.
    setAttribute :: Attribute -> Bool -> Update ()
    setAttribute attr on = withWindow_ "setAttribute" $ \win ->
    	let c = if on then wattr_on else wattr_off in
    	c win (attrToInt attr) nullPtr

    -- | Set all 'Attribute's at once on the current window. Any attributes not
    -- included in the list will be unset.
    setAttributes :: [Attribute] -> Update ()
    setAttributes attrs = withWindow_ "setAttributes" $ \win ->
    	let cint = foldl' (\acc a -> acc .|. attrToInt a) 0 attrs in
    	alloca $ \pPair -> do
    	wattr_get win nullPtr pPair nullPtr >>= checkRC "setAttributes"
    	colorPair <- peek pPair
    	wattr_set win cint colorPair nullPtr

    data Color
    	= ColorBlack
    	| ColorRed
    	| ColorGreen
    	| ColorYellow
    	| ColorBlue
    	| ColorMagenta
    	| ColorCyan
    	| ColorWhite

    	-- | An unspecified default terminal color, for terminals that support
    	-- ISO/IEC 6429 escape sequences (or equivalent).
    	--
    	-- This is most useful for terminals with translucent backgrounds.
    	| ColorDefault

    	-- | A color outside of the standard COLOR_* enum space, for terminals
    	-- that support more than eight colors.
    	--
    	-- Color-related functions may fail if a Color is provided that cannot
    	-- be supported by the current terminal. Users are responsible for
    	-- checking 'maxColor' when using extended colors.
    	| Color Int16
    	deriving (Show, Eq)

    -- Get the maximum 'Color' supported by the current terminal.
    maxColor :: Curses Integer
    maxColor = Curses $ do
    	count <- toInteger `fmap` peek c_COLORS
    	return (count - 1)

    foreign import ccall "static &COLORS"
    	c_COLORS :: Ptr CInt

    -- | A wrapper around 'Integer' to ensure clients don&#x2019;t use an
    -- uninitialized color in an attribute.
    newtype ColorID = ColorID CShort
    	deriving (Show, Eq)

    colorEnum :: E.Color -> CShort
    colorEnum = fromInteger . E.fromEnum

    colorToShort :: Color -> CShort
    colorToShort x = case x of
    	Color n      -> CShort n
    	ColorBlack   -> colorEnum E.COLOR_BLACK
    	ColorRed     -> colorEnum E.COLOR_RED
    	ColorGreen   -> colorEnum E.COLOR_GREEN
    	ColorYellow  -> colorEnum E.COLOR_YELLOW
    	ColorBlue    -> colorEnum E.COLOR_BLUE
    	ColorMagenta -> colorEnum E.COLOR_MAGENTA
    	ColorCyan    -> colorEnum E.COLOR_CYAN
    	ColorWhite   -> colorEnum E.COLOR_WHITE
    	ColorDefault -> colorEnum E.COLOR_DEFAULT

    -- | Check if the terminal supports color. If it doesn&#x2019;t,
    -- alternative indicators (such as underlines or bold) should be used.
    supportsColor :: Curses Bool
    supportsColor = Curses (fmap cToBool has_colors)

    -- | Check if the terminal supports changing color defintiions.
    canDefineColor :: Curses Bool
    canDefineColor = Curses (fmap cToBool can_change_color)

    -- | Change the definition of an existing color. Use 'canDefineColor' to
    -- determine whether changing color values is possible.
    defineColor :: Color
                -> Integer -- ^ Red (0 &#x2013; 1000)
                -> Integer -- ^ Green (0 &#x2013; 1000)
                -> Integer -- ^ Blue (0 &#x2013; 1000)
                -> Curses ()
    defineColor c r g b = Curses $ do
    	rc <- init_color
    {-# LINE 642 "lib/UI/NCurses.chs" #-}

    		(colorToShort c)
    		(fromInteger r)
    		(fromInteger g)
    		(fromInteger b)
    	checkRC "defineColor" rc

    -- | Query the current definition of the given color (see 'defineColor').
    -- The returned tuple is (red, green, blue), with values 0 &#x2013; 1000.
    queryColor :: Color -> Curses (Integer, Integer, Integer)
    queryColor c = Curses $
    	alloca $ \pRed ->
    	alloca $ \pGreen ->
    	alloca $ \pBlue -> do
    		rc <- color_content (colorToShort c) pRed pGreen pBlue
    		checkRC "queryColor" rc
    		red <- fmap toInteger (peek pRed)
    		green <- fmap toInteger (peek pGreen)
    		blue <- fmap toInteger (peek pBlue)
    		return (red, green, blue)

    -- | The default color ID
    defaultColorID :: ColorID
    defaultColorID = ColorID 0

    -- | Assign a new 'ColorID' to some (foreground, background) color pair.
    -- The user may pick which color ID is assigned, but it must be valid. Use
    -- 'maxColorID' to determine how many colors the current terminal supports.
    newColorID :: Color -- ^ Foreground
               -> Color -- ^ Background
               -> Integer -- ^ A value /n/, such that
                          -- (0 < /n/ &#x2264; 'maxColorID')
               -> Curses ColorID
    newColorID fg bg n = Curses $ do
    	unless (n > 0) $ throwIO (CursesException "newColorID: n must be > 0")
    	maxColor <- unCurses maxColorID
    	unless (n <= maxColor) $ throwIO (CursesException "newColorID: n must be <= maxColorID")
    	checkRC "newColorID" =<< init_pair
    {-# LINE 679 "lib/UI/NCurses.chs" #-}

    		(fromInteger n)
    		(colorToShort fg)
    		(colorToShort bg)
    	return (ColorID (fromInteger n))

    -- Change the definition of an existing 'ColorID'
    setColorID :: Color -- ^ Foreground
               -> Color -- ^ Background
               -> ColorID -- ^ The 'ColorID' to change
               -> Curses ()
    setColorID fg bg (ColorID n) = Curses $
    	checkRC "setColorID" =<< init_pair n
    		(colorToShort fg)
    		(colorToShort bg)

    -- | Get the maximum color ID supported by the current terminal
    maxColorID :: Curses Integer
    maxColorID = Curses $ do
    	pairs <- toInteger `fmap` peek c_COLOR_PAIRS
    	return (pairs - 1)

    foreign import ccall "static &COLOR_PAIRS"
    	c_COLOR_PAIRS :: Ptr CInt

    -- | A glyph is a character, typically spacing, combined with a set of
    -- attributes.
    data Glyph = Glyph
    	{ glyphCharacter :: Char
    	, glyphAttributes :: [Attribute]
    	}
    	deriving (Show, Eq)

    withMaybeGlyph :: Maybe Glyph -> (CCharT -> IO a) -> IO a
    withMaybeGlyph Nothing io = io (CCharT nullPtr)
    withMaybeGlyph (Just g) io = withGlyph g io

    withGlyph :: Glyph -> (CCharT -> IO a) -> IO a
    withGlyph (Glyph char attrs) io =
    	let cAttrs = foldl' (\acc a -> acc .|. attrToInt a) 0 attrs in
    	withCWStringLen [char] $ \(cChars, cCharsLen) ->
    	allocaBytes 32 $ \pBuf -> do
    	hsncurses_init_cchar_t (CCharT pBuf) cAttrs cChars (fromIntegral cCharsLen)
    	io (CCharT pBuf)

    -- | Upper left corner
    glyphCornerUL :: Glyph
    glyphCornerUL = Glyph '\x250C' []

    -- | Lower left corner
    glyphCornerLL :: Glyph
    glyphCornerLL = Glyph '\x2514' []

    -- | Upper right corner
    glyphCornerUR :: Glyph
    glyphCornerUR = Glyph '\x2510' []

    -- | Lower right corner
    glyphCornerLR :: Glyph
    glyphCornerLR = Glyph '\x2518' []

    -- | Tee pointing right
    glyphTeeL :: Glyph
    glyphTeeL = Glyph '\x251C' []

    -- | Tee pointing left
    glyphTeeR :: Glyph
    glyphTeeR = Glyph '\x2524' []

    -- | Tee pointing up
    glyphTeeB :: Glyph
    glyphTeeB = Glyph '\x2534' []

    -- | Tee pointing down
    glyphTeeT :: Glyph
    glyphTeeT = Glyph '\x252C' []

    -- | Horizontal line
    glyphLineH :: Glyph
    glyphLineH = Glyph '\x2500' []

    -- | Vertical line
    glyphLineV :: Glyph
    glyphLineV = Glyph '\x2502' []

    -- | Large plus or crossover
    glyphPlus :: Glyph
    glyphPlus = Glyph '\x253C' []

    -- | Scan line 1
    glyphScan1 :: Glyph
    glyphScan1 = Glyph '\x23BA' []

    -- | Scan line 9
    glyphScan9 :: Glyph
    glyphScan9 = Glyph '\x23BD' []

    -- | Diamond
    glyphDiamond :: Glyph
    glyphDiamond = Glyph '\x25C6' []

    -- | Stipple, or checker board
    glyphStipple :: Glyph
    glyphStipple = Glyph '\x2592' []

    -- | Degree symbol
    glyphDegree :: Glyph
    glyphDegree = Glyph '\xb0' []

    -- | Plus/minus
    glyphPlusMinus :: Glyph
    glyphPlusMinus = Glyph '\xb1' []

    -- | Bullet
    glyphBullet :: Glyph
    glyphBullet = Glyph '\xb7' []

    -- | Arrow pointing left
    glyphArrowL :: Glyph
    glyphArrowL = Glyph '\x2190' []

    -- | Arrow pointing right
    glyphArrowR :: Glyph
    glyphArrowR = Glyph '\x2192' []

    -- | Arrow pointing down
    glyphArrowD :: Glyph
    glyphArrowD = Glyph '\x2193' []

    -- | Arrow pointing up
    glyphArrowU :: Glyph
    glyphArrowU = Glyph '\x2191' []

    -- | Board of squares
    glyphBoard :: Glyph
    glyphBoard = Glyph '\x2592' []

    -- | Lantern symbol
    glyphLantern :: Glyph
    glyphLantern = Glyph '\x2603' []

    -- | Solid square block
    glyphBlock :: Glyph
    glyphBlock = Glyph '\x25AE' []

    -- | Scan line 3
    glyphS3 :: Glyph
    glyphS3 = Glyph '\x23BB' []

    -- | Scan line 7
    glyphS7 :: Glyph
    glyphS7 = Glyph '\x23BC' []

    -- | Not equal
    glyphNE :: Glyph
    glyphNE = Glyph '\x2260' []

    -- | Less than or equal
    glyphLTE :: Glyph
    glyphLTE = Glyph '\x2264' []

    -- | Greater than or equal
    glyphGTE :: Glyph
    glyphGTE = Glyph '\x2265' []

    -- | Pi
    glyphPi :: Glyph
    glyphPi = Glyph '\x3c0' []

    -- | UK pounds sterling symbol
    glyphSterling :: Glyph
    glyphSterling = Glyph '\xa3' []

    data Event
    	= EventCharacter Char
    	| EventSpecialKey Key
    	| EventMouse Integer MouseState
    	| EventResized
    	| EventUnknown Integer
    	deriving (Show, Eq)

    -- | Get the next 'Event' from a given window.
    --
    -- If the timeout is 'Nothing', @getEvent@ blocks until an event is received.
    --
    -- If the timeout is specified, @getEvent@ blocks for up to that many
    -- milliseconds. If no event is received before timing out, @getEvent@ returns
    -- 'Nothing'.
    --
    -- If the timeout is 0 or less, @getEvent@ will not block at all.
    getEvent :: Window
             -> Maybe Integer -- ^ Timeout, in milliseconds
             -> Curses (Maybe Event)
    getEvent win timeout = Curses io where
    	io = alloca $ \ptr -> do
    		wtimeout win $ case timeout of
    			Nothing -> -1
    			Just n | n <= 0 -> 0
    			Just n -> fromInteger n
    		rc <- hsncurses_wget_wch win ptr
    		if toInteger rc == E.fromEnum E.ERR
    			then return Nothing
    			else fmap Just (parseCode ptr rc)

    	parseCode ptr rc = do
    		code <- toInteger `fmap` peek ptr
    		if rc == 0
    			then return (charEvent code)
    			else if code == E.fromEnum E.KEY_MOUSE
    				then mouseEvent
    				else if code == E.fromEnum E.KEY_RESIZE
    					then return EventResized
    					else keyEvent code

    	charEvent = EventCharacter . chr . fromInteger

    	mouseEvent = allocaBytes 24 $ \pEv -> do
    		getmouse pEv >>= checkRC "getEvent"
    		evID <- fmap toInteger ((\ptr -> do {C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CShort}) pEv)
    		x <- fmap toInteger ((\ptr -> do {C2HSImp.peekByteOff ptr 4 :: IO C2HSImp.CInt}) pEv)
    		y <- fmap toInteger ((\ptr -> do {C2HSImp.peekByteOff ptr 8 :: IO C2HSImp.CInt}) pEv)
    		z <- fmap toInteger ((\ptr -> do {C2HSImp.peekByteOff ptr 12 :: IO C2HSImp.CInt}) pEv)

    		mask <- (\ptr -> do {C2HSImp.peekByteOff ptr 16 :: IO C2HSImp.CULong}) pEv
    		let state = parseMouseState mask

    		return (EventMouse evID (state { mouseCoordinates = (x, y, z) }))

    	codeF0 = E.fromEnum E.KEY_F0
    	codeF64 = codeF0 + 64
    	keyEvent code = return $ if code >= codeF0 && code <= codeF64
    		then EventSpecialKey (KeyFunction (code - codeF0))
    		else case M.lookup code keyMap of
    			Just key -> EventSpecialKey key
    			Nothing -> EventUnknown code

    data Key
    	= KeyUpArrow
    	| KeyDownArrow
    	| KeyLeftArrow
    	| KeyRightArrow
    	| KeyHome
    	| KeyBackspace
    	| KeyFunction Integer -- ^ Function keys, F0 &#x2013; F64
    	| KeyDeleteLine
    	| KeyInsertLine
    	| KeyDeleteCharacter
    	| KeyInsertCharacter
    	| KeyEIC -- ^ Sent by rmir or smir in insert mode
    	| KeyClear -- ^ Clear screen
    	| KeyEOS -- ^ Clear to end of screen
    	| KeyEOL -- ^ Clear to end of line
    	| KeyScrollForward
    	| KeyScrollBackward
    	| KeyNextPage
    	| KeyPreviousPage
    	| KeySetTab
    	| KeyClearTab
    	| KeyClearAllTabs
    	| KeyEnter
    	| KeyPrint
    	| KeyHomeDown
    	| KeyA1 -- ^ Upper left of keypad
    	| KeyA3 -- ^ Upper right of keypad
    	| KeyB2 -- ^ Center of keypad
    	| KeyC1 -- ^ Lower left of keypad
    	| KeyC3 -- ^ Lower right of keypad
    	| KeyBackTab
    	| KeyBegin
    	| KeyCancel
    	| KeyClose
    	| KeyCommand
    	| KeyCopy
    	| KeyCreate
    	| KeyEnd
    	| KeyExit
    	| KeyFind
    	| KeyHelp
    	| KeyMark
    	| KeyMessage
    	| KeyMove
    	| KeyNext
    	| KeyOpen
    	| KeyOptions
    	| KeyPrevious
    	| KeyRedo
    	| KeyReference
    	| KeyRefresh
    	| KeyReplace
    	| KeyRestart
    	| KeyResume
    	| KeySave
    	| KeyShiftedBegin
    	| KeyShiftedCancel
    	| KeyShiftedCommand
    	| KeyShiftedCopy
    	| KeyShiftedCreate
    	| KeyShiftedDeleteCharacter
    	| KeyShiftedDeleteLine
    	| KeySelect
    	| KeyShiftedEnd
    	| KeyShiftedEOL
    	| KeyShiftedExit
    	| KeyShiftedFind
    	| KeyShiftedHelp
    	| KeyShiftedHome
    	| KeyShiftedInsertCharacter
    	| KeyShiftedLeftArrow
    	| KeyShiftedMessage
    	| KeyShiftedMove
    	| KeyShiftedNext
    	| KeyShiftedOptions
    	| KeyShiftedPrevious
    	| KeyShiftedPrint
    	| KeyShiftedRedo
    	| KeyShiftedReplace
    	| KeyShiftedRightArrow
    	| KeyShiftedResume
    	| KeyShiftedSave
    	| KeyShiftedSuspend
    	| KeyShiftedUndo
    	| KeySuspend
    	| KeyUndo
    	deriving (Show, Eq)

    keyMap :: M.Map Integer Key
    keyMap = M.fromList $ map (\(enum, key) -> (E.fromEnum enum, key))
    	[ (E.KEY_DOWN, KeyDownArrow)
    	, (E.KEY_UP, KeyUpArrow)
    	, (E.KEY_LEFT, KeyLeftArrow)
    	, (E.KEY_RIGHT, KeyRightArrow)
    	, (E.KEY_HOME, KeyHome)
    	, (E.KEY_BACKSPACE, KeyBackspace)
    	, (E.KEY_DL, KeyDeleteLine)
    	, (E.KEY_IL, KeyInsertLine)
    	, (E.KEY_DC, KeyDeleteCharacter)
    	, (E.KEY_IC, KeyInsertCharacter)
    	, (E.KEY_EIC, KeyEIC)
    	, (E.KEY_CLEAR, KeyClear)
    	, (E.KEY_EOS, KeyEOS)
    	, (E.KEY_EOL, KeyEOL)
    	, (E.KEY_SF, KeyScrollForward)
    	, (E.KEY_SR, KeyScrollBackward)
    	, (E.KEY_NPAGE, KeyNextPage)
    	, (E.KEY_PPAGE, KeyPreviousPage)
    	, (E.KEY_STAB, KeySetTab)
    	, (E.KEY_CTAB, KeyClearTab)
    	, (E.KEY_CATAB, KeyClearAllTabs)
    	, (E.KEY_ENTER, KeyEnter)
    	, (E.KEY_PRINT, KeyPrint)
    	, (E.KEY_LL, KeyHomeDown)
    	, (E.KEY_A1, KeyA1)
    	, (E.KEY_A3, KeyA3)
    	, (E.KEY_B2, KeyB2)
    	, (E.KEY_C1, KeyC1)
    	, (E.KEY_C3, KeyC3)
    	, (E.KEY_BTAB, KeyBackTab)
    	, (E.KEY_BEG, KeyBegin)
    	, (E.KEY_CANCEL, KeyCancel)
    	, (E.KEY_CLOSE, KeyClose)
    	, (E.KEY_COMMAND, KeyCommand)
    	, (E.KEY_COPY, KeyCopy)
    	, (E.KEY_CREATE, KeyCreate)
    	, (E.KEY_END, KeyEnd)
    	, (E.KEY_EXIT, KeyExit)
    	, (E.KEY_FIND, KeyFind)
    	, (E.KEY_HELP, KeyHelp)
    	, (E.KEY_MARK, KeyMark)
    	, (E.KEY_MESSAGE, KeyMessage)
    	, (E.KEY_MOVE, KeyMove)
    	, (E.KEY_NEXT, KeyNext)
    	, (E.KEY_OPEN, KeyOpen)
    	, (E.KEY_OPTIONS, KeyOptions)
    	, (E.KEY_PREVIOUS, KeyPrevious)
    	, (E.KEY_REDO, KeyRedo)
    	, (E.KEY_REFERENCE, KeyReference)
    	, (E.KEY_REFRESH, KeyRefresh)
    	, (E.KEY_REPLACE, KeyReplace)
    	, (E.KEY_RESTART, KeyRestart)
    	, (E.KEY_RESUME, KeyResume)
    	, (E.KEY_SAVE, KeySave)
    	, (E.KEY_SBEG, KeyShiftedBegin)
    	, (E.KEY_SCANCEL, KeyShiftedCancel)
    	, (E.KEY_SCOMMAND, KeyShiftedCommand)
    	, (E.KEY_SCOPY, KeyShiftedCopy)
    	, (E.KEY_SCREATE, KeyShiftedCreate)
    	, (E.KEY_SDC, KeyShiftedDeleteCharacter)
    	, (E.KEY_SDL, KeyShiftedDeleteLine)
    	, (E.KEY_SELECT, KeySelect)
    	, (E.KEY_SEND, KeyShiftedEnd)
    	, (E.KEY_SEOL, KeyShiftedEOL)
    	, (E.KEY_SEXIT, KeyShiftedExit)
    	, (E.KEY_SFIND, KeyShiftedFind)
    	, (E.KEY_SHELP, KeyShiftedHelp)
    	, (E.KEY_SHOME, KeyShiftedHome)
    	, (E.KEY_SIC, KeyShiftedInsertCharacter)
    	, (E.KEY_SLEFT, KeyShiftedLeftArrow)
    	, (E.KEY_SMESSAGE, KeyShiftedMessage)
    	, (E.KEY_SMOVE, KeyShiftedMove)
    	, (E.KEY_SNEXT, KeyShiftedNext)
    	, (E.KEY_SOPTIONS, KeyShiftedOptions)
    	, (E.KEY_SPREVIOUS, KeyShiftedPrevious)
    	, (E.KEY_SPRINT, KeyShiftedPrint)
    	, (E.KEY_SREDO, KeyShiftedRedo)
    	, (E.KEY_SREPLACE, KeyShiftedReplace)
    	, (E.KEY_SRIGHT, KeyShiftedRightArrow)
    	, (E.KEY_SRSUME, KeyShiftedResume)
    	, (E.KEY_SSAVE, KeyShiftedSave)
    	, (E.KEY_SSUSPEND, KeyShiftedSuspend)
    	, (E.KEY_SUNDO, KeyShiftedUndo)
    	, (E.KEY_SUSPEND, KeySuspend)
    	, (E.KEY_UNDO, KeyUndo)
    	]

    data ButtonState
    	= ButtonPressed
    	| ButtonReleased
    	| ButtonClicked
    	| ButtonDoubleClicked
    	| ButtonTripleClicked
    	deriving (Show, Eq)

    data MouseState = MouseState
    	{ mouseCoordinates :: (Integer, Integer, Integer) -- ^ (X, Y, Z)

    	-- | If the mouse event was caused by a change in button state,
    	-- the buttons and their new state will be listed here.
    	, mouseButtons :: [(Integer, ButtonState)]

    	, mouseAlt :: Bool
    	, mouseShift :: Bool
    	, mouseControl :: Bool
    	}
    	deriving (Show, Eq)

    parseMouseState :: MMaskT -> MouseState
    parseMouseState mask = MouseState (0, 0, 0) buttons alt shift ctrl where
    	maskI = toInteger mask
    	test e = (maskI .&. (E.fromEnum e)) > 0

    	alt = test E.BUTTON_ALT
    	shift = test E.BUTTON_SHIFT
    	ctrl = test E.BUTTON_CTRL

    	buttons = catMaybes [button1, button2, button3, button4, button5]

    	testButton idx r p c dc tc
    		| test r  = Just (idx, ButtonReleased)
    		| test p  = Just (idx, ButtonPressed)
    		| test c  = Just (idx, ButtonClicked)
    		| test dc = Just (idx, ButtonDoubleClicked)
    		| test tc = Just (idx, ButtonTripleClicked)
    		| otherwise = Nothing

    	button1 = testButton 1
    		E.BUTTON1_RELEASED
    		E.BUTTON1_PRESSED
    		E.BUTTON1_CLICKED
    		E.BUTTON1_DOUBLE_CLICKED
    		E.BUTTON1_TRIPLE_CLICKED
    	button2 = testButton 2
    		E.BUTTON2_RELEASED
    		E.BUTTON2_PRESSED
    		E.BUTTON2_CLICKED
    		E.BUTTON2_DOUBLE_CLICKED
    		E.BUTTON2_TRIPLE_CLICKED
    	button3 = testButton 3
    		E.BUTTON3_RELEASED
    		E.BUTTON3_PRESSED
    		E.BUTTON3_CLICKED
    		E.BUTTON3_DOUBLE_CLICKED
    		E.BUTTON3_TRIPLE_CLICKED
    	button4 = testButton 4
    		E.BUTTON4_RELEASED
    		E.BUTTON4_PRESSED
    		E.BUTTON4_CLICKED
    		E.BUTTON4_DOUBLE_CLICKED
    		E.BUTTON4_TRIPLE_CLICKED
    	button5 = Nothing

    data CursorMode
    	= CursorInvisible
    	| CursorVisible
    	| CursorVeryVisible
    	| CursorModeUnknown CInt
    	deriving (Eq, Show)

    -- | Set the current cursor mode to visible, invisible, or \"very visible\".
    -- The previous cursor mode is returned.
    setCursorMode :: CursorMode -> Curses CursorMode
    setCursorMode mode = Curses $ do
    	let intMode = case mode of
    		CursorInvisible -> 0
    		CursorVisible -> 1
    		CursorVeryVisible -> 2
    		CursorModeUnknown n -> n
    	rc <- curs_set intMode
    	checkRC "setCursorMode" rc
    	return $ case rc of
    		0 -> CursorInvisible
    		1 -> CursorVisible
    		2 -> CursorVeryVisible
    		_ -> CursorModeUnknown rc

    -- | Returns Left if a Curses exception occured in the given computation.
    --
    -- See 'try' for more details.
    tryCurses :: Curses a -> Curses (Either CursesException a)
    tryCurses (Curses io) = Curses (try io)

    -- | Handles errors in the given computation by passing them to a callback.
    --
    -- See 'catch' for more details.
    catchCurses :: Curses a -> (CursesException -> Curses a) -> Curses a
    catchCurses (Curses io) fn = Curses (catch io (unCurses . fn))

    -- | Throws an exception from within Curses handling code. This is useful
    -- for re-throwing errors from within a 'catchCurses' callback.
    --
    -- See 'throwIO' for more details.
    throwCurses :: CursesException -> Curses a
    throwCurses = Curses . throwIO

    -- | Runs @raw()@ or @noraw()@
    setRaw :: Bool -> Curses ()
    setRaw set = Curses (io >>= checkRC "setRaw") where
    	io = if set then raw else noraw
    {-# LINE 1214 "lib/UI/NCurses.chs" #-}

    -- | Runs @cbreak()@ or @nocbreak()@
    setCBreak :: Bool -> Curses ()
    setCBreak set = Curses (io >>= checkRC "setCBreak") where
    	io = if set then cbreak else nocbreak
    {-# LINE 1219 "lib/UI/NCurses.chs" #-}

    -- | Runs @echo()@ or @noecho()@
    setEcho :: Bool -> Curses ()
    setEcho set = Curses (io >>= checkRC "setEcho") where
    	io = if set then echo else noecho
    {-# LINE 1224 "lib/UI/NCurses.chs" #-}

    -- | Get the output speed of the current terminal, in bits per second.
    baudrate :: Curses Integer
    baudrate = Curses $ do
    	rc <- c_baudrate
    {-# LINE 1229 "lib/UI/NCurses.chs" #-}

    	checkRC "baudrate" rc
    	return (toInteger rc)

    beep :: Curses ()
    beep = Curses (c_beep >>= checkRC "beep")

    flash :: Curses ()
    flash = Curses (c_flash >>= checkRC "flash")

    -- | Check if the terminal has a mouse
    hasMouse :: Curses Bool
    hasMouse = Curses (fmap cToBool c_hasMouse)

    foreign import ccall unsafe "hsncurses_has_mouse"
    	c_hasMouse :: IO CInt

    -- | Check if some position is contained within the given 'Window'.
    enclosed :: Window
             -> Integer -- ^ Row
             -> Integer -- ^ Column
             -> Curses Bool
    enclosed win row col = Curses . fmap cToBool $
    	wenclose win (fromInteger row) (fromInteger col)

    -- | Return (rows, columns) of current screen
    screenSize :: Curses (Integer, Integer)
    screenSize = Curses $ do
    	rows <- peek c_LINES
    	cols <- peek c_COLS
    	return (toInteger rows, toInteger cols)

    foreign import ccall "static &LINES"
    	c_LINES :: Ptr CInt

    foreign import ccall "static &COLS"
    	c_COLS :: Ptr CInt

    -- | Set whether the entire window has been &#x201C;touched&#x201D;;
    -- touched characters are redrawn on the next refresh.
    setTouched :: Bool -> Update ()
    setTouched touched = withWindow_ "setTouched" $ if touched
    	then touchwin
    {-# LINE 1271 "lib/UI/NCurses.chs" #-}

    	else untouchwin
    {-# LINE 1272 "lib/UI/NCurses.chs" #-}

    -- | Set whether particular rows in the window have been
    -- &#x201C;touched&#x201D;.
    setRowsTouched :: Bool
                    -> Integer -- ^ Start
                    -> Integer -- ^ Count
                    -> Update ()
    setRowsTouched touched start count = withWindow_ "setRowsTouched" $ \win ->
    	wtouchln win
    		(fromInteger start)
    		(fromInteger count)
    		(cFromBool touched)

    -- | Enable/disable support for special keys.
    setKeypad :: Window -> Bool -> Curses ()
    setKeypad win set = Curses (io >>= checkRC "setKeypad") where
    	io = keypad win (cFromBool set)

    -- | Attempt to resize the terminal to the given number of lines and columns.
    resizeTerminal :: Integer -> Integer -> Curses ()
    resizeTerminal lines cols = Curses (io >>= checkRC "resizeTerminal") where
    	io = resizeterm (fromInteger lines) (fromInteger cols)

    withWindow :: (Window -> IO a) -> Update a
    withWindow io = Update (R.ReaderT (\win -> Curses (io win)))

    withWindow_ :: String -> (Window -> IO CInt) -> Update ()
    withWindow_ name io = withWindow $ \win -> io win >>= checkRC name

    foreign import ccall safe "UI/NCurses.chs.h endwin"
      endwin :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h initscr"
      initscr :: (IO (Window))

    foreign import ccall safe "UI/NCurses.chs.h cbreak"
      cbreak :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h mousemask"
      mousemask :: (C2HSImp.CULong -> ((C2HSImp.Ptr C2HSImp.CULong) -> (IO C2HSImp.CULong)))

    foreign import ccall safe "UI/NCurses.chs.h has_colors"
      has_colors :: (IO C2HSImp.CUChar)

    foreign import ccall safe "UI/NCurses.chs.h start_color"
      start_color :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h use_default_colors"
      use_default_colors :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h keypad"
      keypad :: ((Window) -> (C2HSImp.CUChar -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h meta"
      meta :: ((Window) -> (C2HSImp.CUChar -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h wtimeout"
      wtimeout :: ((Window) -> (C2HSImp.CInt -> (IO ())))

    foreign import ccall safe "UI/NCurses.chs.h newwin"
      newwin :: (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO (Window))))))

    foreign import ccall safe "UI/NCurses.chs.h delwin"
      delwin :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h dupwin"
      dupwin :: ((Window) -> (IO (Window)))

    foreign import ccall safe "UI/NCurses.chs.h wnoutrefresh"
      wnoutrefresh :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h mvwin"
      mvwin :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h getbegy"
      getbegy :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h getbegx"
      getbegx :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h wresize"
      wresize :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h getmaxy"
      getmaxy :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h getmaxx"
      getmaxx :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h overlay"
      c_overlay :: ((Window) -> ((Window) -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h overwrite"
      overwrite :: ((Window) -> ((Window) -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h copywin"
      copywin :: ((Window) -> ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))))))))

    foreign import ccall safe "UI/NCurses.chs.h newpad"
      newpad :: (C2HSImp.CInt -> (C2HSImp.CInt -> (IO (Window))))

    foreign import ccall safe "UI/NCurses.chs.h pnoutrefresh"
      pnoutrefresh :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))))))

    foreign import ccall safe "UI/NCurses.chs.h wmove"
      wmove :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h getcury"
      getcury :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h getcurx"
      getcurx :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h doupdate"
      doupdate :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h wcolor_set"
      wcolor_set :: ((Window) -> (C2HSImp.CShort -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h waddwstr"
      waddwstr :: ((Window) -> ((CWString) -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h wadd_wch"
      wadd_wch :: ((Window) -> ((CCharT) -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h wborder_set"
      wborder_set :: ((Window) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> ((CCharT) -> (IO C2HSImp.CInt))))))))))

    foreign import ccall safe "UI/NCurses.chs.h whline_set"
      whline_set :: ((Window) -> ((CCharT) -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h wvline_set"
      wvline_set :: ((Window) -> ((CCharT) -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h wclear"
      wclear :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h wclrtoeol"
      wclrtoeol :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h wbkgrndset"
      wbkgrndset :: ((Window) -> ((CCharT) -> (IO ())))

    foreign import ccall unsafe "UI/NCurses.chs.h COLOR_PAIR"
      c_COLOR_PAIR :: (C2HSImp.CInt -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h wattr_on"
      wattr_on :: ((Window) -> (C2HSImp.CULong -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h wattr_off"
      wattr_off :: ((Window) -> (C2HSImp.CULong -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h wattr_get"
      wattr_get :: ((Window) -> ((C2HSImp.Ptr C2HSImp.CULong) -> ((C2HSImp.Ptr C2HSImp.CShort) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))))

    foreign import ccall safe "UI/NCurses.chs.h wattr_set"
      wattr_set :: ((Window) -> (C2HSImp.CULong -> (C2HSImp.CShort -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))))

    foreign import ccall safe "UI/NCurses.chs.h can_change_color"
      can_change_color :: (IO C2HSImp.CUChar)

    foreign import ccall safe "UI/NCurses.chs.h init_color"
      init_color :: (C2HSImp.CShort -> (C2HSImp.CShort -> (C2HSImp.CShort -> (C2HSImp.CShort -> (IO C2HSImp.CInt)))))

    foreign import ccall safe "UI/NCurses.chs.h color_content"
      color_content :: (C2HSImp.CShort -> ((C2HSImp.Ptr C2HSImp.CShort) -> ((C2HSImp.Ptr C2HSImp.CShort) -> ((C2HSImp.Ptr C2HSImp.CShort) -> (IO C2HSImp.CInt)))))

    foreign import ccall safe "UI/NCurses.chs.h init_pair"
      init_pair :: (C2HSImp.CShort -> (C2HSImp.CShort -> (C2HSImp.CShort -> (IO C2HSImp.CInt))))

    foreign import ccall safe "UI/NCurses.chs.h hsncurses_init_cchar_t"
      hsncurses_init_cchar_t :: ((CCharT) -> (C2HSImp.CULong -> ((CWString) -> (C2HSImp.CULong -> (IO ())))))

    foreign import ccall safe "UI/NCurses.chs.h hsncurses_wget_wch"
      hsncurses_wget_wch :: ((Window) -> ((C2HSImp.Ptr C2HSImp.CUInt) -> (IO C2HSImp.CInt)))

    foreign import ccall safe "UI/NCurses.chs.h getmouse"
      getmouse :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h curs_set"
      curs_set :: (C2HSImp.CInt -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h raw"
      raw :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h noraw"
      noraw :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h nocbreak"
      nocbreak :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h echo"
      echo :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h noecho"
      noecho :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h baudrate"
      c_baudrate :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h beep"
      c_beep :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h flash"
      c_flash :: (IO C2HSImp.CInt)

    foreign import ccall safe "UI/NCurses.chs.h wenclose"
      wenclose :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CUChar))))

    foreign import ccall safe "UI/NCurses.chs.h touchwin"
      touchwin :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h untouchwin"
      untouchwin :: ((Window) -> (IO C2HSImp.CInt))

    foreign import ccall safe "UI/NCurses.chs.h wtouchln"
      wtouchln :: ((Window) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))

    foreign import ccall safe "UI/NCurses.chs.h resizeterm"
      resizeterm :: (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))