This is a megapatch with the following changes:
[platform/upstream/gstreamer.git] / gstplay / gstmediaplay.c
1 /*
2  * Initial main.c file generated by Glade. Edit as required.
3  * Glade will not overwrite this file.
4  */
5
6 #include <config.h>
7
8 #include <sys/stat.h>
9 #include <unistd.h>
10
11 #include <gnome.h>
12 #include "gstmediaplay.h"
13 #include "callbacks.h"
14
15 static void gst_media_play_class_init           (GstMediaPlayClass *klass);
16 static void gst_media_play_init                 (GstMediaPlay *play);
17
18 static void gst_media_play_set_arg              (GtkObject *object,GtkArg *arg,guint id);
19 static void gst_media_play_get_arg              (GtkObject *object,GtkArg *arg,guint id);
20
21 static void gst_media_play_frame_displayed      (GstPlay *play, GstMediaPlay *mplay);
22 static void gst_media_play_state_changed        (GstPlay *play, GstPlayState state, GstMediaPlay *mplay);
23 static void gst_media_play_slider_changed       (GtkAdjustment   *adj, GstMediaPlay *mplay);
24
25 static void update_buttons                      (GstMediaPlay *mplay, GstPlayState state);
26 static void update_slider                       (GstMediaPlay *mplay, GtkAdjustment *adjustment, gfloat value);
27
28 /* signals and args */
29 enum {
30   LAST_SIGNAL
31 };
32
33 enum {
34   ARG_0,
35 };
36
37 static void
38 target_drag_data_received  (GtkWidget          *widget,
39                             GdkDragContext     *context,
40                             gint                x,
41                             gint                y,
42                             GtkSelectionData   *data,
43                             guint               info,
44                             guint               time,
45                             GstMediaPlay       *play)
46 {
47   if (strstr (data->data, "file:")) {
48     g_print ("Got: %s\n",&data->data[5]);
49     gdk_threads_leave ();
50     gst_media_play_start_uri (play, g_strchomp(&data->data[5]));
51     gdk_threads_enter ();
52   }
53 }
54
55 static GtkTargetEntry target_table[] = {
56   { "text/plain", 0, 0 }
57 };
58
59 static GtkObject *parent_class = NULL;
60 //static guint gst_media_play_signals[LAST_SIGNAL] = { 0 };
61
62 GtkType
63 gst_media_play_get_type(void)
64 {
65   static GtkType play_type = 0;
66
67   if (!play_type) {
68     static const GtkTypeInfo play_info = {
69       "GstMediaPlay",
70       sizeof(GstMediaPlay),
71       sizeof(GstMediaPlayClass),
72       (GtkClassInitFunc)gst_media_play_class_init,
73       (GtkObjectInitFunc)gst_media_play_init,
74       NULL,
75       NULL,
76       (GtkClassInitFunc)NULL,
77     };
78     play_type = gtk_type_unique(gtk_object_get_type(),&play_info);
79   }
80   return play_type;
81 }
82
83 static void
84 gst_media_play_class_init (GstMediaPlayClass *klass)
85 {
86   GtkObjectClass *object_class;
87
88   parent_class = gtk_type_class (gtk_object_get_type ());
89
90   object_class = (GtkObjectClass*)klass;
91
92   object_class->set_arg = gst_media_play_set_arg;
93   object_class->get_arg = gst_media_play_get_arg;
94 }
95
96 typedef struct {
97   GstMediaPlay *play;
98   GModule *symbols;
99 } connect_struct;
100
101 /* we need more control here so... */
102 static void
103 gst_media_play_connect_func (const gchar *handler_name,
104                              GtkObject *object,
105                              const gchar *signal_name,
106                              const gchar *signal_data,
107                              GtkObject *connect_object,
108                              gboolean after,
109                              gpointer user_data)
110 {
111   GtkSignalFunc func;
112   connect_struct *data = (connect_struct *)user_data;
113
114   if (!g_module_symbol (data->symbols, handler_name, (gpointer *)&func))
115     g_warning("gsteditorproperty: could not find signal handler '%s'.", handler_name);
116   else {
117     if (after)
118       gtk_signal_connect_after (object, signal_name, func, (gpointer) data->play);
119     else
120       gtk_signal_connect (object, signal_name, func, (gpointer) data->play);
121   }
122 }
123
124
125 static void
126 gst_media_play_init(GstMediaPlay *mplay)
127 {
128   GModule *symbols;
129   connect_struct data;
130   struct stat statbuf;
131
132
133   /* load the interface */
134   if (stat(DATADIR"gstmediaplay.glade", &statbuf) == 0) {
135     mplay->xml = glade_xml_new (DATADIR"gstmediaplay.glade", "gstplay");
136   }
137   else {
138     mplay->xml = glade_xml_new ("gstmediaplay.glade", "gstplay");
139   }
140   g_assert (mplay->xml != NULL);
141
142   mplay->slider = glade_xml_get_widget(mplay->xml, "slider");
143   g_assert (mplay->slider != NULL);
144   {
145     GtkArg arg;
146     GtkRange *range;
147
148     arg.name = "adjustment";
149     gtk_object_getv (GTK_OBJECT (mplay->slider), 1, &arg);
150     range = GTK_RANGE (GTK_VALUE_POINTER (arg));
151     mplay->adjustment = gtk_range_get_adjustment (range);
152
153     gtk_signal_connect (GTK_OBJECT (mplay->adjustment), "value_changed",
154                     GTK_SIGNAL_FUNC (gst_media_play_slider_changed), mplay);
155   }
156
157   mplay->play_button = glade_xml_get_widget (mplay->xml, "toggle_play");
158   g_assert (mplay->play_button != NULL);
159   mplay->pause_button = glade_xml_get_widget (mplay->xml, "toggle_pause");
160   g_assert (mplay->pause_button != NULL);
161   mplay->stop_button = glade_xml_get_widget (mplay->xml, "toggle_stop");
162   g_assert (mplay->stop_button != NULL);
163
164   mplay->window = glade_xml_get_widget (mplay->xml, "gstplay");
165   g_assert (mplay->window != NULL);
166
167   gtk_drag_dest_set (mplay->window,
168                      GTK_DEST_DEFAULT_ALL,
169                      target_table, 1,
170                      GDK_ACTION_COPY);
171   gtk_signal_connect (GTK_OBJECT (mplay->window), "drag_data_received",
172                       GTK_SIGNAL_FUNC (target_drag_data_received),
173                       mplay);
174
175   mplay->play = gst_play_new();
176
177   gtk_signal_connect (GTK_OBJECT (mplay->play), "frame_displayed",
178                       GTK_SIGNAL_FUNC (gst_media_play_frame_displayed),
179                       mplay);
180
181   gtk_signal_connect (GTK_OBJECT (mplay->play), "audio_played",
182                       GTK_SIGNAL_FUNC (gst_media_play_frame_displayed),
183                       mplay);
184
185   gtk_signal_connect (GTK_OBJECT (mplay->play), "playing_state_changed",
186                       GTK_SIGNAL_FUNC (gst_media_play_state_changed),
187                       mplay);
188
189   gnome_dock_set_client_area (GNOME_DOCK (glade_xml_get_widget(mplay->xml, "dock1")),
190                   GTK_WIDGET (mplay->play));
191
192   gtk_widget_show (GTK_WIDGET (mplay->play));
193
194   mplay->status = (GstStatusArea *)glade_xml_get_widget (mplay->xml, "status_area");
195   gst_status_area_set_state (mplay->status, GST_STATUS_AREA_STATE_INIT);
196   gst_status_area_set_playtime (mplay->status, "00:00 / 00:00");
197
198   symbols = g_module_open (NULL, 0);
199
200   data.play = mplay;
201   data.symbols = symbols;
202
203   glade_xml_signal_autoconnect_full (mplay->xml, gst_media_play_connect_func, &data);
204
205   mplay->last_time = 0;
206 }
207
208 GstMediaPlay *
209 gst_media_play_new ()
210 {
211   return GST_MEDIA_PLAY (gtk_type_new (GST_TYPE_MEDIA_PLAY));
212 }
213
214 static void
215 gst_media_play_update_status_area (GstMediaPlay *play,
216                                    gulong current_time,
217                                    gulong total_time)
218 {
219   gchar time[14];
220
221   sprintf(time, "%02lu:%02lu / %02lu:%02lu",
222          current_time/60, current_time%60,
223          total_time/60, total_time%60);
224
225   gst_status_area_set_playtime (play->status, time);
226 }
227
228 void
229 gst_media_play_start_uri (GstMediaPlay *play,
230                           const guchar *uri)
231 {
232   GstPlayReturn ret;
233
234   g_return_if_fail (play != NULL);
235   g_return_if_fail (GST_IS_MEDIA_PLAY (play));
236
237   if (uri != NULL) {
238     ret = gst_play_set_uri (play->play, uri);
239
240     if (!gst_play_media_can_seek (play->play)) {
241       gtk_widget_set_sensitive (play->slider, FALSE);
242     }
243
244     gtk_window_set_title (GTK_WINDOW (play->window),
245                           g_strconcat ( "Gstplay - ", uri, NULL));
246
247     gst_play_play (play->play);
248   }
249 }
250
251 typedef struct {
252   GtkWidget *selection;
253   GstMediaPlay *play;
254 } file_select;
255
256 static void
257 on_load_file_selected (GtkWidget *button,
258                        file_select *data)
259 {
260   GtkWidget *selector = data->selection;
261   GstMediaPlay *play = data->play;
262
263   gchar *file_name = gtk_file_selection_get_filename (GTK_FILE_SELECTION(selector));
264   gdk_threads_leave();
265   gst_media_play_start_uri (play, file_name);
266   gdk_threads_enter();
267
268   g_free (data);
269 }
270
271 void
272 on_open2_activate (GtkWidget *widget,
273                    GstMediaPlay *play)
274 {
275   GtkWidget *file_selector;
276   file_select *file_data = g_new0 (file_select, 1);
277
278   file_selector = gtk_file_selection_new("Please select a file to load.");
279
280   file_data->selection = file_selector;
281   file_data->play = play;
282
283   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
284                                       "clicked", GTK_SIGNAL_FUNC (on_load_file_selected),
285                                       file_data);
286
287   /* Ensure that the dialog box is destroyed when the user clicks a button. */
288   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
289                                       "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
290                                       (gpointer) file_selector);
291   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->cancel_button),
292                                       "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
293                                       (gpointer) file_selector);
294
295   /* Display that dialog */
296   gtk_widget_show (file_selector);
297 }
298
299
300 static void
301 gst_media_play_set_arg (GtkObject *object,
302                         GtkArg *arg,
303                         guint id)
304 {
305   GstMediaPlay *play;
306   play = GST_MEDIA_PLAY (object);
307
308   switch (id) {
309     default:
310       g_warning("GstMediaPlay: unknown arg!");
311       break;
312   }
313 }
314
315 static void
316 gst_media_play_get_arg (GtkObject *object,
317                         GtkArg *arg,
318                         guint id)
319 {
320   GstMediaPlay *play;
321
322   play = GST_MEDIA_PLAY (object);
323
324   switch (id) {
325     default:
326       arg->type = GTK_TYPE_INVALID;
327       break;
328   }
329 }
330
331 static void
332 gst_media_play_state_changed (GstPlay *play,
333                               GstPlayState state,
334                               GstMediaPlay *mplay)
335 {
336   GstStatusAreaState area_state;
337
338   g_return_if_fail (GST_IS_PLAY (play));
339   g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
340
341
342   gdk_threads_enter ();
343   update_buttons (mplay, state);
344
345   switch (state) {
346     case GST_PLAY_STOPPED:
347       area_state =  GST_STATUS_AREA_STATE_STOPPED;
348       break;
349     case GST_PLAY_PLAYING:
350       area_state =  GST_STATUS_AREA_STATE_PLAYING;
351       break;
352     case GST_PLAY_PAUSED:
353       area_state =  GST_STATUS_AREA_STATE_PAUSED;
354       break;
355     default:
356       area_state =  GST_STATUS_AREA_STATE_INIT;
357   }
358   gst_status_area_set_state (mplay->status, area_state);
359   gdk_threads_leave ();
360 }
361
362 void
363 on_gst_media_play_destroy (GtkWidget *widget,
364                            GstMediaPlay *mplay)
365 {
366   gst_main_quit ();
367 }
368
369 void
370 on_exit_menu_activate (GtkWidget *widget,
371                        GstMediaPlay *mplay)
372 {
373   gdk_threads_leave ();
374   gst_play_stop (mplay->play);
375   gdk_threads_enter ();
376   gst_main_quit ();
377 }
378
379 gint
380 on_gst_media_play_delete_event (GtkWidget *widget,
381                                 GdkEvent *event,
382                                 GstMediaPlay *mplay)
383 {
384   gdk_threads_leave ();
385   gst_play_stop (mplay->play);
386   gdk_threads_enter ();
387   return FALSE;
388 }
389
390 void
391 on_extended1_activate (GtkCheckMenuItem *item,
392                        GstMediaPlay *mplay)
393 {
394   gdk_threads_leave ();
395   gst_status_area_show_extended (mplay->status, item->active);
396   gdk_threads_enter ();
397 }
398
399 static void
400 gst_media_play_frame_displayed (GstPlay *play,
401                                 GstMediaPlay *mplay)
402 {
403   gulong current_time;
404   gulong total_time;
405   gulong size, current_offset;
406
407   g_return_if_fail (GST_IS_PLAY (play));
408   g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
409
410   current_time   = gst_play_get_media_current_time (play);
411   total_time     = gst_play_get_media_total_time (play);
412   size           = gst_play_get_media_size (play);
413   current_offset = gst_play_get_media_offset (play);
414
415   if (current_time != mplay->last_time) {
416     gdk_threads_enter ();
417     gst_media_play_update_status_area (mplay, current_time, total_time);
418     update_slider (mplay, mplay->adjustment, current_offset*100.0/size);
419     mplay->last_time = current_time;
420     gdk_threads_leave ();
421   }
422 }
423
424 static void
425 gst_media_play_slider_changed (GtkAdjustment *adj,
426                                GstMediaPlay *mplay)
427 {
428   gulong size;
429
430   g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
431
432   size   = gst_play_get_media_size (mplay->play);
433
434   gst_play_media_seek(mplay->play, (int)(adj->value*size/100.0));
435 }
436
437 void
438 on_toggle_play_toggled (GtkToggleButton *togglebutton,
439                         GstMediaPlay    *play)
440 {
441   gdk_threads_leave ();
442   gst_play_play (play->play);
443   gdk_threads_enter ();
444   update_buttons (play, GST_PLAY_STATE(play->play));
445 }
446
447 void
448 on_toggle_pause_toggled (GtkToggleButton *togglebutton,
449                          GstMediaPlay    *play)
450 {
451   gdk_threads_leave ();
452   gst_play_pause (play->play);
453   gdk_threads_enter ();
454   update_buttons (play, GST_PLAY_STATE(play->play));
455 }
456
457 void
458 on_toggle_stop_toggled (GtkToggleButton *togglebutton,
459                         GstMediaPlay    *play)
460 {
461   gdk_threads_leave ();
462   gst_play_stop (play->play);
463   gdk_threads_enter ();
464   update_buttons (play, GST_PLAY_STATE(play->play));
465 }
466
467 static void
468 update_buttons (GstMediaPlay *mplay,
469                 GstPlayState state)
470 {
471   gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->play_button),
472                          GTK_SIGNAL_FUNC (on_toggle_play_toggled),
473                          mplay);
474   gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->pause_button),
475                          GTK_SIGNAL_FUNC (on_toggle_pause_toggled),
476                          mplay);
477   gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->stop_button),
478                          GTK_SIGNAL_FUNC (on_toggle_stop_toggled),
479                          mplay);
480
481   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->play_button), FALSE);
482   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->pause_button), FALSE);
483   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->stop_button), FALSE);
484
485   if (state == GST_PLAY_PLAYING) {
486     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->play_button), TRUE);
487   }
488   else if (state == GST_PLAY_PAUSED) {
489     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->pause_button), TRUE);
490   }
491   else if (state == GST_PLAY_STOPPED) {
492     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->stop_button), TRUE);
493   }
494
495   gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->play_button),
496                          GTK_SIGNAL_FUNC (on_toggle_play_toggled),
497                          mplay);
498   gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->pause_button),
499                          GTK_SIGNAL_FUNC (on_toggle_pause_toggled),
500                          mplay);
501   gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->stop_button),
502                          GTK_SIGNAL_FUNC (on_toggle_stop_toggled),
503                          mplay);
504 }
505
506 static void
507 update_slider (GstMediaPlay *mplay,
508                GtkAdjustment *adjustment,
509                gfloat value)
510 {
511   gtk_signal_handler_block_by_func (GTK_OBJECT (adjustment),
512                          GTK_SIGNAL_FUNC (gst_media_play_slider_changed),
513                          mplay);
514   gtk_adjustment_set_value (adjustment, value);
515   gtk_signal_handler_unblock_by_func (GTK_OBJECT (adjustment),
516                          GTK_SIGNAL_FUNC (gst_media_play_slider_changed),
517                          mplay);
518 }
519