    {-# LINE 1 "libraries\\Win32\\Graphics\\Win32\\Window\\IMM.hsc" #-}
    {-# LANGUAGE CPP #-}
    {- |
       Module      :  Graphics.Win32.Window.IMM
       Copyright   :  2013 shelarcy
       License     :  BSD-style

       Maintainer  :  shelarcy@gmail.com
       Stability   :  Provisional
       Portability :  Non-portable (Win32 API)

       An FFI binding to the IMM (Input Method Manager) part of the Win32 API.
    -}
    module Graphics.Win32.Window.IMM where
    import Foreign.Marshal.Alloc    ( alloca )
    import Foreign.Marshal.Utils    ( fromBool )
    import Foreign.Ptr              ( Ptr )
    import Foreign.Storable         ( peek )
    import Graphics.Win32.GDI.Types ( HWND )
    import Graphics.Win32.Key       ( VKey )
    import System.Win32.Types       ( UINT, DWORD, LPDWORD, BOOL, failIfFalse_ )

    #include "windows_cconv.h"

    type HIMC = Ptr ()

    foreign import WINDOWS_CCONV "windows.h ImmGetContext"
      immGetContext     :: HWND -> IO HIMC

    foreign import WINDOWS_CCONV "windows.h ImmGetOpenStatus"
      immGetOpenStatus :: HIMC -> IO BOOL

    immSetOpenStatus :: HIMC -> BOOL -> IO ()
    immSetOpenStatus imc flg =
      failIfFalse_ (unwords ["ImmSetOpenStatus", show imc, show flg])
        $ c_ImmSetOpenStatus imc (fromBool flg)

    foreign import WINDOWS_CCONV "windows.h ImmSetOpenStatus"
      c_ImmSetOpenStatus  :: HIMC -> UINT -> IO BOOL

    data IMEMode = IMEMode DWORD DWORD

    immGetConversionStatus :: HIMC -> IO IMEMode
    immGetConversionStatus imc =
      alloca $ \lpConv ->
      alloca $ \lpStnc -> do
        failIfFalse_ (unwords ["ImmGetConversionStatus", show imc, show lpConv, show lpStnc]) $
          c_ImmGetConversionStatus imc lpConv lpStnc
        conv <- peek lpConv
        stnc <- peek lpStnc
        return $ IMEMode conv stnc

    foreign import WINDOWS_CCONV "windows.h ImmGetConversionStatus"
      c_ImmGetConversionStatus :: HIMC -> LPDWORD ->  LPDWORD -> IO BOOL

    immSetConversionStatus :: HIMC -> IMEMode -> IO ()
    immSetConversionStatus imc (IMEMode conv stnc) =
      failIfFalse_ (unwords ["ImmSetConversionStatus", show imc, show conv, show stnc])
        $ c_ImmSetConversionStatus imc conv stnc

    foreign import WINDOWS_CCONV "windows.h ImmSetConversionStatus"
      c_ImmSetConversionStatus :: HIMC -> DWORD -> DWORD -> IO BOOL

    -- iMN_SETCONVERSIONSTATUS = #const IMN_SETCONVERSIONSTATUS

    iME_CMODE_ALPHANUMERIC   :: DWORD
    iME_CMODE_ALPHANUMERIC   =  0
    iME_CMODE_CHARCODE       :: DWORD
    iME_CMODE_CHARCODE       =  32
    iME_CMODE_EUDC           :: DWORD
    iME_CMODE_EUDC           =  512
    iME_CMODE_FIXED          :: DWORD
    iME_CMODE_FIXED          =  2048
    iME_CMODE_FULLSHAPE      :: DWORD
    iME_CMODE_FULLSHAPE      =  8
    iME_CMODE_HANJACONVERT   :: DWORD
    iME_CMODE_HANJACONVERT   =  64
    iME_CMODE_KATAKANA       :: DWORD
    iME_CMODE_KATAKANA       =  2
    iME_CMODE_NATIVE         :: DWORD
    iME_CMODE_NATIVE         =  1
    iME_CMODE_NOCONVERSION   :: DWORD
    iME_CMODE_NOCONVERSION   =  256
    iME_CMODE_ROMAN          :: DWORD
    iME_CMODE_ROMAN          =  16
    iME_CMODE_SOFTKBD        :: DWORD
    iME_CMODE_SOFTKBD        =  128
    iME_CMODE_SYMBOL         :: DWORD
    iME_CMODE_SYMBOL         =  1024

    {-# LINE 81 "libraries\\Win32\\Graphics\\Win32\\Window\\IMM.hsc" #-}

    iME_SMODE_AUTOMATIC      :: DWORD
    iME_SMODE_AUTOMATIC      =  4
    iME_SMODE_NONE           :: DWORD
    iME_SMODE_NONE           =  0
    iME_SMODE_PHRASEPREDICT  :: DWORD
    iME_SMODE_PHRASEPREDICT  =  8
    iME_SMODE_PLAURALCLAUSE  :: DWORD
    iME_SMODE_PLAURALCLAUSE  =  1
    iME_SMODE_SINGLECONVERT  :: DWORD
    iME_SMODE_SINGLECONVERT  =  2

    {-# LINE 89 "libraries\\Win32\\Graphics\\Win32\\Window\\IMM.hsc" #-}
    {-
     , iME_SMODE_CONVERSATION  = IME_SMODE_CONVERSATION
    -}

    immReleaseContext :: HWND -> HIMC -> IO ()
    immReleaseContext wnd imc =
      failIfFalse_ (unwords ["ImmSetOpenStatus", show wnd, show imc])
        $ c_ImmReleaseContext wnd imc

    foreign import WINDOWS_CCONV "windows.h ImmReleaseContext"
      c_ImmReleaseContext :: HWND -> HIMC -> IO BOOL

    foreign import WINDOWS_CCONV "windows.h ImmGetVirtualKey"
      immGetVirtualKey :: HWND -> IO VKey

    immSimulateHotKey :: HWND -> DWORD -> IO ()
    immSimulateHotKey hwd hkey =
      failIfFalse_ (unwords ["ImmSimulateHotKey", show hwd, show hkey])
        $ c_ImmSimulateHotKey hwd hkey

    foreign import WINDOWS_CCONV "windows.h ImmSimulateHotKey"
      c_ImmSimulateHotKey :: HWND -> DWORD -> IO BOOL