module Graphics.Wayland.Internal.Server (
  ClientState(..), clientStateReadable, clientStateWritable, clientStateHangup,
  clientStateError,
  EventLoop, EventSource,
  EventLoopFdFunc, EventLoopTimerFunc, EventLoopSignalFunc, EventLoopIdleFunc,
  eventLoopCreate, eventLoopDestroy, eventLoopAddFd, eventSourceFdUpdate,
  eventLoopAddTimer, eventLoopAddSignal, eventSourceTimerUpdate, eventSourceRemove,
  eventSourceCheck, eventLoopDispatch, eventLoopDispatchIdle, eventLoopAddIdle, eventLoopGetFd,
  DisplayServer, displayCreate, displayDestroy, displayGetEventLoop, displayAddSocket,
  displayTerminate, displayRun, displayFlushClients, displayGetSerial, displayNextSerial,
  clientCreate, clientDestroy, clientFlush, clientGetCredentials, clientPostNoMemory,
  ShmBuffer, shmBufferBeginAccess, shmBufferEndAccess, shmBufferGet, shmBufferGetData,
  shmBufferGetStride, shmBufferGetFormat, shmBufferGetWidth, shmBufferGetHeight,
  displayInitShm, displayAddShmFormat, shmBufferCreate
  ) where
import Control.Monad (liftM)
import Data.Functor ((<$>))
import Data.Flags
import Data.Flags.TH
import Foreign
import Foreign.C.Types
import Foreign.C.String
import System.Posix.Types
import Graphics.Wayland.Internal.ServerClientState 
import Graphics.Wayland.Internal.SpliceServerInternal
import Graphics.Wayland.Internal.SpliceServer
import Graphics.Wayland.Internal.SpliceServerTypes
import Graphics.Wayland.Internal.Util (Client(..))
import Graphics.Wayland
boolToCInt :: Bool -> CInt
boolToCInt True = 1
boolToCInt False = 0
unFd :: Fd -> CInt
unFd (Fd n) = n
makeWith :: (a -> IO b) -> (a -> (b -> IO c) -> IO c)
makeWith func = \ a f -> do
  b <- func a
  f b
makeWith' :: b -> (b -> IO c) -> IO c
makeWith' b f = f b
withNullPtr = makeWith' nullPtr
$(bitmaskWrapper "ClientState" ''CUInt [''Num, ''Integral, ''Real, ''Enum, ''Ord] [
  ("clientStateReadable", fromIntegral $ fromEnum ClientReadable),
  ("clientStateWritable", fromIntegral $  fromEnum ClientWritable),
  ("clientStateHangup",   fromIntegral $  fromEnum ClientHangup),
  ("clientStateError",    fromIntegral $  fromEnum ClientError)
  ])
newtype EventLoop = EventLoop (Ptr (EventLoop))
newtype EventSource = EventSource (Ptr (EventSource))
type CEventLoopFdFunc = CInt -> (CUInt) -> Ptr () -> IO CInt
type EventLoopFdFunc = Int -> ClientState -> IO Bool
foreign import ccall unsafe "wrapper" makeFdFunPtr :: CEventLoopFdFunc -> IO (FunPtr CEventLoopFdFunc)
marshallEventLoopFdFunc :: EventLoopFdFunc -> IO (FunPtr CEventLoopFdFunc)
marshallEventLoopFdFunc func = makeFdFunPtr $ \ fd mask _ -> boolToCInt <$> func (fromIntegral fd) (fromIntegral mask)
melff = makeWith marshallEventLoopFdFunc
type CEventLoopTimerFunc = Ptr () -> IO CInt
type EventLoopTimerFunc = IO Bool
foreign import ccall unsafe "wrapper" makeTimerFunPtr :: CEventLoopTimerFunc -> IO (FunPtr CEventLoopTimerFunc)
marshallEventLoopTimerFunc :: EventLoopTimerFunc -> IO (FunPtr CEventLoopTimerFunc)
marshallEventLoopTimerFunc func = makeTimerFunPtr $ \ _ -> boolToCInt <$> func
meltf = makeWith marshallEventLoopTimerFunc
type CEventLoopSignalFunc = CInt -> Ptr () -> IO CInt
type EventLoopSignalFunc = Int -> IO Bool
foreign import ccall unsafe "wrapper" makeSignalFunPtr :: CEventLoopSignalFunc -> IO (FunPtr CEventLoopSignalFunc)
marshallEventLoopSignalFunc :: EventLoopSignalFunc -> IO (FunPtr CEventLoopSignalFunc)
marshallEventLoopSignalFunc func = makeSignalFunPtr $ \ x _ -> boolToCInt <$> func (fromIntegral x)
melsf = makeWith marshallEventLoopSignalFunc
type CEventLoopIdleFunc = Ptr () -> IO ()
type EventLoopIdleFunc = IO ()
foreign import ccall unsafe "wrapper" makeIdleFunPtr :: CEventLoopIdleFunc -> IO (FunPtr CEventLoopIdleFunc)
marshallEventLoopIdleFunc :: EventLoopIdleFunc -> IO (FunPtr CEventLoopIdleFunc)
marshallEventLoopIdleFunc func = makeIdleFunPtr $ \ _ -> func
melif = makeWith marshallEventLoopIdleFunc
eventLoopCreate :: IO ((EventLoop))
eventLoopCreate =
  eventLoopCreate'_ >>= \res ->
  let {res' = id res} in
  return (res')
eventLoopDestroy :: (EventLoop) -> IO ()
eventLoopDestroy a1 =
  let {a1' = id a1} in 
  eventLoopDestroy'_ a1' >>
  return ()
eventLoopAddFd :: (EventLoop) -> (Fd) -> (ClientState) -> (EventLoopFdFunc) -> IO ((EventSource))
eventLoopAddFd a1 a2 a3 a4 =
  let {a1' = id a1} in 
  let {a2' = unFd a2} in 
  let {a3' = fromIntegral a3} in 
  melff a4 $ \a4' -> 
  withNullPtr $ \a5' -> 
  eventLoopAddFd'_ a1' a2' a3' a4' a5' >>= \res ->
  let {res' = id res} in
  return (res')
eventSourceFdUpdate :: (EventSource) -> (ClientState) -> IO ((Result))
eventSourceFdUpdate a1 a2 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  eventSourceFdUpdate'_ a1' a2' >>= \res ->
  let {res' = errToResult res} in
  return (res')
eventLoopAddTimer :: (EventLoop) -> (EventLoopTimerFunc) -> IO ((EventSource))
eventLoopAddTimer a1 a2 =
  let {a1' = id a1} in 
  meltf a2 $ \a2' -> 
  withNullPtr $ \a3' -> 
  eventLoopAddTimer'_ a1' a2' a3' >>= \res ->
  let {res' = id res} in
  return (res')
eventLoopAddSignal :: (EventLoop) -> (Int) -> (EventLoopSignalFunc) -> IO ((EventSource))
eventLoopAddSignal a1 a2 a3 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  melsf a3 $ \a3' -> 
  withNullPtr $ \a4' -> 
  eventLoopAddSignal'_ a1' a2' a3' a4' >>= \res ->
  let {res' = id res} in
  return (res')
eventSourceTimerUpdate :: (EventSource) -> (Int) -> IO ((Result))
eventSourceTimerUpdate a1 a2 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  eventSourceTimerUpdate'_ a1' a2' >>= \res ->
  let {res' = errToResult res} in
  return (res')
eventSourceRemove :: (EventSource) -> IO ()
eventSourceRemove a1 =
  let {a1' = id a1} in 
  eventSourceRemove'_ a1' >>
  return ()
eventSourceCheck :: (EventSource) -> IO ()
eventSourceCheck a1 =
  let {a1' = id a1} in 
  eventSourceCheck'_ a1' >>
  return ()
eventLoopDispatch :: (EventLoop) -> (Int) -> IO ((Result))
eventLoopDispatch a1 a2 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  eventLoopDispatch'_ a1' a2' >>= \res ->
  let {res' = errToResult res} in
  return (res')
eventLoopDispatchIdle :: (EventLoop) -> IO ()
eventLoopDispatchIdle a1 =
  let {a1' = id a1} in 
  eventLoopDispatchIdle'_ a1' >>
  return ()
eventLoopAddIdle :: (EventLoop) -> (EventLoopIdleFunc) -> IO ((EventSource))
eventLoopAddIdle a1 a2 =
  let {a1' = id a1} in 
  melif a2 $ \a2' -> 
  withNullPtr $ \a3' -> 
  eventLoopAddIdle'_ a1' a2' a3' >>= \res ->
  let {res' = id res} in
  return (res')
eventLoopGetFd :: (EventLoop) -> IO ((Fd))
eventLoopGetFd a1 =
  let {a1' = id a1} in 
  eventLoopGetFd'_ a1' >>= \res ->
  let {res' = Fd res} in
  return (res')
receiveMaybeClient :: Client -> Maybe Client
receiveMaybeClient (Client x)
  | x == nullPtr = Nothing
  | otherwise    = Just (Client x)
newtype DisplayServer = DisplayServer (Ptr (DisplayServer))
displayCreate :: IO ((DisplayServer))
displayCreate =
  displayCreate'_ >>= \res ->
  let {res' = id res} in
  return (res')
displayDestroy :: (DisplayServer) -> IO ()
displayDestroy a1 =
  let {a1' = id a1} in 
  displayDestroy'_ a1' >>
  return ()
displayGetEventLoop :: (DisplayServer) -> IO ((EventLoop))
displayGetEventLoop a1 =
  let {a1' = id a1} in 
  displayGetEventLoop'_ a1' >>= \res ->
  let {res' = id res} in
  return (res')
withMaybeCString :: Maybe String -> (CString -> IO a) -> IO a
withMaybeCString Nothing fun = fun nullPtr
withMaybeCString (Just str) fun = withCString str fun
displayAddSocket :: (DisplayServer) -> (Maybe String) -> IO ((Result))
displayAddSocket a1 a2 =
  let {a1' = id a1} in 
  withMaybeCString a2 $ \a2' -> 
  displayAddSocket'_ a1' a2' >>= \res ->
  let {res' = errToResult res} in
  return (res')
displayTerminate :: (DisplayServer) -> IO ()
displayTerminate a1 =
  let {a1' = id a1} in 
  displayTerminate'_ a1' >>
  return ()
displayRun :: (DisplayServer) -> IO ()
displayRun a1 =
  let {a1' = id a1} in 
  displayRun'_ a1' >>
  return ()
displayFlushClients :: (DisplayServer) -> IO ()
displayFlushClients a1 =
  let {a1' = id a1} in 
  displayFlushClients'_ a1' >>
  return ()
displayGetSerial :: (DisplayServer) -> IO ((Word))
displayGetSerial a1 =
  let {a1' = id a1} in 
  displayGetSerial'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
displayNextSerial :: (DisplayServer) -> IO ((Word))
displayNextSerial a1 =
  let {a1' = id a1} in 
  displayNextSerial'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
clientCreate :: (DisplayServer) -> (Fd) -> IO ((Maybe Client))
clientCreate a1 a2 =
  let {a1' = id a1} in 
  let {a2' = unFd a2} in 
  clientCreate'_ a1' a2' >>= \res ->
  let {res' = receiveMaybeClient res} in
  return (res')
clientDestroy :: (Client) -> IO ()
clientDestroy a1 =
  let {a1' = id a1} in 
  clientDestroy'_ a1' >>
  return ()
clientFlush :: (Client) -> IO ()
clientFlush a1 =
  let {a1' = id a1} in 
  clientFlush'_ a1' >>
  return ()
peekPid = liftM CPid . liftM fromIntegral . peek
peekUid = liftM CUid . liftM fromIntegral . peek
peekGid = liftM CGid . liftM fromIntegral . peek
clientGetCredentials :: (Client) -> IO ((ProcessID), (UserID), (GroupID))
clientGetCredentials a1 =
  let {a1' = id a1} in 
  alloca $ \a2' -> 
  alloca $ \a3' -> 
  alloca $ \a4' -> 
  clientGetCredentials'_ a1' a2' a3' a4' >>
  peekPid  a2'>>= \a2'' -> 
  peekUid  a3'>>= \a3'' -> 
  peekGid  a4'>>= \a4'' -> 
  return (a2'', a3'', a4'')
clientPostNoMemory :: (Client) -> IO ()
clientPostNoMemory a1 =
  let {a1' = id a1} in 
  clientPostNoMemory'_ a1' >>
  return ()
newtype ShmBuffer = ShmBuffer (Ptr (ShmBuffer))
receiveMaybeShmBuffer :: ShmBuffer -> Maybe ShmBuffer
receiveMaybeShmBuffer (ShmBuffer x)
  | x == nullPtr = Nothing
  | otherwise    = Just (ShmBuffer x)
shmBufferBeginAccess :: (ShmBuffer) -> IO ()
shmBufferBeginAccess a1 =
  let {a1' = id a1} in 
  shmBufferBeginAccess'_ a1' >>
  return ()
shmBufferEndAccess :: (ShmBuffer) -> IO ()
shmBufferEndAccess a1 =
  let {a1' = id a1} in 
  shmBufferEndAccess'_ a1' >>
  return ()
shmBufferGet :: (Buffer) -> IO ((Maybe ShmBuffer))
shmBufferGet a1 =
  let {a1' = id a1} in 
  shmBufferGet'_ a1' >>= \res ->
  let {res' = receiveMaybeShmBuffer res} in
  return (res')
shmBufferGetData :: (ShmBuffer) -> IO ((Ptr ()))
shmBufferGetData a1 =
  let {a1' = id a1} in 
  shmBufferGetData'_ a1' >>= \res ->
  let {res' = id res} in
  return (res')
shmBufferGetStride :: (ShmBuffer) -> IO ((Int))
shmBufferGetStride a1 =
  let {a1' = id a1} in 
  shmBufferGetStride'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
shmBufferGetFormat :: (ShmBuffer) -> IO ((Word))
shmBufferGetFormat a1 =
  let {a1' = id a1} in 
  shmBufferGetFormat'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
shmBufferGetWidth :: (ShmBuffer) -> IO ((Int))
shmBufferGetWidth a1 =
  let {a1' = id a1} in 
  shmBufferGetWidth'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
shmBufferGetHeight :: (ShmBuffer) -> IO ((Int))
shmBufferGetHeight a1 =
  let {a1' = id a1} in 
  shmBufferGetHeight'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')
displayInitShm :: (DisplayServer) -> IO ((Result))
displayInitShm a1 =
  let {a1' = id a1} in 
  displayInitShm'_ a1' >>= \res ->
  let {res' = errToResult res} in
  return (res')
displayAddShmFormat :: (DisplayServer) -> (Word) -> IO ()
displayAddShmFormat a1 a2 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  displayAddShmFormat'_ a1' a2' >>
  return ()
shmBufferCreate :: (Client) -> (Word) -> (Word) -> (Int) -> (Int) -> (Word) -> IO ((Maybe ShmBuffer))
shmBufferCreate a1 a2 a3 a4 a5 a6 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  let {a3' = fromIntegral a3} in 
  let {a4' = fromIntegral a4} in 
  let {a5' = fromIntegral a5} in 
  let {a6' = fromIntegral a6} in 
  shmBufferCreate'_ a1' a2' a3' a4' a5' a6' >>= \res ->
  let {res' = receiveMaybeShmBuffer res} in
  return (res')
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_create"
  eventLoopCreate'_ :: (IO (EventLoop))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_destroy"
  eventLoopDestroy'_ :: ((EventLoop) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_add_fd"
  eventLoopAddFd'_ :: ((EventLoop) -> (CInt -> (CUInt -> ((FunPtr (CInt -> (CUInt -> ((Ptr ()) -> (IO CInt))))) -> ((Ptr ()) -> (IO (EventSource)))))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_source_fd_update"
  eventSourceFdUpdate'_ :: ((EventSource) -> (CUInt -> (IO CInt)))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_add_timer"
  eventLoopAddTimer'_ :: ((EventLoop) -> ((FunPtr ((Ptr ()) -> (IO CInt))) -> ((Ptr ()) -> (IO (EventSource)))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_add_signal"
  eventLoopAddSignal'_ :: ((EventLoop) -> (CInt -> ((FunPtr (CInt -> ((Ptr ()) -> (IO CInt)))) -> ((Ptr ()) -> (IO (EventSource))))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_source_timer_update"
  eventSourceTimerUpdate'_ :: ((EventSource) -> (CInt -> (IO CInt)))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_source_remove"
  eventSourceRemove'_ :: ((EventSource) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_source_check"
  eventSourceCheck'_ :: ((EventSource) -> (IO ()))
foreign import ccall safe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_dispatch"
  eventLoopDispatch'_ :: ((EventLoop) -> (CInt -> (IO CInt)))
foreign import ccall safe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_dispatch_idle"
  eventLoopDispatchIdle'_ :: ((EventLoop) -> (IO ()))
foreign import ccall safe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_add_idle"
  eventLoopAddIdle'_ :: ((EventLoop) -> ((FunPtr ((Ptr ()) -> (IO ()))) -> ((Ptr ()) -> (IO (EventSource)))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_event_loop_get_fd"
  eventLoopGetFd'_ :: ((EventLoop) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_create"
  displayCreate'_ :: (IO (DisplayServer))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_destroy"
  displayDestroy'_ :: ((DisplayServer) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_get_event_loop"
  displayGetEventLoop'_ :: ((DisplayServer) -> (IO (EventLoop)))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_add_socket"
  displayAddSocket'_ :: ((DisplayServer) -> ((Ptr CChar) -> (IO CInt)))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_terminate"
  displayTerminate'_ :: ((DisplayServer) -> (IO ()))
foreign import ccall safe "Graphics/Wayland/Internal/Server.chs.h wl_display_run"
  displayRun'_ :: ((DisplayServer) -> (IO ()))
foreign import ccall safe "Graphics/Wayland/Internal/Server.chs.h wl_display_flush_clients"
  displayFlushClients'_ :: ((DisplayServer) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_get_serial"
  displayGetSerial'_ :: ((DisplayServer) -> (IO CUInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_next_serial"
  displayNextSerial'_ :: ((DisplayServer) -> (IO CUInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_client_create"
  clientCreate'_ :: ((DisplayServer) -> (CInt -> (IO (Client))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_client_destroy"
  clientDestroy'_ :: ((Client) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_client_flush"
  clientFlush'_ :: ((Client) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_client_get_credentials"
  clientGetCredentials'_ :: ((Client) -> ((Ptr CInt) -> ((Ptr CUInt) -> ((Ptr CUInt) -> (IO ())))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_client_post_no_memory"
  clientPostNoMemory'_ :: ((Client) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_begin_access"
  shmBufferBeginAccess'_ :: ((ShmBuffer) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_end_access"
  shmBufferEndAccess'_ :: ((ShmBuffer) -> (IO ()))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get"
  shmBufferGet'_ :: ((Buffer) -> (IO (ShmBuffer)))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get_data"
  shmBufferGetData'_ :: ((ShmBuffer) -> (IO (Ptr ())))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get_stride"
  shmBufferGetStride'_ :: ((ShmBuffer) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get_format"
  shmBufferGetFormat'_ :: ((ShmBuffer) -> (IO CUInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get_width"
  shmBufferGetWidth'_ :: ((ShmBuffer) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_get_height"
  shmBufferGetHeight'_ :: ((ShmBuffer) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_init_shm"
  displayInitShm'_ :: ((DisplayServer) -> (IO CInt))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_display_add_shm_format"
  displayAddShmFormat'_ :: ((DisplayServer) -> (CUInt -> (IO (Ptr CUInt))))
foreign import ccall unsafe "Graphics/Wayland/Internal/Server.chs.h wl_shm_buffer_create"
  shmBufferCreate'_ :: ((Client) -> (CUInt -> (CInt -> (CInt -> (CInt -> (CUInt -> (IO (ShmBuffer))))))))