/* GStreamer * Copyright (C) <1999> Erik Walthinsen * * 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 #include #include #include #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 [] = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; 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); /* * 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) { /* * Setup the factory. */ init_server_factory (argc, argv); init_gstmediaplay_factory (); /* * Start processing. */ bonobo_main (); return 0; }