module Ermine.Console.Unicode
( withUnicode
) where
import Control.Monad.Catch
#ifdef mingw32_HOST_ARCH
#ifdef i386_HOST_ARCH
#define USE_CP
import Control.Monad.IO.Class
import System.IO
import Foreign.C.Types
foreign import stdcall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool
foreign import stdcall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt
#elif defined(x86_64_HOST_ARCH)
#define USE_CP
import Control.Monad.IO.Class
import System.IO
import Foreign.C.Types
foreign import ccall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool
foreign import ccall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt
#endif
#endif
withUnicode :: MonadCatch m => m a -> m a
#ifdef USE_CP
withUnicode m = do
cp <- liftIO c_GetConsoleCP
enc <- liftIO $ hGetEncoding stdout
let setup = liftIO $ c_SetConsoleCP 65001 >> hSetEncoding stdout utf8
cleanup = liftIO $ maybe (return ()) (hSetEncoding stdout) enc >> c_SetConsoleCP cp
finally (setup >> m) cleanup
#else
withUnicode m = m
#endif