{-# LANGUAGE CPP #-}
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 PHANDLER_ROUTINE = FunPtr Handler
withConsoleCtrlHandler :: Handler -> IO a -> IO a
withConsoleCtrlHandler :: forall a. Handler -> IO a -> IO a
withConsoleCtrlHandler Handler
handler IO a
io
= IO (FunPtr Handler)
-> (FunPtr Handler -> IO ()) -> (FunPtr Handler -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (do hd <- Handler -> IO (FunPtr Handler)
mkHandler Handler
handler
void $ c_SetConsoleCtrlHandler hd True
return hd)
(\FunPtr Handler
hd -> IO BOOL -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO BOOL -> IO ()) -> IO BOOL -> IO ()
forall a b. (a -> b) -> a -> b
$ FunPtr Handler -> BOOL -> IO BOOL
c_SetConsoleCtrlHandler FunPtr Handler
hd BOOL
False)
((FunPtr Handler -> IO a) -> IO a)
-> (FunPtr Handler -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ IO a -> FunPtr Handler -> IO a
forall a b. a -> b -> a
const IO a
io
setConsoleCtrlHandler :: PHANDLER_ROUTINE -> BOOL -> IO ()
setConsoleCtrlHandler :: FunPtr Handler -> BOOL -> IO ()
setConsoleCtrlHandler FunPtr Handler
handler BOOL
flag
= String -> IO BOOL -> IO ()
failIfFalse_ String
"SetConsoleCtrlHandler"
(IO BOOL -> IO ()) -> IO BOOL -> IO ()
forall a b. (a -> b) -> a -> b
$ FunPtr Handler -> BOOL -> IO BOOL
c_SetConsoleCtrlHandler FunPtr Handler
handler BOOL
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