| /* GStreamer |
| * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #include <config.h> |
| #include <gnome.h> |
| #include <liboaf/liboaf.h> |
| |
| #include <bonobo.h> |
| |
| #include "gstplay.h" |
| |
| #include "pause.xpm" |
| #include "play.xpm" |
| #include "stop.xpm" |
| |
| /* |
| * Number of running objects |
| */ |
| static int running_objects = 0; |
| static BonoboGenericFactory *factory = NULL; |
| |
| /* |
| * BonoboControl data |
| */ |
| typedef struct |
| { |
| BonoboControl *bonobo_object; |
| BonoboUIComponent *uic; |
| |
| GstPlay *play; |
| } |
| control_data_t; |
| |
| /* |
| * This callback is invoked when the BonoboControl object |
| * encounters a fatal CORBA exception. |
| */ |
| static void |
| control_system_exception_cb (BonoboControl * control, CORBA_Object corba_object, |
| CORBA_Environment * ev, gpointer data) |
| { |
| bonobo_object_unref (BONOBO_OBJECT (control)); |
| } |
| |
| static void |
| control_update (control_data_t * control_data) |
| { |
| gtk_widget_queue_draw (GTK_WIDGET (control_data->play)); |
| } |
| |
| static void |
| verb_Play_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname) |
| { |
| control_data_t *control_data = (control_data_t *) user_data; |
| |
| gst_play_play (control_data->play); |
| control_update (control_data); |
| } |
| |
| static void |
| verb_Pause_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname) |
| { |
| control_data_t *control_data = (control_data_t *) user_data; |
| |
| gst_play_pause (control_data->play); |
| control_update (control_data); |
| } |
| |
| static void |
| verb_Stop_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname) |
| { |
| 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); |
| } |
| |
| /* |
| * When one of our controls is activated, we merge our menus |
| * in with our container's menus. |
| */ |
| static void |
| control_create_menus (control_data_t * control_data) |
| { |
| BonoboControl *control = control_data->bonobo_object; |
| Bonobo_UIContainer remote_uic; |
| GdkPixbuf *pixbuf; |
| |
| static char ui[] = |
| "<Root>" |
| " <commands>" |
| " <cmd name=\"Play\" _label=\"Play\" _tip=\"Play\"/>" |
| " <cmd name=\"Pause\" _label=\"Pause\" _tip=\"Pause\"/>" |
| " <cmd name=\"Stop\" _label=\"Stop\" _tip=\"Stop\"/>" |
| " <cmd name=\"Open\" _label=\"Open Media\" _tip=\"Open a media stream\"/>" |
| " </commands>" |
| " <menu>" |
| " <submenu name=\"Player\" _label=\"_Player\">" |
| " <menuitem name=\"Open\" pixtype=\"stock\" pixname=\"Open\" verb=\"\"/>" |
| " <separator/>" |
| " <menuitem name=\"Play\" verb=\"\"/>" |
| " <menuitem name=\"Pause\" verb=\"\"/>" |
| " <menuitem name=\"Stop\" verb=\"\"/>" |
| " </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. |
| */ |
| remote_uic = bonobo_control_get_remote_ui_container (control); |
| |
| /* |
| * We have to deal gracefully with containers |
| * which don't have a UIContainer running. |
| */ |
| if (remote_uic == CORBA_OBJECT_NIL) { |
| g_warning ("No UI container!"); |
| 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. |
| */ |
| bonobo_object_release_unref (remote_uic, NULL); |
| |
| /* Set up the UI from the XML string. */ |
| { |
| BonoboUINode *node; |
| |
| 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_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); |
| |
| g_print ("create menu done\n"); |
| } |
| |
| static void |
| control_remove_menus (control_data_t * control_data) |
| { |
| bonobo_ui_component_unset_container (control_data->uic); |
| } |
| |
| /* |
| * Clean up our supplementary BonoboControl data sturctures. |
| */ |
| static void |
| control_destroy_cb (BonoboControl * control, gpointer data) |
| { |
| control_data_t *control_data = (control_data_t *) data; |
| |
| control_data->play = NULL; |
| |
| g_free (control_data); |
| |
| running_objects--; |
| if (running_objects > 0) |
| return; |
| |
| /* |
| * When the last object has gone, unref the factory & quit. |
| */ |
| bonobo_object_unref (BONOBO_OBJECT (factory)); |
| gtk_main_quit (); |
| } |
| |
| static void |
| control_activate_cb (BonoboControl * control, gboolean activate, gpointer data) |
| { |
| control_data_t *control_data = (control_data_t *) data; |
| |
| g_message ("control_activate"); |
| /* |
| * The ControlFrame has just asked the Control (that's us) to be |
| * activated or deactivated. We must reply to the ControlFrame |
| * and say whether or not we want our activation state to |
| * change. We are an acquiescent BonoboControl, so we just agree |
| * with whatever the ControlFrame told us. Most components |
| * should behave this way. |
| */ |
| bonobo_control_activate_notify (control, activate); |
| |
| /* |
| * If we were just activated, we merge in our menu entries. |
| * If we were just deactivated, we remove them. |
| */ |
| if (activate) |
| control_create_menus (control_data); |
| else |
| control_remove_menus (control_data); |
| } |
| |
| static void |
| control_set_frame_cb (BonoboControl * control, gpointer data) |
| { |
| control_create_menus ((control_data_t *) data); |
| } |
| |
| static BonoboObject * |
| bonobo_gstmediaplay_factory (BonoboGenericFactory * this, void *data) |
| { |
| BonoboControl *bonobo_object; |
| control_data_t *control_data; |
| GtkWidget *vbox; |
| |
| gst_init (NULL, NULL); |
| /* |
| * 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) |
| return NULL; |
| |
| control_data->play = gst_play_new (); |
| |
| |
| vbox = gtk_vbox_new (TRUE, 0); |
| |
| gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (control_data->play), |
| TRUE, TRUE, 0); |
| gtk_widget_show_all (vbox); |
| |
| gst_play_set_uri (control_data->play, "/opt/data/armageddon1.mpg"); |
| gst_play_play (control_data->play); |
| |
| /* |
| * Create the BonoboControl object. |
| */ |
| bonobo_object = bonobo_control_new (vbox); |
| |
| if (bonobo_object == NULL) { |
| gtk_widget_destroy (vbox); |
| g_free (control_data); |
| return NULL; |
| } |
| |
| control_data->bonobo_object = bonobo_object; |
| |
| control_data->uic = bonobo_control_get_ui_component (bonobo_object); |
| |
| /* |
| * When our container wants to activate this component, we will get |
| * the "activate" signal. |
| */ |
| gtk_signal_connect (GTK_OBJECT (bonobo_object), "activate", |
| GTK_SIGNAL_FUNC (control_activate_cb), control_data); |
| gtk_signal_connect (GTK_OBJECT (bonobo_object), "set_frame", |
| GTK_SIGNAL_FUNC (control_set_frame_cb), control_data); |
| |
| /* |
| * The "system_exception" signal is raised when the BonoboControl |
| * encounters a fatal CORBA exception. |
| */ |
| gtk_signal_connect (GTK_OBJECT (bonobo_object), "system_exception", |
| GTK_SIGNAL_FUNC (control_system_exception_cb), control_data); |
| |
| /* |
| * We'll need to be able to cleanup when this control gets |
| * destroyed. |
| */ |
| gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", |
| GTK_SIGNAL_FUNC (control_destroy_cb), control_data); |
| |
| bonobo_ui_component_add_verb (control_data->uic, "Play", |
| verb_Play_cb, control_data); |
| bonobo_ui_component_add_verb (control_data->uic, "Pause", |
| verb_Pause_cb, control_data); |
| bonobo_ui_component_add_verb (control_data->uic, "Stop", |
| verb_Stop_cb, control_data); |
| |
| bonobo_ui_component_add_verb (control_data->uic, "Open", |
| verb_Open_cb, control_data); |
| |
| /* |
| * Count the new running object |
| */ |
| running_objects++; |
| g_print ("running objects: %d\n", running_objects); |
| |
| return BONOBO_OBJECT (bonobo_object); |
| } |
| |
| static void |
| init_gstmediaplay_factory (void) |
| { |
| factory = |
| bonobo_generic_factory_new |
| ("OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18", |
| bonobo_gstmediaplay_factory, NULL); |
| } |
| |
| static void |
| init_server_factory (int argc, char **argv) |
| { |
| CORBA_Environment ev; |
| CORBA_ORB orb; |
| |
| bindtextdomain (PACKAGE, GNOMELOCALEDIR); |
| textdomain (PACKAGE); |
| |
| CORBA_exception_init (&ev); |
| |
| gnome_init_with_popt_table ("bonobo-gstmediaplay", VERSION, |
| argc, argv, oaf_popt_options, 0, NULL); |
| orb = oaf_init (argc, argv); |
| |
| if (bonobo_init (orb, NULL, NULL) == FALSE) |
| g_error (_("Could not initialize Bonobo!")); |
| |
| CORBA_exception_free (&ev); |
| } |
| |
| int |
| main (int argc, char **argv) |
| { |
| /* g_thread_init (NULL); */ |
| /* |
| * Setup the factory. |
| */ |
| init_server_factory (argc, argv); |
| init_gstmediaplay_factory (); |
| |
| /* |
| * Start processing. |
| */ |
| bonobo_main (); |
| |
| return 0; |
| } |