File: Bin.chs

package info (click to toggle)
haskell-gstreamer 0.12.1-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 720 kB
  • sloc: haskell: 635; ansic: 116; makefile: 11; sh: 7
file content (251 lines) | stat: -rw-r--r-- 10,927 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
{-# LANGUAGE CPP #-}
--  GIMP Toolkit (GTK) Binding for Haskell: binding to gstreamer -*-haskell-*-
--
--  Author : Peter Gavin
--  Created: 1-Apr-2007
--
--  Copyright (c) 2007 Peter Gavin
--
--  This library is free software: you can redistribute it and/or
--  modify it under the terms of the GNU Lesser General Public License
--  as published by the Free Software Foundation, either version 3 of
--  the License, or (at your option) any later version.
--  
--  This library is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--  Lesser General Public License for more details.
--  
--  You should have received a copy of the GNU Lesser General Public
--  License along with this program.  If not, see
--  <http://www.gnu.org/licenses/>.
--  
--  GStreamer, the C library which this Haskell library depends on, is
--  available under LGPL Version 2. The documentation included with
--  this library is based on the original GStreamer documentation.
--  
--  | Maintainer  : gtk2hs-devel@lists.sourceforge.net
--    Stability   : alpha
--    Portability : portable (depends on GHC)
--  
--  Base class for elements that can contain other elements.
module Media.Streaming.GStreamer.Core.Bin (

-- * Detail
  -- | 'Bin' is an element that can contain other 'Element's, allowing
  --   them to be managed as a group. 'Pad's from the child elements
  --   can be ghosted to the bin; see 'GhostPad'. This makes the bin
  --   look like any other element, and enables creation of
  --   higher-level abstractions.
  --   
  --   A new 'Bin' is created with 'binNew'. Use a 'Pipeline' instead
  --   if you want to create a toplevel bin, because a normal bin
  --   doesn't have a bus or handle clock distribution of its own.
  --   
  --   After the bin has been created you will typically add elements
  --   to it with 'binAdd'. You can remove elements with 'binRemove'.
  --   
  --   An element can be retrieved from a bin with 'binGetByName',
  --   using the element's name. 'binGetByNameRecurseUp' is mainly
  --   used for internal purposes and will query the parent bins when
  --   the element is not found in the current bin.
  --   
  --   An iterator of elements in a bin can be retrieved with
  --   'binIterateElements'. Various other iterators exist to retrieve
  --   the elements in a bin.
  --   
  --   The 'binElementAdded' signal is fired whenever a new element is
  --   added to the bin. Likewise the 'binElementRemoved' signal is
  --   fired whenever an element is removed from the bin.

-- * Types
  Bin,
  BinClass,
  castToBin,
  gTypeBin,

-- * Bin Operations
  binNew,
  binAdd,
  binRemove,
  binGetByName,
  binGetByNameRecurseUp,
  binGetByInterface,
  binIterateElements,
  binIterateRecurse,
  binIterateSinks,
  binIterateSorted,
  binIterateSources,
  binIterateAllByInterface,
  binFindUnconnectedPad,
  
-- * Bin Signals
  binElementAdded,
  binElementRemoved
  
  ) where

import Control.Exception                      ( bracket_ )
import Control.Monad                          ( liftM )
import System.Glib.FFI
{#import System.Glib.GType#}                  ( GType )
import System.Glib.UTFString                  ( withUTFString )
import System.Glib.GList                      ( GList
                                              , readGList )
{#import Media.Streaming.GStreamer.Core.Types#}
{#import Media.Streaming.GStreamer.Core.Signals#}

{# context lib = "gstreamer" prefix = "gst" #}

-- | Create a new 'Bin' with the given name.
binNew :: String -- ^ @name@ - the name to give the new 'Bin'
       -> IO Bin -- ^ the new 'Bin'
binNew name =
    withUTFString name {# call bin_new #} >>= takeObject . castPtr

-- | Add @element@ to @bin@, and set @element@'s parent to
--   @bin@. An 'Element' can only be added to one 'Bin' at a time.
--   
--   If any of @element@'s pads are linked to other 'Pad's, they will be
--   unlinked before @element@ is added to @bin@.
binAdd :: (BinClass bin, ElementClass element)
       => bin     -- ^ @bin@ - a 'Bin'
       -> element -- ^ @element@ - the element to add
       -> IO Bool -- ^ 'True' if the element could be added, 'False'
                  --   if the bin does not want to accept the element
binAdd bin element =
    liftM toBool $ {# call bin_add #} (toBin bin) (toElement element)

-- | Remove @element@ from @bin@, unparenting it as well.
--   
--   If any @element@'s pads are linked to other pads, they will be
--   unlinked before @element@ is added to @bin@.
binRemove :: (BinClass bin, ElementClass element)
          => bin     -- ^ @bin@ - a 'Bin'
          -> element -- ^ @element@ - the element to remove
          -> IO Bool -- ^ 'True' if @element@ could be removed, otherwise 'False'
binRemove bin element =
    liftM toBool $ {# call bin_remove #} (toBin bin) (toElement element)

-- | Get the 'Element' with the given name @name@ from @bin@,
--   recursing down through @bin@'s children. 'Nothing' is returned if no
--   'Element' with the given name is found.
binGetByName :: BinClass bin
             => bin                -- ^ @bin@ - a 'Bin'
             -> String             -- ^ @name@ - the name to search for
             -> IO (Maybe Element) -- ^ the 'Element' with the name @name@, or 'Nothing'
binGetByName bin name =
    withUTFString name ({# call bin_get_by_name #} (toBin bin)) >>= maybePeek takeObject

-- | Get the 'Element' with the given name @name@ from @bin@,
--   recursing up through @bin@'s parents. Returns 'Nothing' if no
--   element with the given name is found.
binGetByNameRecurseUp :: BinClass bin
                      => bin                -- ^ @bin@ - a 'Bin'
                      -> String             -- ^ @element@ - the name to search for
                      -> IO (Maybe Element) -- ^ the 'Element' with the given name, or 'Nothing'
binGetByNameRecurseUp bin name =
    withUTFString name ({# call bin_get_by_name_recurse_up #} $ toBin bin) >>=
        maybePeek takeObject

-- | Find an 'Element' inside @bin@ that implements the interface
--   given by @iface@. The returned 'Element' can be casted to
--   @iface@'s type. If you want all the 'Element's that implement an
--   interface, use 'binIterateAllByInterface'.
--   
--   This function recurses into child bins.
binGetByInterface :: BinClass bin
                  => bin                -- ^ @bin@ - a 'Bin'
                  -> GType              -- ^ @iface@ - the type of the requested interface
                  -> IO (Maybe Element) -- ^ the 'Element' inside @bin@ that implements @iface@, or 'Nothing'
binGetByInterface bin iface =
    {# call bin_get_by_interface #} (toBin bin) (fromIntegral iface) >>=
        maybePeek takeObject

-- | Get an 'Iterator' over the 'Element's in @bin@.
binIterateElements :: BinClass bin
                   => bin                           -- ^ @bin@ - a 'Bin'
                   -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' over the 'Element's in @bin@,
                                                    --   or 'Nothing'
binIterateElements bin =
    {# call bin_iterate_elements #} (toBin bin) >>=
        maybePeek takeIterator

-- | Get an 'Iterator' over the 'Element's in @bin@. This
--   iterator recurses into @bin@'s children.
binIterateRecurse :: BinClass bin
                  => bin                           -- ^ @bin@ - a 'Bin'
                  -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' over the 'Element's in @bin@
                                                   --   and its descendents, or 'Nothing'
binIterateRecurse bin =
    {# call bin_iterate_recurse #} (toBin bin) >>=
        maybePeek takeIterator

-- | Get an iterator over the 'Element's in @bin@ that have the
--   'ElementIsSink' flag set.
binIterateSinks :: BinClass bin
                => bin                           -- ^ @bin@ - a 'Bin'
                -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' over the sinks in @bin@, or 'Nothing'
binIterateSinks bin =
    {# call bin_iterate_sinks #} (toBin bin) >>=
        maybePeek takeIterator

-- | Gets an iterator for the elements in this bin in topologically
--   sorted order. This means that the elements are returned from the
--   most downstream elements (sinks) to the sources.
--   
--   This function is used internally to perform state changes of the
--   bin elements.
binIterateSorted :: BinClass bin
                 => bin                           -- ^ @bin@ - a 'Bin'
                 -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' over the 'Element's in @bin@, or 'Nothing'
binIterateSorted bin =
    {# call bin_iterate_sorted #} (toBin bin) >>=
        maybePeek takeIterator

-- | Gets an iterator for all elements in the bin that have no sink
--   pads and have the 'ElementIsSink' flag unset.
binIterateSources :: BinClass bin
                  => bin                           -- ^ @bin@ - a 'Bin'
                  -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' on elements, or 'Nothing'
binIterateSources bin =
    {# call bin_iterate_sources #} (toBin bin) >>=
        maybePeek takeIterator

-- | Looks for all elements inside the bin that implement the given
--   interface. You can safely case all elements to the given
--   interface. The function recurses inside child bins.
binIterateAllByInterface :: BinClass bin
                         => bin                           -- ^ @bin@ - a 'Bin'
                         -> GType                         -- ^ @iface@ - the interface's 'GType'
                         -> IO (Maybe (Iterator Element)) -- ^ an 'Iterator' on elements, or 'Nothing'
binIterateAllByInterface bin iface =
    {# call bin_iterate_all_by_interface #} (toBin bin) (fromIntegral iface) >>=
        maybePeek takeIterator

#if GST_CHECK_VERSION (0, 10, 3)
-- | Recursively looks for elements with an unconnected pad of the
--   given direction within the specified bin. Returns an unconnected
--   pad if one is found, otherwise 'Nothing'.
--
--   Since 0.10.3.
binFindUnconnectedPad :: BinClass bin
                      => bin            -- ^ @bin@ - a 'Bin'
                      -> PadDirection   -- ^ @direction@ - the direction of the requested 'Pad'
                      -> IO (Maybe Pad) -- ^ an unconnected 'Pad', or 'Nothing'
binFindUnconnectedPad bin direction =
    {# call bin_find_unconnected_pad #} (toBin bin) (fromIntegral $ fromEnum direction) >>=
        maybePeek takeObject
#endif

-- | An 'Element' has been added to the 'Bin'.
binElementAdded :: BinClass bin
                => Signal bin (Element -> IO ())
binElementAdded =
    Signal $ connect_OBJECT__NONE "element-added"

-- | An 'Element' has been removed from the 'Bin'.
binElementRemoved :: BinClass bin
                  => Signal bin (Element -> IO ())
binElementRemoved =
    Signal $ connect_OBJECT__NONE "element-added"