{-# LINE 1 "System\\Win32\\Time\\Internal.hsc" #-}

{-# LINE 2 "System\\Win32\\Time\\Internal.hsc" #-}
{-# LANGUAGE Safe #-}

{-# LINE 6 "System\\Win32\\Time\\Internal.hsc" #-}
-----------------------------------------------------------------------------

-- |

-- Module      :  System.Win32.Time.Internal

-- Copyright   :  (c) Esa Ilari Vuokko, 2006

-- License     :  BSD-style (see the file LICENSE)

--

-- Maintainer  :  Esa Ilari Vuokko <ei@vuokko.info>

-- Stability   :  provisional

-- Portability :  portable

--

-- A collection of FFI declarations for interfacing with Win32 Time API.

--

-----------------------------------------------------------------------------

module System.Win32.Time.Internal where

import System.Win32.Types   ( BOOL, DDWORD, DWORD, HANDLE, LARGE_INTEGER, LCID
                            , LONG, LPCTSTR, LPCWSTR, LPTSTR, LPWSTR, UINT, WORD
                            , dwordsToDdword, ddwordToDwords
                            )
import Control.Monad    ( when )
import Data.Word        ( Word8 )
import Foreign          ( Storable(sizeOf, alignment, peekByteOff, peek,
                                   pokeByteOff, poke)
                        , Ptr, castPtr, plusPtr, advancePtr
                        , copyArray )
import Foreign.C        ( CInt(..), CWchar(..)
                        , peekCWString, withCWStringLen )

#include "windows_cconv.h"




----------------------------------------------------------------

-- data types

----------------------------------------------------------------


newtype FILETIME = FILETIME DDWORD deriving (Show, Eq, Ord)

data SYSTEMTIME = SYSTEMTIME {
    wYear, wMonth, wDayOfWeek, wDay, wHour, wMinute, wSecond, wMilliseconds :: WORD }
    deriving (Show, Eq, Ord)

data TIME_ZONE_INFORMATION = TIME_ZONE_INFORMATION
    { tziBias :: LONG
    , tziStandardName :: String
    , tziStandardDate :: SYSTEMTIME
    , tziStandardBias :: LONG
    , tziDaylightName :: String
    , tziDaylightDate :: SYSTEMTIME
    , tziDaylightBias :: LONG
    } deriving (Show,Eq,Ord)

data TimeZoneId = TzIdUnknown | TzIdStandard | TzIdDaylight
    deriving (Show, Eq, Ord)

data LASTINPUTINFO = LASTINPUTINFO DWORD deriving (Show)

----------------------------------------------------------------

-- Instances

----------------------------------------------------------------


instance Storable FILETIME where
    sizeOf = const ((8))
{-# LINE 70 "System\\Win32\\Time\\Internal.hsc" #-}
    alignment _ = 4
{-# LINE 71 "System\\Win32\\Time\\Internal.hsc" #-}
    poke buf (FILETIME n) = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) buf low
{-# LINE 73 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) buf hi
{-# LINE 74 "System\\Win32\\Time\\Internal.hsc" #-}
        where (hi,low) = ddwordToDwords n
    peek buf = do
        low <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) buf
{-# LINE 77 "System\\Win32\\Time\\Internal.hsc" #-}
        hi <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) buf
{-# LINE 78 "System\\Win32\\Time\\Internal.hsc" #-}
        return $ FILETIME $ dwordsToDdword (hi,low)

instance Storable SYSTEMTIME where
    sizeOf _ = (16)
{-# LINE 82 "System\\Win32\\Time\\Internal.hsc" #-}
    alignment _ = 2
{-# LINE 83 "System\\Win32\\Time\\Internal.hsc" #-}
    poke buf st = do
         ((\hsc_ptr -> pokeByteOff hsc_ptr 0))          buf (wYear st)
{-# LINE 85 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 2))         buf (wMonth st)
{-# LINE 86 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 4))     buf (wDayOfWeek st)
{-# LINE 87 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 6))           buf (wDay st)
{-# LINE 88 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 8))          buf (wHour st)
{-# LINE 89 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 10))        buf (wMinute st)
{-# LINE 90 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 12))        buf (wSecond st)
{-# LINE 91 "System\\Win32\\Time\\Internal.hsc" #-}
         ((\hsc_ptr -> pokeByteOff hsc_ptr 14))  buf (wMilliseconds st)
{-# LINE 92 "System\\Win32\\Time\\Internal.hsc" #-}
    peek buf = do
        year    <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))        buf
{-# LINE 94 "System\\Win32\\Time\\Internal.hsc" #-}
        month   <- ((\hsc_ptr -> peekByteOff hsc_ptr 2))       buf
{-# LINE 95 "System\\Win32\\Time\\Internal.hsc" #-}
        dow     <- ((\hsc_ptr -> peekByteOff hsc_ptr 4))   buf
{-# LINE 96 "System\\Win32\\Time\\Internal.hsc" #-}
        day     <- ((\hsc_ptr -> peekByteOff hsc_ptr 6))         buf
{-# LINE 97 "System\\Win32\\Time\\Internal.hsc" #-}
        hour    <- ((\hsc_ptr -> peekByteOff hsc_ptr 8))        buf
{-# LINE 98 "System\\Win32\\Time\\Internal.hsc" #-}
        mins    <- ((\hsc_ptr -> peekByteOff hsc_ptr 10))      buf
{-# LINE 99 "System\\Win32\\Time\\Internal.hsc" #-}
        sec     <- ((\hsc_ptr -> peekByteOff hsc_ptr 12))      buf
{-# LINE 100 "System\\Win32\\Time\\Internal.hsc" #-}
        ms      <- ((\hsc_ptr -> peekByteOff hsc_ptr 14)) buf
{-# LINE 101 "System\\Win32\\Time\\Internal.hsc" #-}
        return $ SYSTEMTIME year month dow day hour mins sec ms

instance Storable TIME_ZONE_INFORMATION where
    sizeOf _ = ((172))
{-# LINE 105 "System\\Win32\\Time\\Internal.hsc" #-}
    alignment _ = 4
{-# LINE 106 "System\\Win32\\Time\\Internal.hsc" #-}
    poke buf tzi = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) buf (tziBias tzi)
{-# LINE 108 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 68)) buf (tziStandardDate tzi)
{-# LINE 109 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 84)) buf (tziStandardBias tzi)
{-# LINE 110 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 152)) buf (tziDaylightDate tzi)
{-# LINE 111 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 168)) buf (tziDaylightBias tzi)
{-# LINE 112 "System\\Win32\\Time\\Internal.hsc" #-}
        write buf ((4)) (tziStandardName tzi)
{-# LINE 113 "System\\Win32\\Time\\Internal.hsc" #-}
        write buf ((88)) (tziDaylightName tzi)
{-# LINE 114 "System\\Win32\\Time\\Internal.hsc" #-}
        where
            write buf_ offset str = withCWStringLen str $ \(c_str,len) -> do
                when (len>31) $ fail "Storable TIME_ZONE_INFORMATION.poke: Too long string."
                let len'  = len * sizeOf (undefined :: CWchar)
                    start = (advancePtr (castPtr buf_) offset)
                    end   = advancePtr start len'
                copyArray start (castPtr c_str :: Ptr Word8) len'
                poke (castPtr end) (0 :: CWchar)

    peek buf = do
        bias <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))         buf
{-# LINE 125 "System\\Win32\\Time\\Internal.hsc" #-}
        sdat <- ((\hsc_ptr -> peekByteOff hsc_ptr 68)) buf
{-# LINE 126 "System\\Win32\\Time\\Internal.hsc" #-}
        sbia <- ((\hsc_ptr -> peekByteOff hsc_ptr 84)) buf
{-# LINE 127 "System\\Win32\\Time\\Internal.hsc" #-}
        ddat <- ((\hsc_ptr -> peekByteOff hsc_ptr 152)) buf
{-# LINE 128 "System\\Win32\\Time\\Internal.hsc" #-}
        dbia <- ((\hsc_ptr -> peekByteOff hsc_ptr 168)) buf
{-# LINE 129 "System\\Win32\\Time\\Internal.hsc" #-}
        snam <- peekCWString (plusPtr buf ((4)))
{-# LINE 130 "System\\Win32\\Time\\Internal.hsc" #-}
        dnam <- peekCWString (plusPtr buf ((88)))
{-# LINE 131 "System\\Win32\\Time\\Internal.hsc" #-}
        return $ TIME_ZONE_INFORMATION bias snam sdat sbia dnam ddat dbia

instance Storable LASTINPUTINFO where
    sizeOf = const ((8))
{-# LINE 135 "System\\Win32\\Time\\Internal.hsc" #-}
    alignment = sizeOf
    poke buf (LASTINPUTINFO t) = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) buf (((8)) :: UINT)
{-# LINE 138 "System\\Win32\\Time\\Internal.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) buf t
{-# LINE 139 "System\\Win32\\Time\\Internal.hsc" #-}
    peek buf = do
        t <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) buf
{-# LINE 141 "System\\Win32\\Time\\Internal.hsc" #-}
        return $ LASTINPUTINFO t

foreign import WINDOWS_CCONV "windows.h GetSystemTime"
    c_GetSystemTime :: Ptr SYSTEMTIME -> IO ()

foreign import WINDOWS_CCONV "windows.h SetSystemTime"
    c_SetSystemTime :: Ptr SYSTEMTIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h GetSystemTimeAsFileTime"
    c_GetSystemTimeAsFileTime :: Ptr FILETIME -> IO ()

foreign import WINDOWS_CCONV "windows.h GetLocalTime"
    c_GetLocalTime :: Ptr SYSTEMTIME -> IO ()

foreign import WINDOWS_CCONV "windows.h SetLocalTime"
    c_SetLocalTime :: Ptr SYSTEMTIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h GetSystemTimeAdjustment"
    c_GetSystemTimeAdjustment :: Ptr DWORD -> Ptr DWORD -> Ptr BOOL -> IO BOOL

foreign import WINDOWS_CCONV "windows.h GetTickCount" getTickCount :: IO DWORD

foreign import WINDOWS_CCONV unsafe "windows.h GetLastInputInfo"
  c_GetLastInputInfo :: Ptr LASTINPUTINFO -> IO Bool

foreign import WINDOWS_CCONV "windows.h SetSystemTimeAdjustment"
    c_SetSystemTimeAdjustment :: DWORD -> BOOL -> IO BOOL

foreign import WINDOWS_CCONV "windows.h GetTimeZoneInformation"
    c_GetTimeZoneInformation :: Ptr TIME_ZONE_INFORMATION -> IO DWORD

foreign import WINDOWS_CCONV "windows.h SystemTimeToFileTime"
    c_SystemTimeToFileTime :: Ptr SYSTEMTIME -> Ptr FILETIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h FileTimeToSystemTime"
    c_FileTimeToSystemTime :: Ptr FILETIME -> Ptr SYSTEMTIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h GetFileTime"
    c_GetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h SetFileTime"
    c_SetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h FileTimeToLocalFileTime"
    c_FileTimeToLocalFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL

foreign import WINDOWS_CCONV "windows.h LocalFileTimeToFileTime"
    c_LocalFileTimeToFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL

{-
-- Windows XP SP1
foreign import WINDOWS_CCONV "windows.h GetSystemTimes"
    c_GetSystemTimes :: Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL
getSystemTimes :: IO (FILETIME,FILETIME,FILETIME)
getSystemTimes = alloca $ \idle -> alloca $ \kernel -> alloca $ \user -> do
    failIf not "getSystemTimes: GetSystemTimes" $ c_GetSystemTimes idle kernel user
    liftM3 (,,) (peek idle) (peek kernel) (peek user)
-}

{-
-- Windows XP
foreign import WINDOWS_CCONV "windows.h SystemTimeToTzSpecificLocalTime"
    c_SystemTimeToTzSpecificLocalTime :: Ptr TIME_ZONE_INFORMATION -> Ptr SYSTEMTIME -> Ptr SYSTEMTIME -> IO BOOL
systemTimeToTzSpecificLocalTime :: TIME_ZONE_INFORMATION -> SYSTEMTIME -> IO SYSTEMTIME
systemTimeToTzSpecificLocalTime tzi st = with tzi $ \tzi -> with st $ \st -> alloca $ \res -> do
    failIf not "systemTimeToTzSpecificLocalTime: SystemTimeToTzSpecificLocalTime" $
        c_SystemTimeToTzSpecificLocalTime tzi st res
    peek res

foreign import WINDOWS_CCONV "windows.h TzSpecificLocalTimeToSystemTime"
    c_TzSpecificLocalTimeToSystemTime :: Ptr TIME_ZONE_INFORMATION -> Ptr SYSTEMTIME -> Ptr SYSTEMTIME -> IO BOOL
tzSpecificLocalTimeToSystemTime :: TIME_ZONE_INFORMATION -> SYSTEMTIME -> IO SYSTEMTIME
tzSpecificLocalTimeToSystemTime tzi st = with tzi $ \tzi -> with st $ \st -> alloca $ \res -> do
    failIf not "tzSpecificLocalTimeToSystemTime: TzSpecificLocalTimeToSystemTime" $
        c_TzSpecificLocalTimeToSystemTime tzi st res
    peek res
-}

foreign import WINDOWS_CCONV "windows.h QueryPerformanceFrequency"
    c_QueryPerformanceFrequency :: Ptr LARGE_INTEGER -> IO BOOL

foreign import WINDOWS_CCONV "windows.h QueryPerformanceCounter"
    c_QueryPerformanceCounter:: Ptr LARGE_INTEGER -> IO BOOL

type GetTimeFormatFlags = DWORD
lOCALE_NOUSEROVERRIDE  :: GetTimeFormatFlags
lOCALE_NOUSEROVERRIDE  =  2147483648
lOCALE_USE_CP_ACP      :: GetTimeFormatFlags
lOCALE_USE_CP_ACP      =  1073741824
tIME_NOMINUTESORSECONDS  :: GetTimeFormatFlags
tIME_NOMINUTESORSECONDS  =  1
tIME_NOSECONDS         :: GetTimeFormatFlags
tIME_NOSECONDS         =  2
tIME_NOTIMEMARKER      :: GetTimeFormatFlags
tIME_NOTIMEMARKER      =  4
tIME_FORCE24HOURFORMAT :: GetTimeFormatFlags
tIME_FORCE24HOURFORMAT =  8

{-# LINE 234 "System\\Win32\\Time\\Internal.hsc" #-}

foreign import WINDOWS_CCONV "windows.h GetTimeFormatEx"
    c_GetTimeFormatEx :: LPCWSTR
                      -> GetTimeFormatFlags
                      -> Ptr SYSTEMTIME
                      -> LPCWSTR
                      -> LPWSTR
                      -> CInt
                      -> IO CInt

foreign import WINDOWS_CCONV "windows.h GetTimeFormatW"
    c_GetTimeFormat :: LCID -> GetTimeFormatFlags -> Ptr SYSTEMTIME -> LPCTSTR -> LPTSTR -> CInt -> IO CInt