module Graphics.XHB.Connection.Internal
(sendRequest
,sendRequestWithReply
,lookupExtension
,cacheExtension
,Connection
) where
import Data.Word(Word16)
import Control.Exception(bracket)
import Control.Concurrent.STM
import Control.Concurrent
import System.IO
import Data.ByteString.Lazy(ByteString)
import qualified Data.ByteString.Lazy as BS
import Data.Maybe
import qualified Data.Map as M
import Graphics.XHB.Connection.Types
import Graphics.XHB.Shared
import Graphics.XHB.Gen.Xproto.Types
sendRequest :: Connection -> ByteString -> IO ()
sendRequest c bytes = withConnectionHandle c $ \h -> do
BS.hPut h bytes
_ <- atomically $ nextSequence c
return ()
sendRequestWithReply :: Connection -> ByteString -> RawReceipt -> IO ()
sendRequestWithReply c bytes r = withConnectionHandle c $ \h -> do
BS.hPut h bytes
atomically $ do
seq <- nextSequence c
writeTChan (conn_reps c) $ PendedReply seq r
nextSequence :: Connection -> STM SequenceId
nextSequence c = do
let tv = conn_next_sequence c
seq <- readTVar tv
writeTVar tv (seq + 1)
return seq
withConnectionHandle :: Connection -> (Handle -> IO a) -> IO a
withConnectionHandle c f = do
let mv = conn_handle c
bracket
(takeMVar mv)
(putMVar mv)
f
lookupExtension :: Connection -> ExtensionId -> IO (Maybe QueryExtensionReply)
lookupExtension c extId = atomically $ do
m <- readTVar $ conn_extensions c
return $ M.lookup extId m
cacheExtension :: Connection -> ExtensionId -> QueryExtensionReply -> IO ()
cacheExtension c extId ext = atomically $ do
let tv = conn_extensions c
m <- readTVar tv
if isNothing (M.lookup extId m)
then
let m' = M.insert extId ext m
in writeTVar tv m'
else return ()