{-# LINE 1 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}

{-# LINE 2 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}
{-# LANGUAGE Safe #-}

{-# LINE 6 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Win32.Key
-- Copyright   :  (c) Alastair Reid, 1997-2003, 2013 shelarcy
-- 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.Key where

import Control.Monad (liftM)
import Graphics.Win32.GDI.Types (HWND)
import System.Win32.Types    ( DWORD, UINT, WORD, ptrToMaybe, BOOL, SHORT,
                               failIfFalse_, failIfZero )
import Control.Exception     ( bracket )
import Foreign.Ptr           ( Ptr, nullPtr )
import Foreign.C.Types       ( CWchar(..) )
import Foreign.Marshal.Array ( allocaArray, peekArray )
import System.Win32.String   ( LPTSTR, LPCTSTR
                             , withTString, withTStringBuffer, peekTString )
import System.Win32.Thread   ( TID, getCurrentThreadId )

#include "windows_cconv.h"


{-# LINE 37 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}

{-# LINE 38 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}

type VKey   = DWORD

vK_LBUTTON              :: VKey
vK_LBUTTON              =  1
vK_RBUTTON              :: VKey
vK_RBUTTON              =  2
vK_CANCEL               :: VKey
vK_CANCEL               =  3
vK_MBUTTON              :: VKey
vK_MBUTTON              =  4
vK_BACK                 :: VKey
vK_BACK                 =  8
vK_TAB                  :: VKey
vK_TAB                  =  9
vK_CLEAR                :: VKey
vK_CLEAR                =  12
vK_RETURN               :: VKey
vK_RETURN               =  13
vK_SHIFT                :: VKey
vK_SHIFT                =  16
vK_CONTROL              :: VKey
vK_CONTROL              =  17
vK_MENU                 :: VKey
vK_MENU                 =  18
vK_PAUSE                :: VKey
vK_PAUSE                =  19
vK_CAPITAL              :: VKey
vK_CAPITAL              =  20
vK_ESCAPE               :: VKey
vK_ESCAPE               =  27
vK_SPACE                :: VKey
vK_SPACE                =  32
vK_PRIOR                :: VKey
vK_PRIOR                =  33
vK_NEXT                 :: VKey
vK_NEXT                 =  34
vK_END                  :: VKey
vK_END                  =  35
vK_HOME                 :: VKey
vK_HOME                 =  36
vK_LEFT                 :: VKey
vK_LEFT                 =  37
vK_UP                   :: VKey
vK_UP                   =  38
vK_RIGHT                :: VKey
vK_RIGHT                =  39
vK_DOWN                 :: VKey
vK_DOWN                 =  40
vK_SELECT               :: VKey
vK_SELECT               =  41
vK_EXECUTE              :: VKey
vK_EXECUTE              =  43
vK_SNAPSHOT             :: VKey
vK_SNAPSHOT             =  44
vK_INSERT               :: VKey
vK_INSERT               =  45
vK_DELETE               :: VKey
vK_DELETE               =  46
vK_HELP                 :: VKey
vK_HELP                 =  47
vK_NUMPAD0              :: VKey
vK_NUMPAD0              =  96
vK_NUMPAD1              :: VKey
vK_NUMPAD1              =  97
vK_NUMPAD2              :: VKey
vK_NUMPAD2              =  98
vK_NUMPAD3              :: VKey
vK_NUMPAD3              =  99
vK_NUMPAD4              :: VKey
vK_NUMPAD4              =  100
vK_NUMPAD5              :: VKey
vK_NUMPAD5              =  101
vK_NUMPAD6              :: VKey
vK_NUMPAD6              =  102
vK_NUMPAD7              :: VKey
vK_NUMPAD7              =  103
vK_NUMPAD8              :: VKey
vK_NUMPAD8              =  104
vK_NUMPAD9              :: VKey
vK_NUMPAD9              =  105
vK_MULTIPLY             :: VKey
vK_MULTIPLY             =  106
vK_ADD                  :: VKey
vK_ADD                  =  107
vK_SEPARATOR            :: VKey
vK_SEPARATOR            =  108
vK_SUBTRACT             :: VKey
vK_SUBTRACT             =  109
vK_DECIMAL              :: VKey
vK_DECIMAL              =  110
vK_DIVIDE               :: VKey
vK_DIVIDE               =  111
vK_F1                   :: VKey
vK_F1                   =  112
vK_F2                   :: VKey
vK_F2                   =  113
vK_F3                   :: VKey
vK_F3                   =  114
vK_F4                   :: VKey
vK_F4                   =  115
vK_F5                   :: VKey
vK_F5                   =  116
vK_F6                   :: VKey
vK_F6                   =  117
vK_F7                   :: VKey
vK_F7                   =  118
vK_F8                   :: VKey
vK_F8                   =  119
vK_F9                   :: VKey
vK_F9                   =  120
vK_F10                  :: VKey
vK_F10                  =  121
vK_F11                  :: VKey
vK_F11                  =  122
vK_F12                  :: VKey
vK_F12                  =  123
vK_F13                  :: VKey
vK_F13                  =  124
vK_F14                  :: VKey
vK_F14                  =  125
vK_F15                  :: VKey
vK_F15                  =  126
vK_F16                  :: VKey
vK_F16                  =  127
vK_F17                  :: VKey
vK_F17                  =  128
vK_F18                  :: VKey
vK_F18                  =  129
vK_F19                  :: VKey
vK_F19                  =  130
vK_F20                  :: VKey
vK_F20                  =  131
vK_F21                  :: VKey
vK_F21                  =  132
vK_F22                  :: VKey
vK_F22                  =  133
vK_F23                  :: VKey
vK_F23                  =  134
vK_F24                  :: VKey
vK_F24                  =  135
vK_NUMLOCK              :: VKey
vK_NUMLOCK              =  144
vK_SCROLL               :: VKey
vK_SCROLL               =  145
vK_XBUTTON1            :: VKey
vK_XBUTTON1            =  5
vK_XBUTTON2             :: VKey
vK_XBUTTON2             =  6
vK_KANA                 :: VKey
vK_KANA                 =  21
vK_HANGUL               :: VKey
vK_HANGUL               =  21
vK_JUNJA                :: VKey
vK_JUNJA                =  23
vK_FINAL                :: VKey
vK_FINAL                =  24
vK_HANJA                :: VKey
vK_HANJA                =  25
vK_KANJI                :: VKey
vK_KANJI                =  25
vK_CONVERT              :: VKey
vK_CONVERT              =  28
vK_NONCONVERT           :: VKey
vK_NONCONVERT           =  29
vK_ACCEPT               :: VKey
vK_ACCEPT               =  30
vK_MODECHANGE           :: VKey
vK_MODECHANGE           =  31
vK_PRINT                :: VKey
vK_PRINT                =  42
vK_APPS                 :: VKey
vK_APPS                 =  93
vK_SLEEP                :: VKey
vK_SLEEP                =  95
vK_LWIN                 :: VKey
vK_LWIN                 =  91
vK_RWIN                 :: VKey
vK_RWIN                 =  92
vK_LSHIFT               :: VKey
vK_LSHIFT               =  160
vK_RSHIFT               :: VKey
vK_RSHIFT               =  161
vK_LCONTROL             :: VKey
vK_LCONTROL             =  162
vK_RCONTROL             :: VKey
vK_RCONTROL             =  163
vK_LMENU                :: VKey
vK_LMENU                =  164
vK_RMENU                :: VKey
vK_RMENU                =  165
vK_BROWSER_BACK         :: VKey
vK_BROWSER_BACK         =  166
vK_BROWSER_FORWARD      :: VKey
vK_BROWSER_FORWARD      =  167
vK_BROWSER_REFRESH      :: VKey
vK_BROWSER_REFRESH      =  168
vK_BROWSER_STOP         :: VKey
vK_BROWSER_STOP         =  169
vK_BROWSER_SEARCH       :: VKey
vK_BROWSER_SEARCH       =  170
vK_BROWSER_FAVORITES    :: VKey
vK_BROWSER_FAVORITES    =  171
vK_BROWSER_HOME         :: VKey
vK_BROWSER_HOME         =  172
vK_VOLUME_MUTE          :: VKey
vK_VOLUME_MUTE          =  173
vK_VOLUME_DOWN          :: VKey
vK_VOLUME_DOWN          =  174
vK_VOLUME_UP            :: VKey
vK_VOLUME_UP            =  175
vK_MEDIA_NEXT_TRACK     :: VKey
vK_MEDIA_NEXT_TRACK     =  176
vK_MEDIA_PREV_TRACK     :: VKey
vK_MEDIA_PREV_TRACK     =  177
vK_MEDIA_STOP           :: VKey
vK_MEDIA_STOP           =  178
vK_MEDIA_PLAY_PAUSE     :: VKey
vK_MEDIA_PLAY_PAUSE     =  179
vK_LAUNCH_MAIL          :: VKey
vK_LAUNCH_MAIL          =  180
vK_LAUNCH_MEDIA_SELECT  :: VKey
vK_LAUNCH_MEDIA_SELECT  =  181
vK_LAUNCH_APP1          :: VKey
vK_LAUNCH_APP1          =  182
vK_LAUNCH_APP2          :: VKey
vK_LAUNCH_APP2          =  183
vK_OEM_1                :: VKey
vK_OEM_1                =  186
vK_OEM_PLUS             :: VKey
vK_OEM_PLUS             =  187
vK_OEM_COMMA            :: VKey
vK_OEM_COMMA            =  188
vK_OEM_MINUS            :: VKey
vK_OEM_MINUS            =  189
vK_OEM_PERIOD           :: VKey
vK_OEM_PERIOD           =  190
vK_OEM_2                :: VKey
vK_OEM_2                =  191
vK_OEM_3                :: VKey
vK_OEM_3                =  192
vK_OEM_4                :: VKey
vK_OEM_4                =  219
vK_OEM_5                :: VKey
vK_OEM_5                =  220
vK_OEM_6                :: VKey
vK_OEM_6                =  221
vK_OEM_7                :: VKey
vK_OEM_7                =  222
vK_OEM_8                :: VKey
vK_OEM_8                =  223
vK_OEM_102              :: VKey
vK_OEM_102              =  226
vK_PROCESSKEY           :: VKey
vK_PROCESSKEY           =  229
vK_PACKET               :: VKey
vK_PACKET               =  231
vK_ATTN                 :: VKey
vK_ATTN                 =  246
vK_CRSEL                :: VKey
vK_CRSEL                =  247
vK_EXSEL                :: VKey
vK_EXSEL                =  248
vK_EREOF                :: VKey
vK_EREOF                =  249
vK_PLAY                 :: VKey
vK_PLAY                 =  250
vK_ZOOM                 :: VKey
vK_ZOOM                 =  251
vK_NONAME               :: VKey
vK_NONAME               =  252
vK_PA1                  :: VKey
vK_PA1                  =  253
vK_OEM_CLEAR            :: VKey
vK_OEM_CLEAR            =  254

{-# LINE 179 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}
foreign import WINDOWS_CCONV unsafe "windows.h VkKeyScanExW"
    c_VkKeyScanEx :: CWchar -> HKL -> IO SHORT

foreign import WINDOWS_CCONV unsafe "windows.h MapVirtualKeyW"
    c_MapVirtualKey :: VKey -> UINT -> IO UINT

foreign import WINDOWS_CCONV unsafe "windows.h MapVirtualKeyExW"
    c_MapVirtualKeyEx :: VKey -> UINT -> HKL -> IO UINT

foreign import WINDOWS_CCONV unsafe "windows.h EnableWindow"
  enableWindow :: HWND -> Bool -> IO Bool

getActiveWindow :: IO (Maybe HWND)
getActiveWindow = liftM ptrToMaybe c_GetActiveWindow
foreign import WINDOWS_CCONV unsafe "windows.h GetActiveWindow"
  c_GetActiveWindow :: IO HWND

foreign import WINDOWS_CCONV unsafe "windows.h GetAsyncKeyState"
  getAsyncKeyState :: Int -> IO WORD

getFocus :: IO (Maybe HWND)
getFocus = liftM ptrToMaybe c_GetFocus
foreign import WINDOWS_CCONV unsafe "windows.h GetFocus"
  c_GetFocus :: IO HWND

foreign import WINDOWS_CCONV unsafe "windows.h GetKBCodePage"
  getKBCodePage :: IO UINT

foreign import WINDOWS_CCONV unsafe "windows.h IsWindowEnabled"
  isWindowEnabled :: HWND -> IO Bool

getCurrentKeyboardLayout :: IO HKL
getCurrentKeyboardLayout = do
    tid <- getCurrentThreadId
    c_GetKeyboardLayout tid

getKeyboardLayoutList :: IO [HKL]
getKeyboardLayoutList = do
    len' <- failIfZero "GetKeyboardLayoutList" $ c_GetKeyboardLayoutList 0 nullPtr
    let len = fromIntegral len'
    allocaArray len $ \buf -> do
        _ <- failIfZero "GetKeyboardLayoutList" $ c_GetKeyboardLayoutList len  buf
        peekArray len buf

getKeyboardLayoutName :: IO String
getKeyboardLayoutName
  = withTStringBuffer 256 $ \buf -> do
       failIfFalse_ "GetKeyboardLayoutName" $ c_GetKeyboardLayoutName buf
       peekTString buf

withLoadKeyboardLayout :: KeyLayoutFlags -> (HKL -> IO a) -> IO a
withLoadKeyboardLayout flag io
  = withTStringBuffer 256 $ \buf -> do
       failIfFalse_ "GetKeyboardLayoutName" $ c_GetKeyboardLayoutName buf
       bracket (c_LoadKeyboardLayout buf flag)
               unloadKeyboardLayout
               io

withLoadKeyboardLayoutWithName :: String -> KeyLayoutFlags -> (HKL -> IO a) -> IO a
withLoadKeyboardLayoutWithName str flag io
  = withTString str $ \c_str ->
      bracket (c_LoadKeyboardLayout c_str flag)
              unloadKeyboardLayout
              io

unloadKeyboardLayout :: HKL -> IO ()
unloadKeyboardLayout
  = failIfFalse_ "UnloadKeyboardLayout" . c_UnloadKeyboardLayout

foreign import WINDOWS_CCONV unsafe "windows.h GetKeyboardLayout"
    c_GetKeyboardLayout :: TID -> IO HKL

foreign import WINDOWS_CCONV unsafe "windows.h GetKeyboardLayoutList"
    c_GetKeyboardLayoutList :: Int -> (Ptr HKL) -> IO UINT

foreign import WINDOWS_CCONV unsafe "windows.h GetKeyboardLayoutNameW"
    c_GetKeyboardLayoutName :: LPTSTR -> IO BOOL

foreign import WINDOWS_CCONV unsafe "windows.h LoadKeyboardLayoutW"
    c_LoadKeyboardLayout :: LPCTSTR  -> KeyLayoutFlags -> IO HKL

foreign import WINDOWS_CCONV unsafe "windows.h UnloadKeyboardLayout"
    c_UnloadKeyboardLayout :: HKL -> IO BOOL

type HKL = Ptr ()

type KeyLayoutFlags = UINT

kLF_ACTIVATE       :: KeyLayoutFlags
kLF_ACTIVATE       =  1
kLF_NOTELLSHELL    :: KeyLayoutFlags
kLF_NOTELLSHELL    =  128
kLF_REORDER        :: KeyLayoutFlags
kLF_REORDER        =  8
kLF_REPLACELANG    :: KeyLayoutFlags
kLF_REPLACELANG    =  16
kLF_SUBSTITUTE_OK  :: KeyLayoutFlags
kLF_SUBSTITUTE_OK  =  2
kLF_SETFORPROCESS  :: KeyLayoutFlags
kLF_SETFORPROCESS  =  256

{-# LINE 275 "libraries\\Win32\\Graphics\\Win32\\Key.hsc" #-}