1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gstreamer.Registry;
26 
27 private import glib.ListG;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gstreamer.ObjectGst;
32 private import gstreamer.Plugin;
33 private import gstreamer.PluginFeature;
34 private import gstreamerc.gstreamer;
35 public  import gstreamerc.gstreamertypes;
36 public  import gtkc.gdktypes;
37 
38 
39 /**
40  * One registry holds the metadata of a set of plugins.
41  * 
42  * <emphasis role="bold">Design:</emphasis>
43  * 
44  * The #GstRegistry object is a list of plugins and some functions for dealing
45  * with them. Each #GstPlugin is matched 1-1 with a file on disk, and may or may
46  * not be loaded at a given time.
47  * 
48  * The primary source, at all times, of plugin information is each plugin file
49  * itself. Thus, if an application wants information about a particular plugin,
50  * or wants to search for a feature that satisfies given criteria, the primary
51  * means of doing so is to load every plugin and look at the resulting
52  * information that is gathered in the default registry. Clearly, this is a time
53  * consuming process, so we cache information in the registry file. The format
54  * and location of the cache file is internal to gstreamer.
55  * 
56  * On startup, plugins are searched for in the plugin search path. The following
57  * locations are checked in this order:
58  * <itemizedlist>
59  * <listitem>
60  * <para>location from --gst-plugin-path commandline option.</para>
61  * </listitem>
62  * <listitem>
63  * <para>the GST_PLUGIN_PATH environment variable.</para>
64  * </listitem>
65  * <listitem>
66  * <para>the GST_PLUGIN_SYSTEM_PATH environment variable.</para>
67  * </listitem>
68  * <listitem>
69  * <para>default locations (if GST_PLUGIN_SYSTEM_PATH is not set). Those
70  * default locations are:
71  * <filename>$XDG_DATA_HOME/gstreamer-$GST_API_VERSION/plugins/</filename>
72  * and <filename>$prefix/libs/gstreamer-$GST_API_VERSION/</filename>.
73  * <ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">
74  * <filename>$XDG_DATA_HOME</filename></ulink> defaults to
75  * <filename>$HOME/.local/share</filename>.
76  * </para>
77  * </listitem>
78  * </itemizedlist>
79  * The registry cache file is loaded from
80  * <filename>$XDG_CACHE_HOME/gstreamer-$GST_API_VERSION/registry-$ARCH.bin</filename>
81  * (where
82  * <ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">
83  * <filename>$XDG_CACHE_HOME</filename></ulink> defaults to
84  * <filename>$HOME/.cache</filename>) or the file listed in the GST_REGISTRY
85  * env var. One reason to change the registry location is for testing.
86  * 
87  * For each plugin that is found in the plugin search path, there could be 3
88  * possibilities for cached information:
89  * <itemizedlist>
90  * <listitem>
91  * <para>the cache may not contain information about a given file.</para>
92  * </listitem>
93  * <listitem>
94  * <para>the cache may have stale information.</para>
95  * </listitem>
96  * <listitem>
97  * <para>the cache may have current information.</para>
98  * </listitem>
99  * </itemizedlist>
100  * 
101  * In the first two cases, the plugin is loaded and the cache updated. In
102  * addition to these cases, the cache may have entries for plugins that are not
103  * relevant to the current process. These are marked as not available to the
104  * current process. If the cache is updated for whatever reason, it is marked
105  * dirty.
106  * 
107  * A dirty cache is written out at the end of initialization. Each entry is
108  * checked to make sure the information is minimally valid. If not, the entry is
109  * simply dropped.
110  * 
111  * <emphasis role="bold">Implementation notes:</emphasis>
112  * 
113  * The "cache" and "registry" are different concepts and can represent
114  * different sets of plugins. For various reasons, at init time, the cache is
115  * stored in the default registry, and plugins not relevant to the current
116  * process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are
117  * removed at the end of initialization.
118  */
119 public class Registry : ObjectGst
120 {
121 	/** the main Gtk struct */
122 	protected GstRegistry* gstRegistry;
123 
124 	/** Get the main Gtk struct */
125 	public GstRegistry* getRegistryStruct()
126 	{
127 		return gstRegistry;
128 	}
129 
130 	/** the main Gtk struct as a void* */
131 	protected override void* getStruct()
132 	{
133 		return cast(void*)gstRegistry;
134 	}
135 
136 	protected override void setStruct(GObject* obj)
137 	{
138 		gstRegistry = cast(GstRegistry*)obj;
139 		super.setStruct(obj);
140 	}
141 
142 	/**
143 	 * Sets our main struct and passes it to the parent class.
144 	 */
145 	public this (GstRegistry* gstRegistry, bool ownedRef = false)
146 	{
147 		this.gstRegistry = gstRegistry;
148 		super(cast(GstObject*)gstRegistry, ownedRef);
149 	}
150 
151 
152 	/** */
153 	public static GType getType()
154 	{
155 		return gst_registry_get_type();
156 	}
157 
158 	/**
159 	 * By default GStreamer will perform scanning and rebuilding of the
160 	 * registry file using a helper child process.
161 	 *
162 	 * Applications might want to disable this behaviour with the
163 	 * gst_registry_fork_set_enabled() function, in which case new plugins
164 	 * are scanned (and loaded) into the application process.
165 	 *
166 	 * Return: %TRUE if GStreamer will use the child helper process when
167 	 *     rebuilding the registry.
168 	 */
169 	public static bool forkIsEnabled()
170 	{
171 		return gst_registry_fork_is_enabled() != 0;
172 	}
173 
174 	/**
175 	 * Applications might want to disable/enable spawning of a child helper process
176 	 * when rebuilding the registry. See gst_registry_fork_is_enabled() for more
177 	 * information.
178 	 *
179 	 * Params:
180 	 *     enabled = whether rebuilding the registry can use a temporary child helper process.
181 	 */
182 	public static void forkSetEnabled(bool enabled)
183 	{
184 		gst_registry_fork_set_enabled(enabled);
185 	}
186 
187 	/**
188 	 * Retrieves the singleton plugin registry. The caller does not own a
189 	 * reference on the registry, as it is alive as long as GStreamer is
190 	 * initialized.
191 	 *
192 	 * Return: the #GstRegistry.
193 	 */
194 	public static Registry get()
195 	{
196 		auto p = gst_registry_get();
197 		
198 		if(p is null)
199 		{
200 			return null;
201 		}
202 		
203 		return ObjectG.getDObject!(Registry)(cast(GstRegistry*) p);
204 	}
205 
206 	/**
207 	 * Add the feature to the registry. The feature-added signal will be emitted.
208 	 * This function sinks @feature.
209 	 *
210 	 * Params:
211 	 *     feature = the feature to add
212 	 *
213 	 * Return: %TRUE on success.
214 	 *
215 	 *     MT safe.
216 	 */
217 	public bool addFeature(PluginFeature feature)
218 	{
219 		return gst_registry_add_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct()) != 0;
220 	}
221 
222 	/**
223 	 * Add the plugin to the registry. The plugin-added signal will be emitted.
224 	 * This function will sink @plugin.
225 	 *
226 	 * Params:
227 	 *     plugin = the plugin to add
228 	 *
229 	 * Return: %TRUE on success.
230 	 *
231 	 *     MT safe.
232 	 */
233 	public bool addPlugin(Plugin plugin)
234 	{
235 		return gst_registry_add_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct()) != 0;
236 	}
237 
238 	/**
239 	 * Checks whether a plugin feature by the given name exists in
240 	 * @registry and whether its version is at least the
241 	 * version required.
242 	 *
243 	 * Params:
244 	 *     featureName = the name of the feature (e.g. "oggdemux")
245 	 *     minMajor = the minimum major version number
246 	 *     minMinor = the minimum minor version number
247 	 *     minMicro = the minimum micro version number
248 	 *
249 	 * Return: %TRUE if the feature could be found and the version is
250 	 *     the same as the required version or newer, and %FALSE otherwise.
251 	 */
252 	public bool checkFeatureVersion(string featureName, uint minMajor, uint minMinor, uint minMicro)
253 	{
254 		return gst_registry_check_feature_version(gstRegistry, Str.toStringz(featureName), minMajor, minMinor, minMicro) != 0;
255 	}
256 
257 	/**
258 	 * Runs a filter against all features of the plugins in the registry
259 	 * and returns a GList with the results.
260 	 * If the first flag is set, only the first match is
261 	 * returned (as a list with a single object).
262 	 *
263 	 * Params:
264 	 *     filter = the filter to use
265 	 *     first = only return first match
266 	 *     userData = user data passed to the filter function
267 	 *
268 	 * Return: a #GList of
269 	 *     #GstPluginFeature. Use gst_plugin_feature_list_free() after usage.
270 	 *
271 	 *     MT safe.
272 	 */
273 	public ListG featureFilter(GstPluginFeatureFilter filter, bool first, void* userData)
274 	{
275 		auto p = gst_registry_feature_filter(gstRegistry, filter, first, userData);
276 		
277 		if(p is null)
278 		{
279 			return null;
280 		}
281 		
282 		return new ListG(cast(GList*) p, true);
283 	}
284 
285 	/**
286 	 * Find the pluginfeature with the given name and type in the registry.
287 	 *
288 	 * Params:
289 	 *     name = the pluginfeature name to find
290 	 *     type = the pluginfeature type to find
291 	 *
292 	 * Return: the pluginfeature with the
293 	 *     given name and type or %NULL if the plugin was not
294 	 *     found. gst_object_unref() after usage.
295 	 *
296 	 *     MT safe.
297 	 */
298 	public PluginFeature findFeature(string name, GType type)
299 	{
300 		auto p = gst_registry_find_feature(gstRegistry, Str.toStringz(name), type);
301 		
302 		if(p is null)
303 		{
304 			return null;
305 		}
306 		
307 		return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true);
308 	}
309 
310 	/**
311 	 * Find the plugin with the given name in the registry.
312 	 * The plugin will be reffed; caller is responsible for unreffing.
313 	 *
314 	 * Params:
315 	 *     name = the plugin name to find
316 	 *
317 	 * Return: the plugin with the given name
318 	 *     or %NULL if the plugin was not found. gst_object_unref() after
319 	 *     usage.
320 	 *
321 	 *     MT safe.
322 	 */
323 	public Plugin findPlugin(string name)
324 	{
325 		auto p = gst_registry_find_plugin(gstRegistry, Str.toStringz(name));
326 		
327 		if(p is null)
328 		{
329 			return null;
330 		}
331 		
332 		return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true);
333 	}
334 
335 	/**
336 	 * Retrieves a #GList of #GstPluginFeature of @type.
337 	 *
338 	 * Params:
339 	 *     type = a #GType.
340 	 *
341 	 * Return: a #GList of
342 	 *     #GstPluginFeature of @type. Use gst_plugin_feature_list_free() after use
343 	 *
344 	 *     MT safe.
345 	 */
346 	public ListG getFeatureList(GType type)
347 	{
348 		auto p = gst_registry_get_feature_list(gstRegistry, type);
349 		
350 		if(p is null)
351 		{
352 			return null;
353 		}
354 		
355 		return new ListG(cast(GList*) p, true);
356 	}
357 
358 	/**
359 	 * Retrieves a #GList of features of the plugin with name @name.
360 	 *
361 	 * Params:
362 	 *     name = a plugin name.
363 	 *
364 	 * Return: a #GList of
365 	 *     #GstPluginFeature. Use gst_plugin_feature_list_free() after usage.
366 	 */
367 	public ListG getFeatureListByPlugin(string name)
368 	{
369 		auto p = gst_registry_get_feature_list_by_plugin(gstRegistry, Str.toStringz(name));
370 		
371 		if(p is null)
372 		{
373 			return null;
374 		}
375 		
376 		return new ListG(cast(GList*) p, true);
377 	}
378 
379 	/**
380 	 * Returns the registry's feature list cookie. This changes
381 	 * every time a feature is added or removed from the registry.
382 	 *
383 	 * Return: the feature list cookie.
384 	 */
385 	public uint getFeatureListCookie()
386 	{
387 		return gst_registry_get_feature_list_cookie(gstRegistry);
388 	}
389 
390 	/**
391 	 * Get a copy of all plugins registered in the given registry. The refcount
392 	 * of each element in the list in incremented.
393 	 *
394 	 * Return: a #GList of #GstPlugin.
395 	 *     Use gst_plugin_list_free() after usage.
396 	 *
397 	 *     MT safe.
398 	 */
399 	public ListG getPluginList()
400 	{
401 		auto p = gst_registry_get_plugin_list(gstRegistry);
402 		
403 		if(p is null)
404 		{
405 			return null;
406 		}
407 		
408 		return new ListG(cast(GList*) p, true);
409 	}
410 
411 	/**
412 	 * Look up a plugin in the given registry with the given filename.
413 	 * If found, plugin is reffed.
414 	 *
415 	 * Params:
416 	 *     filename = the name of the file to look up
417 	 *
418 	 * Return: the #GstPlugin if found, or
419 	 *     %NULL if not.  gst_object_unref() after usage.
420 	 */
421 	public Plugin lookup(string filename)
422 	{
423 		auto p = gst_registry_lookup(gstRegistry, Str.toStringz(filename));
424 		
425 		if(p is null)
426 		{
427 			return null;
428 		}
429 		
430 		return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true);
431 	}
432 
433 	/**
434 	 * Find a #GstPluginFeature with @name in @registry.
435 	 *
436 	 * Params:
437 	 *     name = a #GstPluginFeature name
438 	 *
439 	 * Return: a #GstPluginFeature with its refcount incremented,
440 	 *     use gst_object_unref() after usage.
441 	 *
442 	 *     MT safe.
443 	 */
444 	public PluginFeature lookupFeature(string name)
445 	{
446 		auto p = gst_registry_lookup_feature(gstRegistry, Str.toStringz(name));
447 		
448 		if(p is null)
449 		{
450 			return null;
451 		}
452 		
453 		return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true);
454 	}
455 
456 	/**
457 	 * Runs a filter against all plugins in the registry and returns a #GList with
458 	 * the results. If the first flag is set, only the first match is
459 	 * returned (as a list with a single object).
460 	 * Every plugin is reffed; use gst_plugin_list_free() after use, which
461 	 * will unref again.
462 	 *
463 	 * Params:
464 	 *     filter = the filter to use
465 	 *     first = only return first match
466 	 *     userData = user data passed to the filter function
467 	 *
468 	 * Return: a #GList of #GstPlugin.
469 	 *     Use gst_plugin_list_free() after usage.
470 	 *
471 	 *     MT safe.
472 	 */
473 	public ListG pluginFilter(GstPluginFilter filter, bool first, void* userData)
474 	{
475 		auto p = gst_registry_plugin_filter(gstRegistry, filter, first, userData);
476 		
477 		if(p is null)
478 		{
479 			return null;
480 		}
481 		
482 		return new ListG(cast(GList*) p, true);
483 	}
484 
485 	/**
486 	 * Remove the feature from the registry.
487 	 *
488 	 * MT safe.
489 	 *
490 	 * Params:
491 	 *     feature = the feature to remove
492 	 */
493 	public void removeFeature(PluginFeature feature)
494 	{
495 		gst_registry_remove_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct());
496 	}
497 
498 	/**
499 	 * Remove the plugin from the registry.
500 	 *
501 	 * MT safe.
502 	 *
503 	 * Params:
504 	 *     plugin = the plugin to remove
505 	 */
506 	public void removePlugin(Plugin plugin)
507 	{
508 		gst_registry_remove_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct());
509 	}
510 
511 	/**
512 	 * Scan the given path for plugins to add to the registry. The syntax of the
513 	 * path is specific to the registry.
514 	 *
515 	 * Params:
516 	 *     path = the path to scan
517 	 *
518 	 * Return: %TRUE if registry changed
519 	 */
520 	public bool scanPath(string path)
521 	{
522 		return gst_registry_scan_path(gstRegistry, Str.toStringz(path)) != 0;
523 	}
524 
525 	int[string] connectedSignals;
526 
527 	void delegate(PluginFeature, Registry)[] onFeatureAddedListeners;
528 	/**
529 	 * Signals that a feature has been added to the registry (possibly
530 	 * replacing a previously-added one by the same name)
531 	 *
532 	 * Params:
533 	 *     feature = the feature that has been added
534 	 */
535 	void addOnFeatureAdded(void delegate(PluginFeature, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
536 	{
537 		if ( "feature-added" !in connectedSignals )
538 		{
539 			Signals.connectData(
540 				this,
541 				"feature-added",
542 				cast(GCallback)&callBackFeatureAdded,
543 				cast(void*)this,
544 				null,
545 				connectFlags);
546 			connectedSignals["feature-added"] = 1;
547 		}
548 		onFeatureAddedListeners ~= dlg;
549 	}
550 	extern(C) static void callBackFeatureAdded(GstRegistry* registryStruct, GstPluginFeature* feature, Registry _registry)
551 	{
552 		foreach ( void delegate(PluginFeature, Registry) dlg; _registry.onFeatureAddedListeners )
553 		{
554 			dlg(ObjectG.getDObject!(PluginFeature)(feature), _registry);
555 		}
556 	}
557 
558 	void delegate(Plugin, Registry)[] onPluginAddedListeners;
559 	/**
560 	 * Signals that a plugin has been added to the registry (possibly
561 	 * replacing a previously-added one by the same name)
562 	 *
563 	 * Params:
564 	 *     plugin = the plugin that has been added
565 	 */
566 	void addOnPluginAdded(void delegate(Plugin, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
567 	{
568 		if ( "plugin-added" !in connectedSignals )
569 		{
570 			Signals.connectData(
571 				this,
572 				"plugin-added",
573 				cast(GCallback)&callBackPluginAdded,
574 				cast(void*)this,
575 				null,
576 				connectFlags);
577 			connectedSignals["plugin-added"] = 1;
578 		}
579 		onPluginAddedListeners ~= dlg;
580 	}
581 	extern(C) static void callBackPluginAdded(GstRegistry* registryStruct, GstPlugin* plugin, Registry _registry)
582 	{
583 		foreach ( void delegate(Plugin, Registry) dlg; _registry.onPluginAddedListeners )
584 		{
585 			dlg(ObjectG.getDObject!(Plugin)(plugin), _registry);
586 		}
587 	}
588 }