module Sound.ALSA.Sequencer.Subscribe.Query
( T
, Query.Type(..)
, getClient
, getPort
, getRoot
, getType
, getIndex
, getNumSubs
, getAddr
, getQueue
, getExclusive
, getTimeUpdate
, getTimeReal
, query
, queryAll
) where
import qualified Sound.ALSA.Sequencer.Marshal.QuerySubscribe as Query
import qualified Sound.ALSA.Sequencer.Marshal.Sequencer as Seq
import qualified Sound.ALSA.Sequencer.Area as Area
import qualified Sound.ALSA.Sequencer.Marshal.Address as Addr
import qualified Sound.ALSA.Sequencer.Marshal.Client as Client
import qualified Sound.ALSA.Sequencer.Marshal.Port as Port
import qualified Sound.ALSA.Sequencer.Marshal.Queue as Queue
import qualified Sound.ALSA.Exception as Exc
import Foreign.C.Error (Errno(Errno), eNOENT, )
import Foreign.C.Types (CInt, )
import Foreign.Ptr (Ptr, )
import Foreign.Marshal.Alloc (alloca, )
import Foreign.Storable (peek, poke, )
import Data.Word (Word, )
type T = Area.QuerySubscribe
type T_ = Area.QuerySubscribe_
alloc :: IO T
_copy :: T -> T -> IO ()
_clone :: T -> IO T
getClient :: T -> IO Client.T
getPort :: T -> IO Port.T
getType :: T -> IO Query.Type
getIndex :: T -> IO Word
getNumSubs :: T -> IO Word
getQueue :: T -> IO Queue.T
getExclusive :: T -> IO Bool
getTimeUpdate :: T -> IO Bool
getTimeReal :: T -> IO Bool
_setClient :: T -> Client.T -> IO ()
_setPort :: T -> Port.T -> IO ()
setType :: T -> Query.Type -> IO ()
setIndex :: T -> Word -> IO ()
alloc = Area.query_subscribe_malloc
_copy = Area.query_subscribe_copy
_clone = Area.query_subscribe_clone
getClient = Area.query_subscribe_get_client
getPort = Area.query_subscribe_get_port
getType = Area.query_subscribe_get_type
getIndex = Area.query_subscribe_get_index
getNumSubs = Area.query_subscribe_get_num_subs
getQueue = Area.query_subscribe_get_queue
getExclusive = Area.query_subscribe_get_exclusive
getTimeUpdate = Area.query_subscribe_get_time_update
getTimeReal = Area.query_subscribe_get_time_real
_setClient = Area.query_subscribe_set_client
_setPort = Area.query_subscribe_set_port
setType = Area.query_subscribe_set_type
setIndex = Area.query_subscribe_set_index
getRoot :: T -> IO Addr.T
getRoot q =
peek =<< Area.with_query_subscribe q snd_seq_query_subscribe_get_root
foreign import ccall unsafe "alsa/asoundlib.h snd_seq_query_subscribe_get_root"
snd_seq_query_subscribe_get_root :: Ptr T_ -> IO (Ptr Addr.T)
getAddr :: T -> IO Addr.T
getAddr q =
peek =<< Area.with_query_subscribe q snd_seq_query_subscribe_get_addr
foreign import ccall unsafe "alsa/asoundlib.h snd_seq_query_subscribe_get_addr"
snd_seq_query_subscribe_get_addr :: Ptr T_ -> IO (Ptr Addr.T)
setRoot :: T -> Addr.T -> IO ()
setRoot q c =
alloca $ \p -> poke p c >> Area.with_query_subscribe q (`snd_seq_query_subscribe_set_root` p)
foreign import ccall unsafe "alsa/asoundlib.h snd_seq_query_subscribe_set_root"
snd_seq_query_subscribe_set_root :: Ptr T_ -> Ptr Addr.T -> IO ()
queryPort :: Seq.T mode -> T -> IO Bool
queryPort (Seq.Cons h) q =
Exc.checkResultMaybe "query_port_subscribers" (const True) (\e -> if Errno (negate e) == eNOENT then Just False else Nothing) =<<
Area.with_query_subscribe q (snd_seq_query_port_subscribers h)
foreign import ccall unsafe "alsa/asoundlib.h snd_seq_query_port_subscribers"
snd_seq_query_port_subscribers :: Ptr Seq.Core -> Ptr T_ -> IO CInt
query :: Seq.T mode -> Addr.T -> Query.Type -> Word -> IO (Maybe T)
query ss root t i = do
q <- alloc
setRoot q root
setType q t
setIndex q i
r <- queryPort ss q
return $ if r then Just q else Nothing
queryAll :: Seq.T mode -> Addr.T -> Query.Type -> IO [T]
queryAll ss root t = queryRest 0 where
queryRest i = query ss root t i >>=
maybe (return []) (\q -> (q:) `fmap` queryRest (succ i))