MAFW Manual |
---|
As MAFW is based on GObject the first step to write a MAFW based application is to initialize the GType system. You can do this by invoking g_type_init at the beginning of your program:
g_type_init ();
Of course, this step is not necessary if the developer is using another GObject based framework, like GTK+. In this case, initializing such framework already initializes the GType system.
The next step is to check for available extensions (sources and renderers). Depending on whether you are using in-process or out-of-process extensions, this process may differ slightly:
As we already pointed out, with the out-of-process approach
extensions are loaded by the
mafw-dbus-wrapper
in a separate address space and they are shared by all applications, which
use these extensions through DBUS services. In order to use these
out-of-process extensions, the first step is to discover their availability
on the bus. This is done by invoking mafw_shared_init. Once the discovery
has been started, the application will be notified of new available
extensions through signals. Likewise, when a certain extension is no
longer available, a signal is received on the application side so the
situation can be handled properly.
/* Start extension discovery service */ registry = MAFW_REGISTRY(mafw_registry_get_instance()); if (registry == NULL) { /* Error management here */ } mafw_shared_init(registry, &error); if (error != NULL) { /* Error management here */ } g_signal_connect(registry, "renderer-added", G_CALLBACK(renderer_added_cb), NULL); g_signal_connect(registry, "renderer-removed", G_CALLBACK(renderer_removed_cb), NULL); g_signal_connect(registry, "source-added", G_CALLBACK(source_added_cb), NULL); g_signal_connect(registry, "source-removed", G_CALLBACK(source_removed_cb), NULL);
The MafwRegistry object is a singleton instance where all the available extensions are registered. It provides an interface for application developers to access the available sources and renderers. In the case of out-of-process extensions, the registry will provide proxies to the actual remote extensions that handle the DBUS communications transparently for the application developer.
After getting a reference to the MafwRegistry object, invoking mafw_shared_init starts the extension discovery, which will look for available extensions and register them. Whenever a new extension is found or removed, the registry emits a signal to inform the application.
It is also possible that extensions were loaded in the registry before the application attached its signal handlers. In this case the application will not get any signals for these extensions and has to query the registry for them using mafw\_registry\_get\_renderers and mafw\_registry\_get\_sources. One should notice that these lists of available extensions must not be freed:
extension_list = mafw_registry_get_renderers(registry); while (extension_list) { renderer_added_cb(registry, G_OBJECT(extension_list->data), NULL); extension_list = g_list_next(extension_list); } extension_list = mafw_registry_get_sources(registry); while (extension_list) { source_added_cb(registry, G_OBJECT(extension_list->data), NULL); extension_list = g_list_next(extension_list); }
Notice that these lists of available extensions should not be freed.
The source-added and renderer-added callbacks look like this:
static void source_added_cb(MafwRegistry *registry, GObject *source, gpointer user_data) { if (MAFW_IS_SOURCE(source)) { /* Handle new source extension */ } } static void renderer_added_cb(MafwRegistry *registry, GObject *renderer, gpointer user_data) { if (MAFW_IS_RENDERER(renderer)) { /* Handle new renderer extension here */ } }
Contrary to the out-of-process approach, in-process extensions are loaded in the same address space of the application's process. In this case we do not have to start a discovery process, instead we can either load all the available plugins or load specific plugins. As in the out-of-process case, this is done through the MafwRegistry object.
registry = MAFW_REGISTRY(mafw_registry_get_instance()); if (registry == NULL) { /* Error management here */ }
After getting a reference to the registry, execute:
mafw_registry_load_plugins(registry);
Individual extensions can be loaded manually by using mafw_registry_load_plugin and declaring the extension to load:
mafw_registry_load_plugin(MAFW_REGISTRY(registry), "mafw-plugin.so", &error); if (error != NULL) { /* Error management here */ }
The second parameter of mafw_registry_load_plugin can be just a filename (in this case the default plugin directory will be used) or the absolute path of the plugin file.
As in the out-of-process approach, the application has to be informed of loaded extensions. The same code as for the out-of-process case can be used here.
This approach loads the extensions in the registry first and then queries it for the lists of available renderers and sources, like this:
mafw_registry_load_plugins(registry); extension_list = mafw_registry_get_renderers(registry); while (extension_list) { renderer_added_cb(registry, G_OBJECT(extension_list->data), NULL); extension_list = g_list_next(extension_list); } extension_list = mafw_registry_get_sources(registry); while (extension_list) { source_added_cb(registry, G_OBJECT(extension_list->data), NULL); extension_list = g_list_next(extension_list); }
This approach is more asynchronous and it is recommended because it can easily handle sources or renderers added after the application was started. It is done by connecting callbacks to the "source-added" and "renderer-added" signals. As soon as a plugin is loaded, a signal is emitted and the application can react to it, preparing everything to use that extension, like this:
registry = MAFW_REGISTRY(mafw_registry_get_instance()); if (registry == NULL) { /* Error handling here */ } g_signal_connect(registry, "renderer_added", G_CALLBACK(renderer_added_cb), NULL); g_signal_connect(registry, "source_added", G_CALLBACK(source_added_cb), NULL); g_signal_connect(registry, "renderer_removed", G_CALLBACK(renderer_removed_cb), NULL); g_signal_connect(registry, "source_removed", G_CALLBACK(source_removed_cb), NULL); mafw_registry_load_plugins(registry);
The form of the callbacks for these signals is the same as in the out-of-process case.
There are a few issues to consider when making the decision of using in-process or out-of-process extensions: