    {-# INCLUDE <windows.h> #-}
    {-# INCLUDE "gettime.h" #-}
    {-# LINE 1 "Graphics\Win32\Misc.hsc" #-}
    -----------------------------------------------------------------------------
    {-# LINE 2 "Graphics\Win32\Misc.hsc" #-}
    -- |
    -- Module      :  Graphics.Win32.Misc
    -- Copyright   :  (c) Alastair Reid, 1997-2003
    -- License     :  BSD-style (see the file libraries/base/LICENSE)
    --
    -- Maintainer  :  Esa Ilari Vuokko <ei@vuokko.info>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- A collection of FFI declarations for interfacing with Win32.
    --
    -----------------------------------------------------------------------------

    module Graphics.Win32.Misc where

    import Graphics.Win32.GDI.Types
    import System.Win32.Types

    import Data.Maybe
    import Foreign

    {-# LINE 24 "Graphics\Win32\Misc.hsc" #-}

    {-# LINE 25 "Graphics\Win32\Misc.hsc" #-}

    ----------------------------------------------------------------
    -- Resources
    -- (should probably be distributed between
    --  Graphics.Win32.{Icon,Cursor,Accelerator,Menu,...})
    ----------------------------------------------------------------

    type Accelerator = LPCTSTR
    -- intToAccelerator :: Int -> Accelerator
    -- intToAccelerator i = makeIntResource (toWord i)

    -- cursor and icon should not be const pointer; GSL ???
    type Cursor = LPTSTR
    -- intToCursor :: Int -> Cursor
    -- intToCursor i = makeIntResource (toWord i)

    type Icon = LPTSTR
    -- intToIcon :: Int -> Icon
    -- intToIcon i = makeIntResource (toWord i)

    loadAccelerators :: Maybe HINSTANCE -> Accelerator -> IO HACCEL
    loadAccelerators mb_inst accel =
      failIfNull "LoadAccelerators" $ c_LoadAccelerators (maybePtr mb_inst) accel
    foreign import stdcall unsafe "windows.h LoadAcceleratorsW"
      c_LoadAccelerators :: HINSTANCE -> Accelerator -> IO HACCEL

    loadCursor :: Maybe HINSTANCE -> Cursor -> IO HCURSOR
    loadCursor mb_inst cursor =
      failIfNull "LoadCursor" $ c_LoadCursor (maybePtr mb_inst) cursor
    foreign import stdcall unsafe "windows.h LoadCursorW"
      c_LoadCursor :: HINSTANCE -> Cursor -> IO HCURSOR

    loadIcon :: Maybe HINSTANCE -> Icon -> IO HICON
    loadIcon mb_inst icon =
      failIfNull "LoadIcon" $ c_LoadIcon (maybePtr mb_inst) icon
    foreign import stdcall unsafe "windows.h LoadIconW"
      c_LoadIcon :: HINSTANCE -> Icon -> IO HICON

    iDC_ARROW         :: Cursor
    iDC_ARROW         = castUINTToPtr 32512
    iDC_IBEAM         :: Cursor
    iDC_IBEAM         = castUINTToPtr 32513
    iDC_WAIT          :: Cursor
    iDC_WAIT          = castUINTToPtr 32514
    iDC_CROSS         :: Cursor
    iDC_CROSS         = castUINTToPtr 32515
    iDC_UPARROW       :: Cursor
    iDC_UPARROW       = castUINTToPtr 32516
    iDC_SIZENWSE      :: Cursor
    iDC_SIZENWSE      = castUINTToPtr 32642
    iDC_SIZENESW      :: Cursor
    iDC_SIZENESW      = castUINTToPtr 32643
    iDC_SIZEWE        :: Cursor
    iDC_SIZEWE        = castUINTToPtr 32644
    iDC_SIZENS        :: Cursor
    iDC_SIZENS        = castUINTToPtr 32645

    {-# LINE 74 "Graphics\Win32\Misc.hsc" #-}

    iDI_APPLICATION   :: Icon
    iDI_APPLICATION   = castUINTToPtr 32512
    iDI_HAND          :: Icon
    iDI_HAND          = castUINTToPtr 32513
    iDI_QUESTION      :: Icon
    iDI_QUESTION      = castUINTToPtr 32514
    iDI_EXCLAMATION   :: Icon
    iDI_EXCLAMATION   = castUINTToPtr 32515
    iDI_ASTERISK      :: Icon
    iDI_ASTERISK      = castUINTToPtr 32516

    {-# LINE 82 "Graphics\Win32\Misc.hsc" #-}

    ----------------------------------------------------------------
    -- Message Boxes
    ----------------------------------------------------------------

    type MBStyle = UINT

    mB_OK                 :: MBStyle
    mB_OK                 =  0
    mB_OKCANCEL           :: MBStyle
    mB_OKCANCEL           =  1
    mB_ABORTRETRYIGNORE   :: MBStyle
    mB_ABORTRETRYIGNORE   =  2
    mB_YESNOCANCEL        :: MBStyle
    mB_YESNOCANCEL        =  3
    mB_YESNO              :: MBStyle
    mB_YESNO              =  4
    mB_RETRYCANCEL        :: MBStyle
    mB_RETRYCANCEL        =  5
    mB_ICONHAND           :: MBStyle
    mB_ICONHAND           =  16
    mB_ICONQUESTION       :: MBStyle
    mB_ICONQUESTION       =  32
    mB_ICONEXCLAMATION    :: MBStyle
    mB_ICONEXCLAMATION    =  48
    mB_ICONASTERISK       :: MBStyle
    mB_ICONASTERISK       =  64
    mB_ICONINFORMATION    :: MBStyle
    mB_ICONINFORMATION    =  64
    mB_ICONSTOP           :: MBStyle
    mB_ICONSTOP           =  16
    mB_DEFBUTTON1         :: MBStyle
    mB_DEFBUTTON1         =  0
    mB_DEFBUTTON2         :: MBStyle
    mB_DEFBUTTON2         =  256
    mB_DEFBUTTON3         :: MBStyle
    mB_DEFBUTTON3         =  512
    mB_APPLMODAL          :: MBStyle
    mB_APPLMODAL          =  0
    mB_SYSTEMMODAL        :: MBStyle
    mB_SYSTEMMODAL        =  4096
    mB_TASKMODAL          :: MBStyle
    mB_TASKMODAL          =  8192
    mB_SETFOREGROUND      :: MBStyle
    mB_SETFOREGROUND      =  65536

    {-# LINE 110 "Graphics\Win32\Misc.hsc" #-}

    type MBStatus = UINT

    iDABORT       :: MBStatus
    iDABORT       =  3
    iDCANCEL      :: MBStatus
    iDCANCEL      =  2
    iDIGNORE      :: MBStatus
    iDIGNORE      =  5
    iDNO          :: MBStatus
    iDNO          =  7
    iDOK          :: MBStatus
    iDOK          =  1
    iDRETRY       :: MBStatus
    iDRETRY       =  4
    iDYES         :: MBStatus
    iDYES         =  6

    {-# LINE 122 "Graphics\Win32\Misc.hsc" #-}

    -- Note: if the error is ever raised, we're in a very sad way!

    messageBox :: HWND -> String -> String -> MBStyle -> IO MBStatus
    messageBox wnd text caption style =
      withTString text $ \ c_text ->
      withTString caption $ \ c_caption ->
      failIfZero "MessageBox" $ c_MessageBox wnd c_text c_caption style
    foreign import stdcall unsafe "windows.h MessageBoxW"
      c_MessageBox :: HWND -> LPCTSTR -> LPCTSTR -> MBStyle -> IO MBStatus

    ----------------------------------------------------------------
    --
    ----------------------------------------------------------------

    type StdHandleId   = DWORD

    sTD_INPUT_HANDLE      :: StdHandleId
    sTD_INPUT_HANDLE      =  4294967286
    sTD_OUTPUT_HANDLE     :: StdHandleId
    sTD_OUTPUT_HANDLE     =  4294967285
    sTD_ERROR_HANDLE      :: StdHandleId
    sTD_ERROR_HANDLE      =  4294967284

    {-# LINE 144 "Graphics\Win32\Misc.hsc" #-}

    getStdHandle :: StdHandleId -> IO HANDLE
    getStdHandle hid =
      failIf (== iNVALID_HANDLE_VALUE) "GetStdHandle" $ c_GetStdHandle hid
    foreign import stdcall unsafe "windows.h GetStdHandle"
      c_GetStdHandle :: StdHandleId -> IO HANDLE

    ----------------------------------------------------------------
    -- Rotatable Ellipse hack
    --
    -- Win95 (Win32?) doesn't support rotating ellipses - so we
    -- implement them with polygons.
    --
    -- We use a fixed number of edges rather than varying the number
    -- according to the radius of the ellipse.
    -- If anyone feels like improving the code (to vary the number),
    -- they should place a fixed upper bound on the number of edges
    -- since it takes a relatively long time to draw 1000 edges.
    ----------------------------------------------------------------

    transformedEllipse :: HDC -> POINT -> POINT -> POINT -> IO ()
    transformedEllipse dc (x0,y0) (x1,y1) (x2,y2) =
      failIfFalse_ "transformedEllipse" $ c_transformedEllipse dc x0 y0 x1 y1 x2 y2
    foreign import ccall unsafe "ellipse.h transformedEllipse"
      c_transformedEllipse :: HDC -> LONG -> LONG -> LONG -> LONG -> LONG -> LONG -> IO Bool

    {-# CFILES cbits/ellipse.c #-}

    ----------------------------------------------------------------
    -- Cursor
    ----------------------------------------------------------------

    getCursorPos :: IO POINT
    getCursorPos =
      allocaPOINT $ \ p_pt -> do
      failIfFalse_ "GetCursorPos" $ c_GetCursorPos p_pt
      peekPOINT p_pt
    foreign import stdcall unsafe "windows.h GetCursorPos"
      c_GetCursorPos :: Ptr POINT -> IO Bool

    setCursorPos :: POINT -> IO ()
    setCursorPos (x,y) =
      failIfFalse_ "setCursorPos" $ c_SetCursorPos x y
    foreign import stdcall unsafe "windows.h SetCursorPos"
      c_SetCursorPos :: LONG -> LONG -> IO Bool

    clipCursor :: RECT -> IO ()
    clipCursor rect =
      withRECT rect $ \ p_rect ->
      failIfFalse_ "ClipCursor" $ c_ClipCursor p_rect
    foreign import stdcall unsafe "windows.h ClipCursor"
      c_ClipCursor :: Ptr RECT -> IO Bool

    getClipCursor :: IO RECT
    getClipCursor =
      allocaRECT $ \ p_rect -> do
      failIfFalse_ "GetClipCursor" $ c_GetClipCursor p_rect
      peekRECT p_rect
    foreign import stdcall unsafe "windows.h GetClipCursor"
      c_GetClipCursor :: Ptr RECT -> IO Bool

    ----------------------------------------------------------------
    -- Exit/shutdown
    ----------------------------------------------------------------

    type ExitOption = UINT

    eWX_FORCE     :: ExitOption
    eWX_FORCE     =  4
    eWX_LOGOFF    :: ExitOption
    eWX_LOGOFF    =  0
    eWX_POWEROFF  :: ExitOption
    eWX_POWEROFF  =  8
    eWX_REBOOT    :: ExitOption
    eWX_REBOOT    =  2
    eWX_SHUTDOWN  :: ExitOption
    eWX_SHUTDOWN  =  1

    {-# LINE 218 "Graphics\Win32\Misc.hsc" #-}

    exitWindowsEx :: ExitOption -> IO ()
    exitWindowsEx opt =
      failIfFalse_ "ExitWindowsEx" $ c_ExitWindowsEx opt 0
    foreign import stdcall unsafe "windows.h ExitWindowsEx"
      c_ExitWindowsEx :: ExitOption -> DWORD -> IO Bool

    exitWindows :: IO ()
    exitWindows = exitWindowsEx 0

    ----------------------------------------------------------------
    -- Beeping
    ----------------------------------------------------------------

    type Beep = UINT
    type MbBeep = Maybe Beep

    maybeBeep :: Maybe Beep -> Beep
    maybeBeep = fromMaybe 0xffffffff

    type Duration   = Int

    type MbDuration   = Maybe Duration

    maybeDuration :: Maybe Duration -> Duration
    maybeDuration = fromMaybe (-1)

    messageBeep :: Maybe Beep -> IO ()
    messageBeep mb_beep =
      c_MessageBeep (maybeBeep mb_beep)
    foreign import stdcall unsafe "windows.h MessageBeep"
      c_MessageBeep :: Beep -> IO ()

    beep :: WORD -> MbDuration -> IO ()
    beep freq mb_dur =
      failIfFalse_ "Beep" $ c_Beep freq (maybeDuration mb_dur)
    foreign import stdcall unsafe "windows.h Beep"
      c_Beep :: WORD -> Duration -> IO Bool

    ----------------------------------------------------------------
    -- Timers
    ----------------------------------------------------------------

    type TimerId   = UINT

    type TIMERPROC = FunPtr (HWND -> UINT -> TimerId -> DWORD -> IO ())

    -- ToDo: support the other two forms of timer initialisation

    -- Cause WM_TIMER events to be sent to window callback

    setWinTimer :: HWND -> TimerId -> UINT -> IO TimerId
    setWinTimer wnd timer elapse =
      failIfZero "SetTimer" $ c_SetTimer wnd timer elapse nullFunPtr
    foreign import stdcall unsafe "windows.h SetTimer"
      c_SetTimer :: HWND -> TimerId -> UINT -> TIMERPROC -> IO TimerId

    killTimer :: Maybe HWND -> TimerId -> IO ()
    killTimer mb_wnd timer =
      failIfFalse_ "KillTimer" $ c_KillTimer (maybePtr mb_wnd) timer
    foreign import stdcall unsafe "windows.h KillTimer"
      c_KillTimer :: HWND -> TimerId -> IO Bool

    -- For documentation purposes:
    type MilliSeconds = DWORD

    foreign import stdcall unsafe "windows.h timeGetTime"
      timeGetTime :: IO MilliSeconds

    ----------------------------------------------------------------

    -- %fun ezCreateFont :: Unknown
    -- %result BITMAP({ getBitmapInfo(x) })

    ----------------------------------------------------------------
    -- End
    ----------------------------------------------------------------