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