System/Win32/Console/CtrlHandler.hs
{-# LANGUAGE CPP #-}
{- |
Module : System.Win32.Console.CtrlHandler
Copyright : 2008-2013 Judah Jacobson, 2013 shelarcy
License : BSD-style
Maintainer : shelarcy@gmail.com
Stability : Provisional
Portability : Non-portable (Win32 API)
Set handlers of console Ctrl events.
-}
module System.Win32.Console.CtrlHandler
( CtrlEvent, Handler, PHANDLER_ROUTINE
, withConsoleCtrlHandler
, setConsoleCtrlHandler, c_SetConsoleCtrlHandler
, mkHandler
, cTRL_C_EVENT, cTRL_BREAK_EVENT
) where
import Control.Exception ( bracket )
import Control.Monad ( void )
import Foreign.Ptr ( FunPtr )
import System.Win32.Console ( CtrlEvent, cTRL_C_EVENT, cTRL_BREAK_EVENT )
import System.Win32.Types ( BOOL, failIfFalse_ )
#include "windows_cconv.h"
type Handler = CtrlEvent -> IO BOOL
-- type HandlerRoutine = Handler
type PHANDLER_ROUTINE = FunPtr Handler
withConsoleCtrlHandler :: Handler -> IO a -> IO a
withConsoleCtrlHandler handler io
= bracket (do hd <- mkHandler handler
-- don't fail if we can't set the Ctrl-C handler
-- for example, we might not be attached to a console?
void $ c_SetConsoleCtrlHandler hd True
return hd)
(\hd -> void $ c_SetConsoleCtrlHandler hd False)
$ const io
-- | This function isn't suitable when we want to set the cTRL_C_EVENT handler.
-- If you want to set the cTRL_C_EVENT handler, use 'c_SetConsoleCtrlHandler' instead.
setConsoleCtrlHandler :: PHANDLER_ROUTINE -> BOOL -> IO ()
setConsoleCtrlHandler handler flag
= failIfFalse_ "SetConsoleCtrlHandler"
$ c_SetConsoleCtrlHandler handler flag
foreign import WINDOWS_CCONV "wrapper" mkHandler :: Handler -> IO PHANDLER_ROUTINE
foreign import WINDOWS_CCONV "windows.h SetConsoleCtrlHandler"
c_SetConsoleCtrlHandler :: PHANDLER_ROUTINE -> BOOL -> IO BOOL