The bonobo component now works on audio only (mp3/vorbis). Video is broken because bonobo does not handle multithread...

Original commit message from CVS:
The bonobo component now works on audio only (mp3/vorbis). Video
is broken because bonobo does not handle multithreading yet.
Added Bonobo toolbar and menu.
This commit is contained in:
Wim Taymans 2000-11-12 20:34:29 +00:00
parent ef31aa64e8
commit 01eb2caf72
3 changed files with 277 additions and 305 deletions

View file

@ -5,14 +5,14 @@ INCLUDES = -I$(top_srcdir)/gst \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-DDATADIR=\""$(datadir)"\" \ -DDATADIR=\""$(datadir)"\" \
-I$(includedir) \ -I$(includedir) \
$(BONOBOX_TEST_CFLAGS) $(BONOBOX_TEST_CFLAGS) -Wall -O2
bin_PROGRAMS = bonobo-gstmediaplay bin_PROGRAMS = bonobo-gstmediaplay
bonobo_gstmediaplay_SOURCES = \ bonobo_gstmediaplay_SOURCES = \
bonobo-gstmediaplay.c bonobo-gstmediaplay.c
bonobo_gstmediaplay_CFLAGS = \ bonobo_gstmediaplay_CFLAGS = -Wall -O2 \
$(shell gnome-config --cflags gnomeui bonobo bonobox) $(shell libglade-config --cflags gnome) \ $(shell gnome-config --cflags gnomeui bonobo bonobox) $(shell libglade-config --cflags gnome) \
$(shell gstreamer-config --clfags ) $(shell gstreamer-config --clfags )

View file

@ -25,6 +25,10 @@
#include "gstplay.h" #include "gstplay.h"
#include "pause.xpm"
#include "play.xpm"
#include "stop.xpm"
/* /*
* Number of running objects * Number of running objects
*/ */
@ -35,10 +39,10 @@ static BonoboGenericFactory *factory = NULL;
* BonoboControl data * BonoboControl data
*/ */
typedef struct { typedef struct {
BonoboControl *bonobo_object; BonoboControl *bonobo_object;
BonoboUIComponent *uic; BonoboUIComponent *uic;
GstPlay *play; GstPlay *play;
} control_data_t; } control_data_t;
/* /*
@ -49,107 +53,88 @@ static void
control_system_exception_cb (BonoboControl *control, CORBA_Object corba_object, control_system_exception_cb (BonoboControl *control, CORBA_Object corba_object,
CORBA_Environment *ev, gpointer data) CORBA_Environment *ev, gpointer data)
{ {
bonobo_object_unref (BONOBO_OBJECT (control)); bonobo_object_unref (BONOBO_OBJECT (control));
} }
static void static void
control_update (control_data_t *control_data) control_update (control_data_t *control_data)
{ {
g_print("control_update\n", running_objects); gtk_widget_queue_draw (GTK_WIDGET (control_data->play));
gtk_widget_queue_draw (GTK_WIDGET (control_data->play));
g_print("control_update done\n", running_objects);
} }
static void static void
load_media (BonoboPersistStream *ps, verb_Play_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
const Bonobo_Stream stream,
Bonobo_Persist_ContentType type,
void *closure,
CORBA_Environment *ev)
{ {
control_data_t *control_data = closure; control_data_t *control_data = (control_data_t *) user_data;
GstPlay *pl;
Bonobo_Stream_iobuf *buffer;
char *str;
int bx, by, j;
g_return_if_fail (control_data != NULL); gst_play_play (control_data->play);
g_return_if_fail (control_data->play != NULL); control_update (control_data);
if (*type && g_strcasecmp (type, "application/x-gstmediaplay") != 0) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_Bonobo_Persist_WrongDataType, NULL);
return;
}
pl = control_data->play;
bonobo_stream_client_read_string (stream, &str, ev);
if (ev->_major != CORBA_NO_EXCEPTION || str == NULL) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_Bonobo_Persist_WrongDataType, NULL);
return;
}
sscanf (str, "%2u%2u\n", &bx, &by);
g_free (str);
if (bx > 128 || by > 128) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_Bonobo_Persist_WrongDataType, NULL);
return;
}
for (j = 0; j < by; j++) {
int i;
Bonobo_Stream_read (stream, bx * 2 + 1, &buffer, ev);
if (ev->_major != CORBA_NO_EXCEPTION)
return;
else if (buffer->_length != bx * 2 + 1) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_Bonobo_Persist_WrongDataType,
NULL);
return;
}
CORBA_free (buffer);
}
control_update (control_data);
} }
static void static void
save_media (BonoboPersistStream *ps, verb_Pause_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
const Bonobo_Stream stream,
Bonobo_Persist_ContentType type,
void *closure,
CORBA_Environment *ev)
{ {
control_data_t *control_data = closure; control_data_t *control_data = (control_data_t *) user_data;
GstPlay *pl;
char *data;
int j;
g_return_if_fail (control_data != NULL); gst_play_pause (control_data->play);
g_return_if_fail (control_data->play != NULL); control_update (control_data);
if (*type && g_strcasecmp (type, "application/x-gstmediaplay") != 0) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
ex_Bonobo_Persist_WrongDataType, NULL);
return;
}
pl = control_data->play;
if (ev->_major != CORBA_NO_EXCEPTION)
return;
} }
static Bonobo_Persist_ContentTypeList * static void
content_types (BonoboPersistStream *ps, void *closure, CORBA_Environment *ev) verb_Stop_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{ {
return bonobo_persist_generate_content_types (1, "application/x-gstmediaplay"); control_data_t *control_data = (control_data_t *) user_data;
gst_play_stop (control_data->play);
control_update (control_data);
}
typedef struct {
control_data_t *control_data;
GtkFileSelection *selector;
} file_select_struct;
static void
filename_selected (GtkButton *ok, gpointer user_data)
{
file_select_struct *select = (file_select_struct *) user_data;
gchar *selected_filename;
selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(select->selector));
gst_play_set_uri (select->control_data->play, selected_filename);
gst_play_play (select->control_data->play);
control_update (select->control_data);
g_free(select);
}
static void
verb_Open_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
{
control_data_t *control_data = (control_data_t *) user_data;
file_select_struct *data = g_new0(file_select_struct, 1);
GtkWidget *file_selector;
file_selector = gtk_file_selection_new("Select a media file");
data->selector = GTK_FILE_SELECTION (file_selector);
data->control_data = control_data;
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked", GTK_SIGNAL_FUNC (filename_selected), data);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->cancel_button),
"clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_widget_show (file_selector);
} }
/* /*
@ -159,71 +144,93 @@ content_types (BonoboPersistStream *ps, void *closure, CORBA_Environment *ev)
static void static void
control_create_menus (control_data_t *control_data) control_create_menus (control_data_t *control_data)
{ {
BonoboControl *control = control_data->bonobo_object; BonoboControl *control = control_data->bonobo_object;
Bonobo_UIContainer remote_uic; Bonobo_UIContainer remote_uic;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
static char ui [] = static char ui [] =
"<Root>" "<Root>"
" <commands>" " <commands>"
" <cmd name=\"NewGame\" _label=\"New game\" _tip=\"Start a new game\"/>" " <cmd name=\"Play\" _label=\"Play\" _tip=\"Play\"/>"
" <cmd name=\"OpenGame\" _label=\"Open game\" _tip=\"Load a saved game\"/>" " <cmd name=\"Pause\" _label=\"Pause\" _tip=\"Pause\"/>"
" </commands>" " <cmd name=\"Stop\" _label=\"Stop\" _tip=\"Stop\"/>"
" <menu>" " <cmd name=\"Open\" _label=\"Open Media\" _tip=\"Open a media stream\"/>"
" <submenu name=\"Game\" _label=\"_Game\">" " </commands>"
" <menuitem name=\"NewGame\" verb=\"\"/>" " <menu>"
" <menuitem name=\"OpenGame\" verb=\"\"/>" " <submenu name=\"Player\" _label=\"_Player\">"
" </submenu>" " <menuitem name=\"Open\" pixtype=\"stock\" pixname=\"Open\" verb=\"\"/>"
" </menu>" " <separator/>"
" <dockitem name=\"Game\">" " <menuitem name=\"Play\" verb=\"\"/>"
" <toolitem name=\"NewGame\" verb=\"\"/>" " <menuitem name=\"Pause\" verb=\"\"/>"
" </dockitem>" " <menuitem name=\"Stop\" verb=\"\"/>"
"</Root>"; " </submenu>"
" </menu>"
" <dockitem name=\"GstMediaPlay\">"
" <toolitem name=\"Play\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Pause\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Stop\" type=\"toggle\" verb=\"\"/>"
" </dockitem>"
"</Root>";
/* g_print("create menu\n");
* Get our container's UIContainer server. /*
*/ * Get our container's UIContainer server.
remote_uic = bonobo_control_get_remote_ui_container (control); */
remote_uic = bonobo_control_get_remote_ui_container (control);
/* /*
* We have to deal gracefully with containers * We have to deal gracefully with containers
* which don't have a UIContainer running. * which don't have a UIContainer running.
*/ */
if (remote_uic == CORBA_OBJECT_NIL) { if (remote_uic == CORBA_OBJECT_NIL) {
g_warning ("No UI container!"); g_warning ("No UI container!");
return; return;
} }
/*
* Give our BonoboUIComponent object a reference to the
* container's UIContainer server.
*/
bonobo_ui_component_set_container (control_data->uic, remote_uic);
/* /*
* Unref the UI container we have been passed. * Give our BonoboUIComponent object a reference to the
*/ * container's UIContainer server.
bonobo_object_release_unref (remote_uic, NULL); */
bonobo_ui_component_set_container (control_data->uic, remote_uic);
/* Set up the UI from the XML string. */ /*
{ * Unref the UI container we have been passed.
BonoboUINode *node; */
bonobo_object_release_unref (remote_uic, NULL);
node = bonobo_ui_node_from_string (ui); /* Set up the UI from the XML string. */
bonobo_ui_util_translate_ui (node); {
bonobo_ui_util_fixup_help (control_data->uic, node, BonoboUINode *node;
DATADIR, "gstmediaplay");
node = bonobo_ui_node_from_string (ui);
bonobo_ui_util_translate_ui (node);
bonobo_ui_util_fixup_help (control_data->uic, node,
DATADIR, "gstmediaplay");
bonobo_ui_component_set_tree (control_data->uic, "/", node, NULL); bonobo_ui_component_set_tree (control_data->uic, "/", node, NULL);
bonobo_ui_node_free (node);
}
pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) play_back_xpm);
bonobo_ui_util_set_pixbuf (control_data->uic, "/commands/Play", pixbuf);
gdk_pixbuf_unref (pixbuf);
pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) pause_xpm);
bonobo_ui_util_set_pixbuf (control_data->uic, "/commands/Pause", pixbuf);
gdk_pixbuf_unref (pixbuf);
pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) stop_back_xpm);
bonobo_ui_util_set_pixbuf (control_data->uic, "/commands/Stop", pixbuf);
gdk_pixbuf_unref (pixbuf);
bonobo_ui_node_free (node);
}
} }
static void static void
control_remove_menus (control_data_t *control_data) control_remove_menus (control_data_t *control_data)
{ {
bonobo_ui_component_unset_container (control_data->uic); bonobo_ui_component_unset_container (control_data->uic);
} }
/* /*
@ -232,214 +239,179 @@ control_remove_menus (control_data_t *control_data)
static void static void
control_destroy_cb (BonoboControl *control, gpointer data) control_destroy_cb (BonoboControl *control, gpointer data)
{ {
control_data_t *control_data = (control_data_t *) data; control_data_t *control_data = (control_data_t *) data;
g_message ("control_destroy_cb"); control_data->play = NULL;
control_data->play = NULL;
g_free (control_data); g_free (control_data);
running_objects--; running_objects--;
if (running_objects > 0) if (running_objects > 0)
return; return;
/* /*
* When the last object has gone, unref the factory & quit. * When the last object has gone, unref the factory & quit.
*/ */
bonobo_object_unref (BONOBO_OBJECT (factory)); bonobo_object_unref (BONOBO_OBJECT (factory));
gtk_main_quit (); gtk_main_quit ();
} }
static void static void
control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
{ {
control_data_t *control_data = (control_data_t *) data; control_data_t *control_data = (control_data_t *) data;
g_message ("control_activate"); g_message ("control_activate");
/* /*
* The ControlFrame has just asked the Control (that's us) to be * The ControlFrame has just asked the Control (that's us) to be
* activated or deactivated. We must reply to the ControlFrame * activated or deactivated. We must reply to the ControlFrame
* and say whether or not we want our activation state to * and say whether or not we want our activation state to
* change. We are an acquiescent BonoboControl, so we just agree * change. We are an acquiescent BonoboControl, so we just agree
* with whatever the ControlFrame told us. Most components * with whatever the ControlFrame told us. Most components
* should behave this way. * should behave this way.
*/ */
bonobo_control_activate_notify (control, activate); bonobo_control_activate_notify (control, activate);
/* /*
* If we were just activated, we merge in our menu entries. * If we were just activated, we merge in our menu entries.
* If we were just deactivated, we remove them. * If we were just deactivated, we remove them.
*/ */
if (activate) if (activate)
control_create_menus (control_data); control_create_menus (control_data);
else else
control_remove_menus (control_data); control_remove_menus (control_data);
} }
static void static void
control_set_frame_cb (BonoboControl *control, gpointer data) control_set_frame_cb (BonoboControl *control, gpointer data)
{ {
g_message ("control_set frame cb"); control_create_menus ((control_data_t *) data);
control_create_menus ((control_data_t *) data);
g_message ("control_set frame cb done");
}
static void
update_control (GtkWidget *widget, control_data_t *control_data)
{
g_message ("update_control");
control_update (control_data);
} }
static BonoboObject * static BonoboObject *
bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data) bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data)
{ {
BonoboControl *bonobo_object; BonoboControl *bonobo_object;
control_data_t *control_data; control_data_t *control_data;
BonoboPersistStream *stream; GtkWidget *vbox;
GtkWidget *vbox;
/* gst_init (NULL, NULL);
* Create a data structure in which we can store /*
* Control-object-specific data about this document. * Create a data structure in which we can store
*/ * Control-object-specific data about this document.
control_data = g_new0 (control_data_t, 1); */
if (control_data == NULL) control_data = g_new0 (control_data_t, 1);
return NULL; if (control_data == NULL)
return NULL;
g_print("creating\n"); control_data->play = gst_play_new ();
control_data->play = gst_play_new ();
g_print("created\n");
vbox = gtk_vbox_new (TRUE, 0); vbox = gtk_vbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (control_data->play), gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (control_data->play),
TRUE, TRUE, 0); TRUE, TRUE, 0);
gtk_widget_show_all (vbox); gtk_widget_show_all (vbox);
/* /*
* Create the BonoboControl object. * Create the BonoboControl object.
*/ */
bonobo_object = bonobo_control_new (vbox); bonobo_object = bonobo_control_new (vbox);
if (bonobo_object == NULL) { if (bonobo_object == NULL) {
gtk_widget_destroy (vbox); gtk_widget_destroy (vbox);
g_free (control_data); g_free (control_data);
return NULL; return NULL;
} }
control_data->bonobo_object = bonobo_object; control_data->bonobo_object = bonobo_object;
control_data->uic = bonobo_control_get_ui_component (bonobo_object); control_data->uic = bonobo_control_get_ui_component (bonobo_object);
/* /*
* When our container wants to activate this component, we will get * When our container wants to activate this component, we will get
* the "activate" signal. * the "activate" signal.
*/ */
gtk_signal_connect (GTK_OBJECT (bonobo_object), "activate", gtk_signal_connect (GTK_OBJECT (bonobo_object), "activate",
GTK_SIGNAL_FUNC (control_activate_cb), control_data); GTK_SIGNAL_FUNC (control_activate_cb), control_data);
gtk_signal_connect (GTK_OBJECT (bonobo_object), "set_frame", gtk_signal_connect (GTK_OBJECT (bonobo_object), "set_frame",
GTK_SIGNAL_FUNC (control_set_frame_cb), control_data); GTK_SIGNAL_FUNC (control_set_frame_cb), control_data);
/* /*
* The "system_exception" signal is raised when the BonoboControl * The "system_exception" signal is raised when the BonoboControl
* encounters a fatal CORBA exception. * encounters a fatal CORBA exception.
*/ */
gtk_signal_connect (GTK_OBJECT (bonobo_object), "system_exception", gtk_signal_connect (GTK_OBJECT (bonobo_object), "system_exception",
GTK_SIGNAL_FUNC (control_system_exception_cb), control_data); GTK_SIGNAL_FUNC (control_system_exception_cb), control_data);
/* /*
* We'll need to be able to cleanup when this control gets * We'll need to be able to cleanup when this control gets
* destroyed. * destroyed.
*/ */
gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy",
GTK_SIGNAL_FUNC (control_destroy_cb), control_data); GTK_SIGNAL_FUNC (control_destroy_cb), control_data);
/* bonobo_ui_component_add_verb (control_data->uic, "Play",
* Create the PersistStream object. verb_Play_cb, control_data);
*/ bonobo_ui_component_add_verb (control_data->uic, "Pause",
stream = bonobo_persist_stream_new (load_media, save_media, verb_Pause_cb, control_data);
NULL, content_types, bonobo_ui_component_add_verb (control_data->uic, "Stop",
control_data); verb_Stop_cb, control_data);
if (stream == NULL) { bonobo_ui_component_add_verb (control_data->uic, "Open",
bonobo_object_unref (BONOBO_OBJECT (bonobo_object)); verb_Open_cb, control_data);
gtk_widget_destroy (vbox);
g_free (control_data);
return NULL;
}
bonobo_object_add_interface (BONOBO_OBJECT (bonobo_object),
BONOBO_OBJECT (stream));
/* /*
* Add some verbs to the control. * Count the new running object
* */
* The container application will then have the programmatic running_objects++;
* ability to execute the verbs on the component. It will g_print("running objects: %d\n", running_objects);
* also provide a simple mechanism whereby the user can
* right-click on the component to create a popup menu
* listing the available verbs.
*
* We provide one simple verb whose job it is to clear the
* window.
*/
control_data->uic = bonobo_control_get_ui_component (bonobo_object);
/* return BONOBO_OBJECT (bonobo_object);
* Count the new running object
*/
running_objects++;
g_print("running objects: %d\n", running_objects);
return BONOBO_OBJECT (bonobo_object);
} }
static void static void
init_gstmediaplay_factory (void) init_gstmediaplay_factory (void)
{ {
printf("init factory\n"); factory = bonobo_generic_factory_new (
factory = bonobo_generic_factory_new ( "OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18",
"OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18", bonobo_gstmediaplay_factory, NULL);
bonobo_gstmediaplay_factory, NULL);
} }
static void static void
init_server_factory (int argc, char **argv) init_server_factory (int argc, char **argv)
{ {
CORBA_Environment ev; CORBA_Environment ev;
CORBA_ORB orb; CORBA_ORB orb;
bindtextdomain (PACKAGE, GNOMELOCALEDIR); bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE); textdomain (PACKAGE);
CORBA_exception_init (&ev); CORBA_exception_init (&ev);
gnome_init_with_popt_table("gstmediaplay", VERSION, gnome_init_with_popt_table("bonobo-gstmediaplay", VERSION,
argc, argv, argc, argv,
oaf_popt_options, 0, NULL); oaf_popt_options, 0, NULL);
orb = oaf_init (argc, argv); orb = oaf_init (argc, argv);
CORBA_exception_free (&ev); if (bonobo_init (orb, NULL, NULL) == FALSE)
g_error (_("Could not initialize Bonobo!"));
if (bonobo_init (orb, NULL, NULL) == FALSE) CORBA_exception_free (&ev);
g_error (_("Could not initialize Bonobo!"));
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
gst_init (&argc, &argv); /*
/* * Setup the factory.
* Setup the factory. */
*/ init_server_factory (argc, argv);
init_server_factory (argc, argv); init_gstmediaplay_factory ();
init_gstmediaplay_factory ();
/* /*
* Start processing. * Start processing.
*/ */
bonobo_main (); bonobo_main ();
return 0; return 0;
} }

View file

@ -1,20 +1,20 @@
<oaf_info> <oaf_info>
<oaf_server iid="OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18" type="exe" location="bonobo-gstmediaplay"> <oaf_server iid="OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18" type="exe" location="bonobo-gstmediaplay">
<oaf_attribute name="repo_ids" type="stringv"> <oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/GenericFactory:1.0"/> <item value="IDL:Bonobo/GenericFactory:1.0"/>
</oaf_attribute> </oaf_attribute>
<oaf_attribute name="name" type="string" value="GstMediaPlay control factory"/> <oaf_attribute name="name" type="string" value="GstMediaPlay control factory"/>
<oaf_attribute name="description" type="string" value="bonobo GstMediaPlay object factory"/> <oaf_attribute name="description" type="string" value="bonobo GstMediaPlay object factory"/>
</oaf_server> </oaf_server>
<oaf_server iid="OAFIID:bonobo_gstmediaplay:b6735078-0a67-4db0-aba6-ce37ecb63ff2" type="factory" location="OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18"> <oaf_server iid="OAFIID:bonobo_gstmediaplay:b6735078-0a67-4db0-aba6-ce37ecb63ff2" type="factory" location="OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18">
<oaf_attribute name="repo_ids" type="stringv"> <oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Control:1.0"/> <item value="IDL:Bonobo/Control:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/> <item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute> </oaf_attribute>
<oaf_attribute name="name" type="string" value="GstMediaPlay control"/> <oaf_attribute name="name" type="string" value="GstMediaPlay control"/>
<oaf_attribute name="description" type="string" value="bonobo GstMediaPlay object"/> <oaf_attribute name="description" type="string" value="bonobo GstMediaPlay object"/>
</oaf_server> </oaf_server>
</oaf_info> </oaf_info>