{-# LANGUAGE ForeignFunctionInterface #-}
module Sound.ALSA.Sequencer.Connect (
   Connect.T(Connect.Cons, Connect.source, Connect.dest),
   reverse,
   toSubscribers, fromSubscribers,

   createFrom, deleteFrom, withFrom,
   createTo,   deleteTo,   withTo,
   ) where

import qualified Sound.ALSA.Sequencer.Marshal.Connect as Connect
import qualified Sound.ALSA.Sequencer.Marshal.Address as Addr
import qualified Sound.ALSA.Sequencer.Marshal.Port as Port
import qualified Sound.ALSA.Sequencer.Marshal.Sequencer as Seq
import qualified Sound.ALSA.Sequencer.Client as Client
import qualified Sound.ALSA.Exception as Exc

import qualified Foreign.C.Types as C
import Foreign.Ptr (Ptr, )

import Control.Exception (bracket, )

import Prelude hiding (reverse, )


reverse :: Connect.T -> Connect.T
reverse :: T -> T
reverse (Connect.Cons T
src T
dst) = T -> T -> T
Connect.Cons T
dst T
src

toSubscribers :: Addr.T -> Connect.T
toSubscribers :: T -> T
toSubscribers T
src = T -> T -> T
Connect.Cons T
src T
Addr.subscribers

fromSubscribers :: Addr.T -> Connect.T
fromSubscribers :: T -> T
fromSubscribers T
dst = T -> T -> T
Connect.Cons T
Addr.subscribers T
dst


-- | Simple subscription (w\/o exclusive & time conversion).
createFrom :: Seq.AllowInput mode => Seq.T mode -> Port.T -> Addr.T -> IO Connect.T
createFrom :: forall mode. AllowInput mode => T mode -> T -> T -> IO T
createFrom s :: T mode
s@(Seq.Cons Ptr Core
h) T
me T
a =
  do forall a. Integral a => String -> a -> IO ()
Exc.checkResult_ String
"connect_from" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
        forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Ptr Core -> CInt -> CInt -> CInt -> IO CInt
snd_seq_connect_from Ptr Core
h (T -> CInt
Port.exp T
me)) (T -> (CInt, CInt)
Addr.exp T
a)
     T
mec <- forall mode. T mode -> IO T
Client.getId T mode
s
     forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ T -> T -> T
Connect.Cons T
a (T -> T -> T
Addr.Cons T
mec T
me)

foreign import ccall unsafe "alsa/asoundlib.h snd_seq_connect_from"
  snd_seq_connect_from :: Ptr Seq.Core -> C.CInt -> C.CInt -> C.CInt -> IO C.CInt


-- | Simple subscription (w\/o exclusive & time conversion).
createTo :: Seq.AllowOutput mode => Seq.T mode -> Port.T -> Addr.T -> IO Connect.T
createTo :: forall mode. AllowOutput mode => T mode -> T -> T -> IO T
createTo s :: T mode
s@(Seq.Cons Ptr Core
h) T
me T
a =
  do forall a. Integral a => String -> a -> IO ()
Exc.checkResult_ String
"connect_to" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
        forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Ptr Core -> CInt -> CInt -> CInt -> IO CInt
snd_seq_connect_to Ptr Core
h (T -> CInt
Port.exp T
me)) (T -> (CInt, CInt)
Addr.exp T
a)
     T
mec <- forall mode. T mode -> IO T
Client.getId T mode
s
     forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ T -> T -> T
Connect.Cons (T -> T -> T
Addr.Cons T
mec T
me) T
a

foreign import ccall unsafe "alsa/asoundlib.h snd_seq_connect_to"
  snd_seq_connect_to :: Ptr Seq.Core -> C.CInt -> C.CInt -> C.CInt -> IO C.CInt


-- | Simple disconnection.
deleteFrom :: Seq.AllowInput mode => Seq.T mode -> Port.T -> Addr.T -> IO ()
deleteFrom :: forall mode. AllowInput mode => T mode -> T -> T -> IO ()
deleteFrom (Seq.Cons Ptr Core
h) T
me T
a =
  forall a. Integral a => String -> a -> IO ()
Exc.checkResult_ String
"disconnect_from" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Core -> CInt -> CInt -> CInt -> IO CInt
snd_seq_disconnect_from Ptr Core
h (T -> CInt
Port.exp T
me) CInt
c CInt
p
  where (CInt
c,CInt
p) = T -> (CInt, CInt)
Addr.exp T
a

foreign import ccall unsafe "alsa/asoundlib.h snd_seq_disconnect_from"
  snd_seq_disconnect_from :: Ptr Seq.Core -> C.CInt -> C.CInt -> C.CInt -> IO C.CInt

-- | Simple disconnection.
deleteTo :: Seq.AllowOutput mode => Seq.T mode -> Port.T -> Addr.T -> IO ()
deleteTo :: forall mode. AllowOutput mode => T mode -> T -> T -> IO ()
deleteTo (Seq.Cons Ptr Core
h) T
me T
a =
  forall a. Integral a => String -> a -> IO ()
Exc.checkResult_ String
"disconnect_to" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr Core -> CInt -> CInt -> CInt -> IO CInt
snd_seq_disconnect_to Ptr Core
h (T -> CInt
Port.exp T
me) CInt
c CInt
p
  where (CInt
c,CInt
p) = T -> (CInt, CInt)
Addr.exp T
a

foreign import ccall unsafe "alsa/asoundlib.h snd_seq_disconnect_to"
  snd_seq_disconnect_to :: Ptr Seq.Core -> C.CInt -> C.CInt -> C.CInt -> IO C.CInt


-- | Temporary subscription.
withFrom :: Seq.AllowInput mode => Seq.T mode -> Port.T -> Addr.T -> (Connect.T -> IO a) -> IO a
withFrom :: forall mode a.
AllowInput mode =>
T mode -> T -> T -> (T -> IO a) -> IO a
withFrom T mode
h T
me T
a =
  forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (forall mode. AllowInput mode => T mode -> T -> T -> IO T
createFrom T mode
h T
me T
a) (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall mode. AllowInput mode => T mode -> T -> T -> IO ()
deleteFrom T mode
h T
me T
a)

-- | Temporary subscription.
withTo :: Seq.AllowOutput mode => Seq.T mode -> Port.T -> Addr.T -> (Connect.T -> IO a) -> IO a
withTo :: forall mode a.
AllowOutput mode =>
T mode -> T -> T -> (T -> IO a) -> IO a
withTo T mode
h T
me T
a =
  forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (forall mode. AllowOutput mode => T mode -> T -> T -> IO T
createTo T mode
h T
me T
a) (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall mode. AllowOutput mode => T mode -> T -> T -> IO ()
deleteTo T mode
h T
me T
a)