+/** the -create-done event transmitter
+ *
+ * \param listener
+ * \param owner
+ * \param self
+ * \param args
+ */
+
+static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
+{
+ if ( listener != NULL )
+ listener( owner, self, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] );
+}
+
+/** Construct the repository and factories.
+ *
+ * The environment variable MLT_PRODUCER is the name of a default producer often used by other services, defaults to "loader".
+ *
+ * The environment variable MLT_CONSUMER is the name of a default consumer, defaults to "sdl".
+ *
+ * The environment variable MLT_TEST_CARD is the name of a producer or file to be played when nothing is available (all tracks blank).
+ *
+ * The environment variable MLT_DATA overrides the default full path to the MLT and module supplemental data files, defaults to \p PREFIX_DATA.
+ *
+ * The environment variable MLT_PROFILE defaults to "dv_pal."
+ *
+ * The environment variable MLT_REPOSITORY overrides the default location of the plugin modules, defaults to \p PREFIX_LIB.
+ *
+ * \param directory an optional full path to a directory containing the modules that overrides the default and
+ * the MLT_REPOSITORY environment variable
+ * \return the repository
+ */
+
+mlt_repository mlt_factory_init( const char *directory )
+{
+ // Load the system locales
+ setlocale( LC_ALL, "" );
+
+ if ( ! global_properties )
+ global_properties = mlt_properties_new( );
+
+ // Allow property refresh on a subsequent initialisation
+ if ( global_properties )
+ {
+ mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" );
+ mlt_properties_set_or_default( global_properties, "MLT_PRODUCER", getenv( "MLT_PRODUCER" ), "loader" );
+ mlt_properties_set_or_default( global_properties, "MLT_CONSUMER", getenv( "MLT_CONSUMER" ), "sdl" );
+ mlt_properties_set( global_properties, "MLT_TEST_CARD", getenv( "MLT_TEST_CARD" ) );
+ mlt_properties_set_or_default( global_properties, "MLT_PROFILE", getenv( "MLT_PROFILE" ), "dv_pal" );
+ mlt_properties_set_or_default( global_properties, "MLT_DATA", getenv( "MLT_DATA" ), PREFIX_DATA );
+#if defined(WIN32)
+ char path[1024];
+ DWORD size = sizeof( path );
+ GetModuleFileName( NULL, path, size );
+#elif defined(__DARWIN__) && defined(RELOCATABLE)
+ char path[1024];
+ uint32_t size = sizeof( path );
+ _NSGetExecutablePath( path, &size );
+#endif
+#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
+ char *path2 = strdup( path );
+ char *appdir = dirname( path2 );
+ mlt_properties_set( global_properties, "MLT_APPDIR", appdir );
+ free( path2 );
+#endif
+ }
+
+ // Only initialise once
+ if ( mlt_directory == NULL )
+ {
+ // Allow user over rides
+ if ( directory == NULL || !strcmp( directory, "" ) )
+ directory = getenv( "MLT_REPOSITORY" );
+
+ // If no directory is specified, default to install directory
+ if ( directory == NULL )
+ directory = PREFIX_LIB;
+
+ // Store the prefix for later retrieval
+#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
+ char *exedir = mlt_environment( "MLT_APPDIR" );
+ size_t size = strlen( exedir );
+ if ( global_properties && !getenv( "MLT_DATA" ) )
+ {
+ mlt_directory = calloc( 1, size + strlen( PREFIX_DATA ) + 1 );
+ strcpy( mlt_directory, exedir );
+ strcat( mlt_directory, PREFIX_DATA );
+ mlt_properties_set( global_properties, "MLT_DATA", mlt_directory );
+ free( mlt_directory );
+ }
+ mlt_directory = calloc( 1, size + strlen( directory ) + 1 );
+ strcpy( mlt_directory, exedir );
+ strcat( mlt_directory, directory );
+#else
+ mlt_directory = strdup( directory );
+#endif
+
+ // Initialise the pool
+ mlt_pool_init( );
+
+ // Create and set up the events object
+ event_object = mlt_properties_new( );
+ mlt_events_init( event_object );
+ mlt_events_register( event_object, "producer-create-request", ( mlt_transmitter )mlt_factory_create_request );
+ mlt_events_register( event_object, "producer-create-done", ( mlt_transmitter )mlt_factory_create_done );
+ mlt_events_register( event_object, "filter-create-request", ( mlt_transmitter )mlt_factory_create_request );
+ mlt_events_register( event_object, "filter-create-done", ( mlt_transmitter )mlt_factory_create_done );
+ mlt_events_register( event_object, "transition-create-request", ( mlt_transmitter )mlt_factory_create_request );
+ mlt_events_register( event_object, "transition-create-done", ( mlt_transmitter )mlt_factory_create_done );
+ mlt_events_register( event_object, "consumer-create-request", ( mlt_transmitter )mlt_factory_create_request );
+ mlt_events_register( event_object, "consumer-create-done", ( mlt_transmitter )mlt_factory_create_done );
+
+ // Create the repository of services
+ repository = mlt_repository_init( mlt_directory );
+
+ // Force a clean up when app closes
+ atexit( mlt_factory_close );
+ }
+
+ return repository;
+}
+
+/** Fetch the events object.
+ *
+ * \return the global factory event object
+ */
+
+mlt_properties mlt_factory_event_object( )
+{
+ return event_object;
+}
+
+/** Fetch the module directory used in this instance.
+ *
+ * \return the full path to the module directory that this session is using
+ */