Using a renderer

Renderers are plugins, therefore, the first step is to obtain a reference to them using the framework registry, like this:

MafwProxyRegistry *registry = MAFW_REGISTRY(mafw_registry_get_instance());
if (registry) {
        GList *renderers = mafw_registry_get_renderers(MAFW_REGISTRY(registry));
}

The code above allows the application developer to obtain a list of available renderers. The developer can use this list to show the available renderers to the users, allowing them to select the renderer they are interested in.

Once we have got a reference to the renderer we are interested in, then the application developer can start using it. Here is a simple example:

static void
_generic_error_cb(MafwExtension *extension, guint domain, guint code, gchar *message, 
                  gpointer user_data)
{
        /* Error management code here */
}

static void
error_cb(MafwRenderer* renderer, gpointer user_data, const GError* error)
{
        if (error != NULL) {
                /* error management code here */
        } else {
                /* Operation was successful */
        }
}

static void
play_button_clicked_cb(GtkButton *button, gpointer user_data)
{
        MafwRenderer *renderer = (MafwRenderer *) user_data;
        mafw_renderer_play(renderer, error_cb, NULL);
}

static void
pause_button_clicked_cb(GtkButton *button, gpointer user_data)
{
        MafwRenderer *renderer = (MafwRenderer *) user_data;
        mafw_renderer_pause(renderer, error_cb, NULL);
}

static void
resume_button_clicked_cb(GtkButton *button, gpointer user_data)
{
        MafwRenderer *renderer = (MafwRenderer *) user_data;
        mafw_renderer_resume(renderer, error_cb, NULL);
}

static void
stop_button_clicked_cb(GtkButton *button, gpointer user_data)
{
        MafwRenderer *renderer = (MafwRenderer *) user_data;
        mafw_renderer_stop(renderer, error_cb, NULL);
}

static void
state_changed_cb(MafwRenderer *renderer, MafwPlayState state, gpointer user_data)
{
        switch (state) {
                case Playing:
                        /* Enable Pause button */
                        break;
                case Paused:
                        /* Enable Resume button */
                        break;
                case Stopped:
                        /* Disable Pause/Resume button */
                        break;
                default:
                        break;
        }
}

static void
media_changed_cb(MafwRenderer *renderer, gint index, gchar *object_id, 
                 gpointer user_data)
{
        if (index >= 0) {
                /* Update UI: select item at position 'index' */
        } else {
               /* Playlist playback interrupted, maybe inform the user
                  about this and then wait until it is resumed, then we 
                  will get a new media-changed signal */
        }
}

static void 
assign_playlist_cb(MafwRenderer *renderer, gpointer user_data, const GError *error)
{
        if (error != NULL) {
                /* error management code here */
        } else {
               /* Start playback right away! */
                mafw_renderer_play(renderer, error_cb, NULL);
        }
}

static void 
renderer_example(void) 
{
        MafwRenderer *renderer = NULL;

        MafwProxyRegistry *registry = 
                MAFW_REGISTRY(mafw_registry_get_instance());

        if (registry) {
                GList *renderers = 
                        mafw_registry_get_renderers(MAFW_REGISTRY(registry));
                if (renderers) {
                        /* Let's just take the first one */
                        renderer = (MafwRenderer *) renderers->data;
                        g_object_ref(renderer);
                }
        }

        if (renderer) {
                g_signal_connect(MAFW_EXTENSION(renderer), "error",
                                 G_CALLBACK(_generic_error_cb), NULL);
                g_signal_connect(renderer, "state-changed",
                                 G_CALLBACK(state_changed_cb), NULL);
                g_signal_connect(renderer, "media-changed",
                                 G_CALLBACK(media_changed_cb), NULL);
     
                mafw_renderer_assign_playlist(renderer, playlist, 
                                          assign_playlist_cb, NULL);
        }
}

The code above assumes an application with four playback buttons (Play, Pause, Resume and Stop), being *_button_clicked_cb the handlers for the clicked events of these buttons.

The program starts by selecting a suitable renderer if any, then it assigns a playlist to the renderer, and, if the playlist could be assigned, it starts playing it right away. As you can see mafw_renderer_play plays the item currently selected in the renderer, there is no need to specify the index in the function call. This applies also for other playback functions.

You can check the Mafw API reference for further details about the renderer API.