Other issues

Properties

MafwExtension objects (renderers and sources) can define properties (MafwExtension properties, not GObject's) to configure them on execution time. To use them, get and set functions have to be provided and hooked in the class_init method. method:

static void 
mafw_my_renderer_get_property(MafwExtension *self,
	 		      const gchar *key,
			      MafwExtensionPropertyCallback callback,
			      gpointer user_data)
{
	MafwMyRenderer *renderer;
	GValue *value = NULL;
	GError *error = NULL;

	g_return_if_fail(MAFW_IS_MY_RENDERER(self));
	g_return_if_fail(callback != NULL);
	g_return_if_fail(key != NULL);

	renderer = MAFW_MY_RENDERER(self);
	if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
		value = g_new0(GValue, 1);
		g_value_init(value, G_TYPE_UINT);
		g_value_set_uint(value, volume);
	}
	else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
           ...
	}
	else {
		/* Unsupported property */
		error = g_error_new(MAFW_MY_RENDERER_ERROR,
				    MAFW_EXTENSION_ERROR_GET_PROPERTY,
				    "Unsupported property");
	}

	callback(self, key, value, user_data, error);
}

static gboolean
mafw_my_renderer_set_property(MafwExtension *self,
                              const gchar *key,
                              const GValue *value)
{
	MafwMyRenderer *renderer;

	g_return_if_fail(MAFW_IS_MY_RENDERER(self));
	g_return_if_fail(key != NULL);

	renderer = MAFW_MY_RENDERER(self);

	if (!strcmp(key, MAFW_PROPERTY_RENDERER_VOLUME)) {
		guint volume = g_value_get_uint(value);
		volume = CLAMP(volume, 0, 100);
                _do_set_volume(renderer, volume);
	}
	else if (!strcmp(key, MAFW_PROPERTY_RENDERER_MUTE)) {
         ...
        }
	else {
		/* Unsupported property */
                return FALSE;
	}

	mafw_extension_emit_property_changed(self, key, value);

        return TRUE;
}

static void mafw_my_renderer_class_init(MafwMyRendererClass *klass)
{
        ...
        MAFW_EXTENSION_CLASS(klass)->get_extension_property =
          (gpointer) mafw_my_renderer_get_property;
        MAFW_EXTENSION_CLASS(klass)->set_extension_property =
          (gpointer) mafw_my_renderer_set_property;
        ...
}
        

Properties declaration is done in the object's init function:

static void mafw_my_renderer_init(MafwMyRenderer *self)
{
        ...
	mafw_extension_add_property(MAFW_EXTENSION(self), "volume", G_TYPE_UINT);
	mafw_extension_add_property(MAFW_EXTENSION(self), "mute", G_TYPE_BOOLEAN);
        ...
}
        

The code shows examples of renderer properties, but the same could be applied to sources (as this is a mechanism defined for any kind of extension), for example, a slow source could use properties to define an eager vs. lazy strategy or the use of caches.