1 /*
2 * gtv - a Gtk+ based SMPEG player
3 * (c) Michael Vance, 1999
4 * briareos@lokigames.com
5 *
6 * TODO
7 * - SMPEG returns an incorrect current_frame after a
8 * call to SMPEG_renderFinal().
9 * - SMPEG loops audio incorrectly when audio stream is
10 * shorter than a video stream, etc.
11 */
12
13 #include "gtv.h"
14 #include "SDL_syswm.h"
15
16 #define TIMER_TIMEOUT 100
17
18 static GtkWidget* create_gtv_window( void );
19 static void gtv_connect( gpointer, gchar*, gchar*, GtkSignalFunc );
20 static void gtv_set_frame( gpointer, int );
21 static void gtv_set_fps( gpointer, float );
22 static void gtv_set_trackbar( gpointer, int );
23 static void gtv_set_sensitive( gpointer, gchar*, gboolean );
24 static void gtv_clear_screen( gpointer );
25 static void gtv_fix_toggle_state( gpointer );
26
27 static void gtv_double( GtkWidget*, gpointer );
28 static void gtv_loop( GtkWidget*, gpointer );
29 static void gtv_audio( GtkWidget*, gpointer );
30 static void gtv_filter( GtkWidget*, gpointer );
31
32 static void gtv_open( GtkWidget*, gpointer );
33 static void gtv_open_file( gchar*, gpointer );
34 static void gtv_close( GtkWidget*, gpointer );
35 static void gtv_info( GtkWidget*, gpointer );
36 static void gtv_quit( GtkWidget*, gpointer );
37 static void gtv_about( GtkWidget*, gpointer );
38
39 static void gtv_play( GtkWidget*, gpointer );
40 static void gtv_pause( GtkWidget*, gpointer );
41 static void gtv_stop( GtkWidget*, gpointer );
42 static void gtv_step( GtkWidget*, gpointer );
43 static void gtv_to_end( GtkWidget*, gpointer );
44 static void gtv_seek( GtkAdjustment*, gpointer );
45 static void gtv_drag_data_received(GtkWidget * widget,
46 GdkDragContext * context,
47 gint x, gint y,
48 GtkSelectionData * selection_data,
49 guint info, guint time);
50
51
52 static int gtv_trackbar_dragging;
53 static gchar * gtv_default_directory = 0;
54
gtv_fix_toggle_state(gpointer raw)55 static void gtv_fix_toggle_state( gpointer raw )
56 {
57 SMPEG* mpeg = NULL;
58
59 assert( raw );
60
61 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
62
63 /* If no mpeg is loaded, pop all the buttons. */
64 if( !mpeg ) {
65 GtkWidget* twotimes = NULL;
66 GtkWidget* loop = NULL;
67 GtkWidget* audio = NULL;
68 GtkWidget* filter = NULL;
69
70 twotimes = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "twotimes" ) );
71 loop = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "loop" ) );
72 audio = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "audio" ) );
73 filter = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "filter" ) );
74
75 #if 1 /* Sam 5/31/2000 - Default to doubled video and audio on */
76 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( twotimes ), FALSE );
77 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( loop ), FALSE );
78 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( audio ), TRUE );
79 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( filter ), FALSE );
80 #else
81 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( twotimes ), FALSE );
82 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( loop ), FALSE );
83 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( audio ), FALSE );
84 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( filter ), FALSE );
85 #endif
86 }
87
88 }
89
gtv_set_sensitive(gpointer raw,gchar * name,gboolean sensitive)90 static void gtv_set_sensitive( gpointer raw, gchar* name, gboolean sensitive )
91 {
92 GtkWidget* item = NULL;
93
94 assert( raw );
95 assert( name );
96
97 item = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), name ) );
98 assert( item );
99 gtk_widget_set_sensitive( item, sensitive );
100 }
101
gtv_set_buttons_sensitive(gpointer raw,gboolean sensitive)102 static void gtv_set_buttons_sensitive( gpointer raw, gboolean sensitive )
103 {
104 SMPEG_Info* info = NULL;
105
106 /* HACK If no MPEG is loaded, info has been memset()'ed to 0. */
107 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
108
109 gtv_set_sensitive( raw, "play", sensitive );
110 gtv_set_sensitive( raw, "pause", sensitive );
111 gtv_set_sensitive( raw, "stop", sensitive );
112 gtv_set_sensitive( raw, "step", sensitive && info->has_video );
113 gtv_set_sensitive( raw, "to_end", sensitive && info->has_video );
114 gtv_set_sensitive( raw, "loop", sensitive );
115 gtv_set_sensitive( raw, "close", sensitive );
116 gtv_set_sensitive( raw, "file_info", sensitive );
117
118 gtv_set_sensitive( raw, "twotimes", sensitive && info->has_video );
119 gtv_set_sensitive( raw, "audio", sensitive && info->has_audio && info->has_video);
120 gtv_set_sensitive( raw, "filter", sensitive && info->has_video );
121
122 gtv_fix_toggle_state( raw );
123 }
124
gtv_dialog_cleanup(gpointer raw)125 static void gtv_dialog_cleanup( gpointer raw )
126 {
127 GtkWidget* dialog = NULL;
128
129 dialog = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "dialog" ) );
130 gtk_grab_remove( dialog );
131 gtk_widget_destroy( dialog );
132 gtk_object_set_data( GTK_OBJECT( raw ), "dialog", NULL );
133 }
134
gtv_dialog_cancel(GtkWidget * item,gpointer raw)135 static void gtv_dialog_cancel( GtkWidget* item, gpointer raw )
136 {
137 gtv_dialog_cleanup( raw );
138 }
139
gtv_open_ok(GtkWidget * item,gpointer raw)140 static void gtv_open_ok( GtkWidget* item, gpointer raw )
141 {
142 GtkWidget* file_sel = NULL;
143 gchar* filename = NULL;
144
145 /* HACK HACK HACK */
146 file_sel = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "dialog" ) );
147 filename = gtk_file_selection_get_filename( GTK_FILE_SELECTION( file_sel ) );
148
149 if( filename ) {
150 gtv_open_file( filename, raw );
151 if( strrchr( filename, '/') )
152 {
153 if( gtv_default_directory ) free( gtv_default_directory );
154 gtv_default_directory = (gchar *) malloc( (strlen(filename) + 1) * sizeof(gchar) );
155 strcpy( gtv_default_directory, filename);
156 *(strrchr( gtv_default_directory, '/' ) + 1) = 0;
157 }
158 }
159
160 gtv_dialog_cleanup( raw );
161 }
162
gtv_open(GtkWidget * item,gpointer raw)163 static void gtv_open( GtkWidget* item, gpointer raw )
164 {
165 GtkWidget* file_sel = NULL;
166
167 file_sel = gtk_file_selection_new( "Select an MPEG" );
168 gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->ok_button ), "clicked",
169 GTK_SIGNAL_FUNC( gtv_open_ok ), raw );
170 gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->cancel_button ), "clicked",
171 GTK_SIGNAL_FUNC( gtv_dialog_cancel ), raw );
172 if( gtv_default_directory )
173 gtk_file_selection_complete( GTK_FILE_SELECTION( file_sel ), gtv_default_directory );
174 gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION( file_sel ) );
175
176 /* HACK HACK HACK */
177 gtk_object_set_data( GTK_OBJECT( raw ), "dialog", file_sel );
178
179 gtk_grab_add( file_sel );
180 gtk_widget_show( file_sel );
181 }
182
gtv_center_window(SDL_Surface * screen)183 static void gtv_center_window(SDL_Surface *screen)
184 {
185 SDL_SysWMinfo info;
186
187 SDL_VERSION(&info.version);
188 if ( SDL_GetWMInfo(&info) > 0 ) {
189 int x, y;
190 int w, h;
191 #ifdef unix
192 if ( info.subsystem == SDL_SYSWM_X11 ) {
193 info.info.x11.lock_func();
194 w = DisplayWidth(info.info.x11.display,
195 DefaultScreen(info.info.x11.display));
196 h = DisplayHeight(info.info.x11.display,
197 DefaultScreen(info.info.x11.display));
198 x = (w - screen->w)/2;
199 y = (h - screen->h)/2;
200 XMoveWindow(info.info.x11.display, info.info.x11.wmwindow, x, y);
201 info.info.x11.unlock_func();
202 }
203 #else
204 #ifdef WIN32
205 /* FIXME: implement centering code for Windows */
206 #else
207 #warning Need to implement these functions for other systems
208 #endif // WIN32
209 #endif // unix
210 }
211 }
212
gtv_open_file(gchar * name,gpointer raw)213 static void gtv_open_file( gchar* name, gpointer raw )
214 {
215 SMPEG_Info* info = NULL;
216 SMPEG* mpeg = NULL;
217 gchar buffer[FILENAME_BUFFER_SIZE];
218
219 assert( name );
220 assert( raw );
221
222 gtv_close( NULL, raw );
223
224 if( SDL_Init( SDL_INIT_AUDIO | SDL_INIT_VIDEO ) < 0 ) {
225 fprintf( stderr, "gtv: couldn't initialize SDL: %s\n", SDL_GetError( ) );
226 exit( 1 );
227 }
228
229 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
230 assert( info );
231
232 mpeg = SMPEG_new( name, info, 1 );
233
234 if( SMPEG_error( mpeg ) ) {
235 fprintf( stderr, "gtv: %s\n", SMPEG_error( mpeg ) );
236 SMPEG_delete( mpeg );
237 gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", NULL );
238 return;
239 }
240
241 gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", mpeg );
242 strncpy( (char*) gtk_object_get_data( GTK_OBJECT( raw ), "filename_buffer" ),
243 name,
244 FILENAME_BUFFER_SIZE );
245 gtv_set_frame( raw, 0 );
246 gtv_set_fps( raw, 0.0 );
247 g_snprintf( buffer, FILENAME_BUFFER_SIZE, "gtv - %s", name );
248 gtk_window_set_title( GTK_WINDOW( raw ), buffer );
249
250 if( info->has_video ) {
251 SDL_Surface* sdl_screen = NULL;
252 const SDL_VideoInfo *video_info;
253 int video_bpp;
254
255 /* Get the "native" video mode */
256 video_info = SDL_GetVideoInfo();
257 switch (video_info->vfmt->BitsPerPixel) {
258 case 16:
259 case 32:
260 video_bpp = video_info->vfmt->BitsPerPixel;
261 break;
262 default:
263 video_bpp = 16;
264 break;
265 }
266 #ifdef linux
267 putenv("SDL_VIDEO_CENTERED=1");
268 #endif
269 sdl_screen = SDL_SetVideoMode( info->width , info->height , video_bpp, SDL_ASYNCBLIT);
270 SDL_WM_SetCaption(name, "gtv movie");
271 gtv_center_window(sdl_screen);
272 SMPEG_setdisplay( mpeg, sdl_screen, NULL, NULL );
273 gtk_object_set_data( GTK_OBJECT( raw ), "sdl_screen", sdl_screen );
274 gtv_double( NULL, raw );
275 }
276
277 gtv_loop( NULL, raw );
278 gtv_audio( NULL, raw );
279 gtv_filter( NULL, raw );
280 gtv_set_buttons_sensitive( raw, TRUE );
281 }
282
gtv_close(GtkWidget * item,gpointer raw)283 static void gtv_close( GtkWidget* item, gpointer raw )
284 {
285 SMPEG* mpeg = NULL;
286 SMPEG_Info* info = NULL;
287
288 assert( raw != NULL );
289
290 gtv_stop( NULL, raw );
291 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
292
293 if( mpeg ) {
294 SDL_Surface* sdl_screen = NULL;
295
296 SMPEG_delete( mpeg );
297 gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", NULL );
298 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
299 memset( info, 0, sizeof( SMPEG_Info ) );
300
301 sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );
302 SDL_FreeSurface( sdl_screen );
303 gtk_object_set_data( GTK_OBJECT( raw ), "sdl_screen", NULL );
304
305 SDL_Quit( );
306 }
307
308 /* Reset title. */
309 gtk_window_set_title( GTK_WINDOW( raw ), "gtv" );
310 gtv_set_frame( raw, 0 );
311 gtv_set_fps( raw, 0.0 );
312 gtv_set_buttons_sensitive( raw, FALSE );
313 }
314
create_file_info_dialog(void)315 static GtkWidget* create_file_info_dialog( void )
316 {
317 GtkWidget *file_info_dialog;
318 GtkWidget *dialog_vbox1;
319 GtkWidget *vbox2;
320 GtkWidget *label5;
321 GtkWidget *scrolledwindow1;
322 GtkWidget *viewport1;
323 GtkWidget *text;
324 GtkWidget *dialog_action_area1;
325 GtkWidget *ok;
326
327 file_info_dialog = gtk_dialog_new ();
328 gtk_object_set_data (GTK_OBJECT (file_info_dialog), "file_info_dialog", file_info_dialog);
329 gtk_window_set_title (GTK_WINDOW (file_info_dialog), "File Info");
330 gtk_window_set_default_size (GTK_WINDOW (file_info_dialog), 256, 192);
331
332 dialog_vbox1 = GTK_DIALOG (file_info_dialog)->vbox;
333 gtk_object_set_data (GTK_OBJECT (file_info_dialog), "dialog_vbox1", dialog_vbox1);
334 gtk_widget_show (dialog_vbox1);
335
336 vbox2 = gtk_vbox_new (FALSE, 5);
337 gtk_widget_ref (vbox2);
338 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "vbox2", vbox2,
339 (GtkDestroyNotify) gtk_widget_unref);
340 gtk_widget_show (vbox2);
341 gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox2, TRUE, TRUE, 0);
342 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
343
344 label5 = gtk_label_new ("File info:");
345 gtk_widget_ref (label5);
346 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "label5", label5,
347 (GtkDestroyNotify) gtk_widget_unref);
348 gtk_widget_show (label5);
349 gtk_box_pack_start (GTK_BOX (vbox2), label5, FALSE, FALSE, 0);
350 gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
351
352 scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
353 gtk_widget_ref (scrolledwindow1);
354 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "scrolledwindow1", scrolledwindow1,
355 (GtkDestroyNotify) gtk_widget_unref);
356 gtk_widget_show (scrolledwindow1);
357 gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow1, TRUE, TRUE, 0);
358 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
359
360 viewport1 = gtk_viewport_new (NULL, NULL);
361 gtk_widget_ref (viewport1);
362 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "viewport1", viewport1,
363 (GtkDestroyNotify) gtk_widget_unref);
364 gtk_widget_show (viewport1);
365 gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
366
367 text = gtk_text_new (NULL, NULL);
368 gtk_widget_ref (text);
369 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "text", text,
370 (GtkDestroyNotify) gtk_widget_unref);
371 gtk_widget_show (text);
372 gtk_container_add (GTK_CONTAINER (viewport1), text);
373
374 dialog_action_area1 = GTK_DIALOG (file_info_dialog)->action_area;
375 gtk_object_set_data (GTK_OBJECT (file_info_dialog), "dialog_action_area1", dialog_action_area1);
376 gtk_widget_show (dialog_action_area1);
377 gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area1), 10);
378
379 ok = gtk_button_new_with_label (" OK ");
380 gtk_widget_ref (ok);
381 gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "ok", ok,
382 (GtkDestroyNotify) gtk_widget_unref);
383 gtk_widget_show (ok);
384 gtk_box_pack_start (GTK_BOX (dialog_action_area1), ok, FALSE, FALSE, 0);
385
386 return file_info_dialog;
387 }
388
gtv_info(GtkWidget * item,gpointer raw)389 static void gtv_info( GtkWidget* item, gpointer raw )
390 {
391 GtkWidget* dialog = NULL;
392 GtkWidget* ok = NULL;
393 gchar buffer[1024];
394 gint ignored = 0;
395 GtkWidget* text = NULL;
396 SMPEG_Info* info = NULL;
397 int hh,mm,ss;
398
399 dialog = create_file_info_dialog( );
400 ok = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "ok" ) );
401 gtk_signal_connect( GTK_OBJECT( ok ), "clicked",
402 GTK_SIGNAL_FUNC( gtv_dialog_cancel ), raw );
403 /* HACK HACK HACK */
404 gtk_object_set_data( GTK_OBJECT( raw ), "dialog", dialog );
405
406 /* Actually stuff some data in there. */
407 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
408 hh = info->total_time / 3600;
409 mm = (info->total_time - hh * 3600)/60;
410 ss = ((int)info->total_time % 60);
411 g_snprintf( buffer, 1024, "Filename: %s\nStream: %s\nVideo: %dx%d resolution\nAudio: %s\nSize: %d\nTime %d:%02d:%02d\n",
412 (gchar*) gtk_object_get_data( GTK_OBJECT( raw ), "filename_buffer" ),
413 ( info->has_audio && info->has_video ) ? "system" :
414 ( info->has_video ? "video" :
415 ( info->has_audio ? "audio" : "not MPEG" ) ),
416 info->width, info->height,
417 ( info->has_audio ? info->audio_string : "none" ),
418 info->total_size , hh,mm,ss);
419 text = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "text" ) );
420 gtk_editable_insert_text( GTK_EDITABLE( text ), buffer, strlen( buffer ), &ignored );
421
422 gtk_grab_add( dialog );
423 gtk_widget_show( dialog );
424 }
425
create_about_dialog(void)426 static GtkWidget* create_about_dialog( void )
427 {
428 GtkWidget *about_dialog;
429 GtkWidget *dialog_vbox2;
430 GtkWidget *scrolledwindow2;
431 GtkWidget *viewport2;
432 GtkWidget *text;
433 GtkWidget *dialog_action_area2;
434 GtkWidget *ok;
435
436 about_dialog = gtk_dialog_new ();
437 gtk_object_set_data (GTK_OBJECT (about_dialog), "about_dialog", about_dialog);
438 gtk_window_set_title (GTK_WINDOW (about_dialog), "About gtv");
439 gtk_window_set_default_size (GTK_WINDOW (about_dialog), 384, 256);
440 gtk_window_set_policy (GTK_WINDOW (about_dialog), TRUE, TRUE, FALSE);
441
442 dialog_vbox2 = GTK_DIALOG (about_dialog)->vbox;
443 gtk_object_set_data (GTK_OBJECT (about_dialog), "dialog_vbox2", dialog_vbox2);
444 gtk_widget_show (dialog_vbox2);
445
446 scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
447 gtk_widget_ref (scrolledwindow2);
448 gtk_object_set_data_full (GTK_OBJECT (about_dialog), "scrolledwindow2", scrolledwindow2,
449 (GtkDestroyNotify) gtk_widget_unref);
450 gtk_widget_show (scrolledwindow2);
451 gtk_box_pack_start (GTK_BOX (dialog_vbox2), scrolledwindow2, TRUE, TRUE, 0);
452 gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow2), 5);
453 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
454
455 viewport2 = gtk_viewport_new (NULL, NULL);
456 gtk_widget_ref (viewport2);
457 gtk_object_set_data_full (GTK_OBJECT (about_dialog), "viewport2", viewport2,
458 (GtkDestroyNotify) gtk_widget_unref);
459 gtk_widget_show (viewport2);
460 gtk_container_add (GTK_CONTAINER (scrolledwindow2), viewport2);
461
462 text = gtk_text_new (NULL, NULL);
463 gtk_widget_ref (text);
464 gtk_object_set_data_full (GTK_OBJECT (about_dialog), "text", text,
465 (GtkDestroyNotify) gtk_widget_unref);
466 gtk_widget_show (text);
467 gtk_container_add (GTK_CONTAINER (viewport2), text);
468
469 dialog_action_area2 = GTK_DIALOG (about_dialog)->action_area;
470 gtk_object_set_data (GTK_OBJECT (about_dialog), "dialog_action_area2", dialog_action_area2);
471 gtk_widget_show (dialog_action_area2);
472 gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area2), 10);
473
474 ok = gtk_button_new_with_label (" OK ");
475 gtk_widget_ref (ok);
476 gtk_object_set_data_full (GTK_OBJECT (about_dialog), "ok", ok,
477 (GtkDestroyNotify) gtk_widget_unref);
478 gtk_widget_show (ok);
479 gtk_box_pack_start (GTK_BOX (dialog_action_area2), ok, FALSE, FALSE, 0);
480
481 return about_dialog;
482 }
483
gtv_about(GtkWidget * item,gpointer raw)484 static void gtv_about( GtkWidget* item, gpointer raw )
485 {
486 static const char* msg = "gtv - Gtk+ MPEG Player\n" \
487 "(c) Michael Vance, 1999\n" \
488 " briareos@lokigames.com\n" \
489 "\n" \
490 "Built using:\n" \
491 "SMPEG - http://www.lokigames.com/development\n" \
492 "Gtk+ - http://www.gtk.org\n" \
493 "Glade - http://glade.pn.org\n" \
494 "\n" \
495 "Distributed under the GPL.\n";
496 GtkWidget* dialog = NULL;
497 GtkWidget* ok = NULL;
498 GtkWidget* text = NULL;
499 gint ignored = 0;
500
501 dialog = create_about_dialog( );
502 ok = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "ok" ) );
503 gtk_signal_connect( GTK_OBJECT( ok ), "clicked",
504 GTK_SIGNAL_FUNC( gtv_dialog_cancel ), raw );
505 text = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "text" ) );
506 gtk_editable_insert_text( GTK_EDITABLE( text ), msg, strlen( msg ), &ignored );
507
508 /* HACK HACK HACK */
509 gtk_object_set_data( GTK_OBJECT( raw ), "dialog", dialog );
510
511 gtk_grab_add( dialog );
512 gtk_widget_show( dialog );
513 }
514
gtv_rewind(gpointer raw)515 static void gtv_rewind( gpointer raw )
516 {
517 SMPEG* mpeg = NULL;
518
519 assert( raw );
520
521 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
522
523 if( mpeg ) {
524 SMPEG_Info* info = NULL;
525
526 SMPEG_rewind( mpeg );
527 gtv_clear_screen( raw );
528 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
529 SMPEG_getinfo( mpeg, info );
530 gtv_set_frame( raw, info->current_frame );
531 }
532
533 }
534
gtv_double(GtkWidget * item,gpointer raw)535 static void gtv_double( GtkWidget* item, gpointer raw )
536 {
537 SMPEG* mpeg = NULL;
538 SDL_Surface* sdl_screen = NULL;
539 SMPEG_Info* info = NULL;
540 int stopped=0;
541 int width,height;
542
543 assert( raw );
544
545 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
546 sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );
547
548 if( mpeg && sdl_screen ) {
549 GtkWidget* twotimes = NULL;
550 gboolean active = FALSE;
551
552 twotimes = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "twotimes" ) );
553 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( twotimes ) );
554
555 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
556 assert( info );
557 if (SMPEG_status(mpeg)==SMPEG_PLAYING) {
558 SMPEG_pause(mpeg);
559 stopped=1;
560 }
561 if( active ) {
562 width = info->width * 2;
563 height = info->height * 2;
564 } else {
565 width = info->width;
566 height = info->height;
567 }
568 sdl_screen = SDL_SetVideoMode(width, height,
569 sdl_screen->format->BitsPerPixel,sdl_screen->flags);
570 gtv_center_window(sdl_screen);
571 SMPEG_setdisplay( mpeg, sdl_screen, NULL, NULL );
572
573 gtk_object_set_data( GTK_OBJECT( raw ), "sdl_screen", sdl_screen );
574 SMPEG_scaleXY( mpeg, sdl_screen->w, sdl_screen->h );
575 gtv_center_window(sdl_screen);
576 if (stopped) SMPEG_pause(mpeg);
577 }
578
579 }
580
gtv_loop(GtkWidget * item,gpointer raw)581 static void gtv_loop( GtkWidget* item, gpointer raw )
582 {
583 SMPEG* mpeg = NULL;
584
585 assert( raw );
586
587 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
588
589 if( mpeg ) {
590 GtkWidget* loop = NULL;
591 gboolean active = FALSE;
592
593 loop = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "loop" ) );
594 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( loop ) );
595 SMPEG_loop( mpeg, active );
596 }
597
598 }
599
gtv_audio(GtkWidget * item,gpointer raw)600 static void gtv_audio( GtkWidget* item, gpointer raw )
601 {
602 SMPEG* mpeg = NULL;
603
604 assert( raw );
605
606 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
607
608 if( mpeg ) {
609 GtkWidget* audio = NULL;
610 gboolean active = FALSE;
611 SMPEG_Info* info = NULL;
612
613 audio = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "audio" ) );
614 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
615 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( audio ) );
616 SMPEG_enableaudio( mpeg, active && info->has_audio );
617 }
618
619 }
620
gtv_filter(GtkWidget * item,gpointer raw)621 static void gtv_filter( GtkWidget* item, gpointer raw )
622 {
623 SMPEG* mpeg = NULL;
624 SMPEG_Info* info = NULL;
625
626 assert( raw );
627
628 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
629 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
630
631 if( mpeg && info->has_video ) {
632 GtkWidget* filter = NULL;
633 gboolean active = FALSE;
634
635 filter = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "filter" ) );
636 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( filter ) );
637
638 if(active)
639 {
640 SMPEG_Filter * filter;
641
642 /* Activate the bilinear filter */
643 filter = SMPEGfilter_bilinear();
644 filter = SMPEG_filter( mpeg, filter );
645 filter->destroy(filter);
646 }
647 else
648 {
649 SMPEG_Filter * filter;
650
651 /* Reset to default (null) filter */
652 filter = SMPEGfilter_null();
653 filter = SMPEG_filter( mpeg, filter );
654 filter->destroy(filter);
655 }
656 }
657
658 }
659
gtv_play(GtkWidget * item,gpointer raw)660 static void gtv_play( GtkWidget* item, gpointer raw )
661 {
662 SMPEG* mpeg = NULL;
663
664 assert( raw );
665
666 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
667
668 if( mpeg ) {
669 // gtv_rewind( raw );
670 SMPEG_play( mpeg );
671 }
672
673 }
674
gtv_pause(GtkWidget * item,gpointer raw)675 static void gtv_pause( GtkWidget* item, gpointer raw )
676 {
677 SMPEG* mpeg = NULL;
678
679 assert( raw );
680
681 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
682
683 if( mpeg ) {
684 SMPEG_pause( mpeg );
685 }
686
687 }
688
gtv_stop(GtkWidget * item,gpointer raw)689 static void gtv_stop( GtkWidget* item, gpointer raw )
690 {
691 SMPEG* mpeg = NULL;
692 SMPEG_Info* info = NULL;
693
694 assert( raw );
695
696 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
697 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
698
699 if( mpeg ) {
700 SMPEG_stop( mpeg );
701 gtv_rewind( raw );
702 SMPEG_getinfo( mpeg, info );
703 gtv_set_trackbar( raw, info->current_offset );
704 }
705
706 }
707
gtv_step(GtkWidget * item,gpointer raw)708 static void gtv_step( GtkWidget* item, gpointer raw )
709 {
710 SMPEG* mpeg = NULL;
711 SMPEG_Info* info = NULL;
712
713 assert( raw );
714
715 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
716 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
717
718 if( mpeg && info && info->has_video && ( SMPEG_status( mpeg ) != SMPEG_PLAYING ) ) {
719 int next_frame = 0;
720 GtkWidget* twotimes = NULL;
721 gboolean active = FALSE;
722 SDL_Surface* sdl_screen = NULL;
723
724 SMPEG_getinfo( mpeg, info );
725 next_frame = info->current_frame + 1;
726 twotimes = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "twotimes" ) );
727 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( twotimes ) );
728 sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );
729
730 SMPEG_renderFrame( mpeg, next_frame );
731
732 SMPEG_getinfo( mpeg, info );
733
734 if( info->current_frame != next_frame ) {
735 GtkWidget *looping;
736
737 /* Sam 5/31/2000 - Only loop if the looping toggle is set */
738 looping = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(raw), "loop"));
739 if ( ! gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(looping)) ) {
740 return;
741 }
742 gtv_rewind( raw );
743 gtv_step( NULL, raw );
744 }
745
746 gtv_set_frame( raw, info->current_frame );
747 }
748
749 }
750
gtv_to_end(GtkWidget * item,gpointer raw)751 static void gtv_to_end( GtkWidget* item, gpointer raw )
752 {
753 SMPEG* mpeg = NULL;
754 SMPEG_Info* info = NULL;
755
756 assert( raw );
757
758 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
759 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
760
761 if( mpeg && info->has_video ) {
762 GtkWidget* twotimes = NULL;
763 gboolean active = FALSE;
764 SDL_Surface* sdl_screen = NULL;
765
766 SMPEG_stop( mpeg );
767
768 twotimes = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "twotimes" ) );
769 active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( twotimes ) );
770 sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );
771
772 if( active ) {
773 SMPEG_renderFinal( mpeg, sdl_screen, 0, 0 );
774 } else {
775 SMPEG_renderFinal( mpeg, sdl_screen,
776 ( sdl_screen->w - info->width ) / 2,
777 ( sdl_screen->h - info->height ) / 2 );
778 }
779
780 SMPEG_getinfo( mpeg, info );
781 gtv_set_frame( raw, info->current_frame );
782 }
783
784 }
785
gtv_seek(GtkAdjustment * adjust,gpointer raw)786 static void gtv_seek( GtkAdjustment* adjust, gpointer raw )
787 {
788 SMPEG* mpeg = NULL;
789 SMPEG_Info* info = NULL;
790
791 assert( raw );
792 if(gtv_trackbar_dragging) return;
793
794 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
795 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
796
797 if( mpeg && info && info->total_size ) {
798
799 /* In case file is growing while we're playing */
800 SMPEG_getinfo( mpeg, info );
801
802 SMPEG_seek(mpeg, (int)((info->total_size*adjust->value)/100));
803 SMPEG_getinfo( mpeg, info );
804 gtv_set_frame( raw, info->current_frame );
805 }
806 }
807
gtv_trackbar_drag_on(GtkWidget * widget,gpointer raw)808 static void gtv_trackbar_drag_on(GtkWidget *widget, gpointer raw)
809 {
810 gtv_trackbar_dragging = 1;
811 }
812
gtv_trackbar_drag_off(GtkWidget * widget,gpointer raw)813 static void gtv_trackbar_drag_off(GtkWidget *widget, gpointer raw)
814 {
815 gtv_trackbar_dragging = 0;
816 }
817
gtv_set_frame(gpointer raw,int value)818 static void gtv_set_frame( gpointer raw, int value )
819 {
820 GtkWidget* frame = NULL;
821 gchar buffer[32];
822
823 assert( raw );
824 assert( value >= 0 );
825
826 frame = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "frame" ) );
827 g_snprintf( buffer, 32, "%d", value );
828 gtk_label_set_text( GTK_LABEL( frame ), buffer );
829 }
830
gtv_set_fps(gpointer raw,float value)831 static void gtv_set_fps( gpointer raw, float value )
832 {
833 GtkWidget* fps = NULL;
834 gchar buffer[32];
835
836 assert( raw );
837 assert( value >= 0.0 );
838
839 fps = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "fps" ) );
840 g_snprintf( buffer, 32, "%2.2f", value );
841 gtk_label_set_text( GTK_LABEL( fps ), buffer );
842 }
843
gtv_set_trackbar(gpointer raw,int value)844 static void gtv_set_trackbar( gpointer raw, int value )
845 {
846 SMPEG* mpeg = NULL;
847 SMPEG_Info* info = NULL;
848 GtkWidget* scale = NULL;
849 GtkAdjustment* seek = NULL;
850
851 assert( raw );
852 assert( value >= 0 );
853 if(gtv_trackbar_dragging) return;
854
855 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
856 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
857
858 if( mpeg && info && info->total_size ) {
859 scale = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "scale" ) );
860 seek = gtk_range_get_adjustment ( GTK_RANGE( scale ) );
861 seek->value = 100. * value / info->total_size;
862 gtk_range_set_adjustment ( GTK_RANGE( scale ), seek );
863 gtk_range_slider_update ( GTK_RANGE( scale ) );
864 gtk_range_clear_background ( GTK_RANGE( scale ) );
865 gtk_range_draw_background ( GTK_RANGE( scale ) );
866 }
867 }
868
869 /* Drag-N-Drop support, contributed by */
gtv_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint time)870 static void gtv_drag_data_received(GtkWidget * widget,
871 GdkDragContext * context,
872 gint x,
873 gint y,
874 GtkSelectionData * selection_data,
875 guint info,
876 guint time)
877 {
878 gchar *temp, *string;
879
880 string = (gchar *)selection_data->data;
881
882 /* remove newline at end of line, and the file:// url header
883 at the begining, copied this code from the xmms source */
884 temp = strchr(string, '\n');
885 if (temp)
886 {
887 if (*(temp - 1) == '\r')
888 *(temp - 1) = '\0';
889 *temp = '\0';
890 }
891 if (!strncmp(string, "file:", 5))
892 string = string + 5;
893
894 gtv_open_file(string, widget);
895 gtv_play(NULL, widget);
896 }
897
gtv_timer(gpointer raw)898 static gint gtv_timer( gpointer raw )
899 {
900 SMPEG* mpeg = NULL;
901 SMPEG_Info* info = NULL;
902
903 mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );
904 info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );
905
906 if( mpeg && info ) {
907
908 if( SMPEG_status( mpeg ) == SMPEG_PLAYING ) {
909 SMPEG_getinfo( mpeg, info );
910 gtv_set_frame( raw, info->current_frame );
911 gtv_set_fps( raw, info->current_fps );
912 gtv_set_trackbar( raw, info->current_offset );
913 }
914
915 }
916
917 return 1;
918 }
919
gtv_clear_screen(gpointer raw)920 static void gtv_clear_screen( gpointer raw )
921 {
922 SDL_Surface* sdl_screen = NULL;
923
924 sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );
925
926 if( sdl_screen ) {
927 SDL_FillRect( sdl_screen, NULL, SDL_MapRGB( sdl_screen->format, 0, 0, 0 ) );
928 SDL_UpdateRect( sdl_screen, 0, 0, 0, 0 );
929 }
930
931 }
932
gtv_quit(GtkWidget * item,gpointer raw)933 static void gtv_quit( GtkWidget* item, gpointer raw )
934 {
935 gtv_close( NULL, raw );
936 gtk_exit( 0 );
937 }
938
gtv_connect(gpointer raw,gchar * name,gchar * signal,GtkSignalFunc func)939 static void gtv_connect( gpointer raw, gchar* name, gchar* signal, GtkSignalFunc func )
940 {
941 GtkObject* item = NULL;
942
943 assert( raw );
944
945 item = GTK_OBJECT( gtk_object_get_data( GTK_OBJECT( raw ), name ) );
946 assert( item );
947 gtk_signal_connect(item, signal, func, raw );
948 }
949
main(int argc,char * argv[])950 int main( int argc, char* argv[] )
951 {
952 static GtkTargetEntry drop_types[] =
953 {
954 { "text/plain", 0, 1 }
955 };
956 /* These are always on the stack until program exit. */
957 SMPEG_Info info;
958 gchar filename_buffer[FILENAME_BUFFER_SIZE];
959
960 GtkWidget* window = NULL;
961
962 memset( &info, 0, sizeof( info ) );
963 memset( &filename_buffer, 0, sizeof( gchar ) * FILENAME_BUFFER_SIZE );
964 gtk_set_locale();
965 gtk_init( &argc, &argv );
966 gtk_set_locale ();
967
968 window = create_gtv_window( );
969 gtk_drag_dest_set(window, GTK_DEST_DEFAULT_ALL, drop_types, 1, GDK_ACTION_COPY);
970 gtk_signal_connect( GTK_OBJECT( window ), "drag_data_received",
971 GTK_SIGNAL_FUNC( gtv_drag_data_received ), window );
972 gtk_signal_connect( GTK_OBJECT( window ), "destroy",
973 GTK_SIGNAL_FUNC( gtv_quit ), window );
974 gtk_object_set_data( GTK_OBJECT( window ), "info", &info );
975 gtk_object_set_data( GTK_OBJECT( window ), "mpeg", NULL );
976 gtk_object_set_data( GTK_OBJECT( window ), "sdl_screen", NULL );
977 gtk_object_set_data( GTK_OBJECT( window ), "filename_buffer", filename_buffer );
978 gtk_widget_show( window );
979
980 gtv_connect( window, "open", "activate", GTK_SIGNAL_FUNC( gtv_open ) );
981 gtv_connect( window, "close", "activate", GTK_SIGNAL_FUNC( gtv_close ) );
982 gtv_connect( window, "file_info", "activate", GTK_SIGNAL_FUNC( gtv_info ) );
983 gtv_connect( window, "quit", "activate", GTK_SIGNAL_FUNC( gtv_quit ) );
984 gtv_connect( window, "about", "activate", GTK_SIGNAL_FUNC( gtv_about ) );
985
986 gtv_connect( window, "play", "clicked", GTK_SIGNAL_FUNC( gtv_play ) );
987 gtv_connect( window, "pause", "clicked", GTK_SIGNAL_FUNC( gtv_pause ) );
988 gtv_connect( window, "stop", "clicked", GTK_SIGNAL_FUNC( gtv_stop ) );
989 gtv_connect( window, "step", "clicked", GTK_SIGNAL_FUNC( gtv_step ) );
990 gtv_connect( window, "to_end", "clicked", GTK_SIGNAL_FUNC( gtv_to_end ) );
991
992 gtv_connect( window, "twotimes", "toggled", GTK_SIGNAL_FUNC( gtv_double ) );
993 gtv_connect( window, "loop", "toggled", GTK_SIGNAL_FUNC( gtv_loop ) );
994 gtv_connect( window, "audio", "toggled", GTK_SIGNAL_FUNC( gtv_audio ) );
995 gtv_connect( window, "filter", "toggled", GTK_SIGNAL_FUNC( gtv_filter ) );
996
997 gtv_connect( window, "seek", "value_changed", GTK_SIGNAL_FUNC( gtv_seek ) );
998
999 gtv_connect( window, "scale", "button_press_event", GTK_SIGNAL_FUNC( gtv_trackbar_drag_on ) );
1000 gtv_connect( window, "scale", "button_release_event", GTK_SIGNAL_FUNC( gtv_trackbar_drag_off ) );
1001
1002 /* gtk_idle_add_priority( G_PRIORITY_LOW, gtv_timer, window );*/
1003 gtk_timeout_add( TIMER_TIMEOUT, gtv_timer, window );
1004
1005 gtv_set_frame( window, 0 );
1006 gtv_set_fps( window, 0.0 );
1007 gtv_set_buttons_sensitive( window, FALSE );
1008
1009 if( argc > 1 ) {
1010 gtv_open_file( argv[1], window );
1011 }
1012
1013 gtk_main( );
1014
1015 return 0;
1016 }
1017
create_gtv_window(void)1018 static GtkWidget* create_gtv_window( void )
1019 {
1020 GtkWidget *gtv_window;
1021 GtkWidget *vbox1;
1022 GtkWidget *menubar1;
1023 GtkWidget *file;
1024 GtkWidget *file_menu;
1025 GtkAccelGroup *file_menu_accels;
1026 GtkWidget *open;
1027 GtkWidget *close;
1028 GtkWidget *separator1;
1029 GtkWidget *file_info;
1030 GtkWidget *separator2;
1031 GtkWidget *quit;
1032 GtkWidget *help;
1033 GtkWidget *help_menu;
1034 GtkAccelGroup *help_menu_accels;
1035 GtkWidget *about;
1036 GtkWidget *table1;
1037 GtkObject *seek;
1038 GtkWidget *scale;
1039 GtkWidget *play;
1040 GtkWidget *pause;
1041 GtkWidget *stop;
1042 GtkWidget *step;
1043 GtkWidget *to_end;
1044 GtkWidget *twotimes;
1045 GtkWidget *loop;
1046 GtkWidget *audio;
1047 GtkWidget *filter;
1048 GtkWidget *label3;
1049 GtkWidget *fps;
1050 GtkWidget *label2;
1051 GtkWidget *frame;
1052 GtkAccelGroup *accel_group;
1053
1054 accel_group = gtk_accel_group_new ();
1055
1056 gtv_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1057 gtk_object_set_data (GTK_OBJECT (gtv_window), "gtv_window", gtv_window);
1058 gtk_window_set_title (GTK_WINDOW (gtv_window), "gtv");
1059 gtk_widget_set_uposition (GTK_WIDGET (gtv_window), 0, 0);
1060
1061 vbox1 = gtk_vbox_new (FALSE, 0);
1062 gtk_widget_ref (vbox1);
1063 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "vbox1", vbox1,
1064 (GtkDestroyNotify) gtk_widget_unref);
1065 gtk_widget_show (vbox1);
1066 gtk_container_add (GTK_CONTAINER (gtv_window), vbox1);
1067
1068 menubar1 = gtk_menu_bar_new ();
1069 gtk_widget_ref (menubar1);
1070 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "menubar1", menubar1,
1071 (GtkDestroyNotify) gtk_widget_unref);
1072 gtk_widget_show (menubar1);
1073 gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
1074
1075 file = gtk_menu_item_new_with_label ("File");
1076 gtk_widget_ref (file);
1077 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "file", file,
1078 (GtkDestroyNotify) gtk_widget_unref);
1079 gtk_widget_show (file);
1080 gtk_container_add (GTK_CONTAINER (menubar1), file);
1081
1082 file_menu = gtk_menu_new ();
1083 gtk_widget_ref (file_menu);
1084 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "file_menu", file_menu,
1085 (GtkDestroyNotify) gtk_widget_unref);
1086 gtk_menu_item_set_submenu (GTK_MENU_ITEM (file), file_menu);
1087 file_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file_menu));
1088
1089 open = gtk_menu_item_new_with_label ("Open");
1090 gtk_widget_ref (open);
1091 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "open", open,
1092 (GtkDestroyNotify) gtk_widget_unref);
1093 gtk_widget_show (open);
1094 gtk_container_add (GTK_CONTAINER (file_menu), open);
1095 gtk_widget_add_accelerator (open, "activate", accel_group,
1096 GDK_O, GDK_CONTROL_MASK,
1097 GTK_ACCEL_VISIBLE);
1098
1099 close = gtk_menu_item_new_with_label ("Close");
1100 gtk_widget_ref (close);
1101 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "close", close,
1102 (GtkDestroyNotify) gtk_widget_unref);
1103 gtk_widget_show (close);
1104 gtk_container_add (GTK_CONTAINER (file_menu), close);
1105 gtk_widget_add_accelerator (close, "activate", accel_group,
1106 GDK_W, GDK_CONTROL_MASK,
1107 GTK_ACCEL_VISIBLE);
1108
1109 separator1 = gtk_menu_item_new ();
1110 gtk_widget_ref (separator1);
1111 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "separator1", separator1,
1112 (GtkDestroyNotify) gtk_widget_unref);
1113 gtk_widget_show (separator1);
1114 gtk_container_add (GTK_CONTAINER (file_menu), separator1);
1115 gtk_widget_set_sensitive (separator1, FALSE);
1116
1117 file_info = gtk_menu_item_new_with_label ("Info");
1118 gtk_widget_ref (file_info);
1119 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "file_info", file_info,
1120 (GtkDestroyNotify) gtk_widget_unref);
1121 gtk_widget_show (file_info);
1122 gtk_container_add (GTK_CONTAINER (file_menu), file_info);
1123 gtk_widget_add_accelerator (file_info, "activate", accel_group,
1124 GDK_I, GDK_CONTROL_MASK,
1125 GTK_ACCEL_VISIBLE);
1126
1127 separator2 = gtk_menu_item_new ();
1128 gtk_widget_ref (separator2);
1129 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "separator2", separator2,
1130 (GtkDestroyNotify) gtk_widget_unref);
1131 gtk_widget_show (separator2);
1132 gtk_container_add (GTK_CONTAINER (file_menu), separator2);
1133 gtk_widget_set_sensitive (separator2, FALSE);
1134
1135 quit = gtk_menu_item_new_with_label ("Quit");
1136 gtk_widget_ref (quit);
1137 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "quit", quit,
1138 (GtkDestroyNotify) gtk_widget_unref);
1139 gtk_widget_show (quit);
1140 gtk_container_add (GTK_CONTAINER (file_menu), quit);
1141 gtk_widget_add_accelerator (quit, "activate", accel_group,
1142 GDK_Q, GDK_CONTROL_MASK,
1143 GTK_ACCEL_VISIBLE);
1144
1145 help = gtk_menu_item_new_with_label ("Help");
1146 gtk_widget_ref (help);
1147 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "help", help,
1148 (GtkDestroyNotify) gtk_widget_unref);
1149 gtk_widget_show (help);
1150 gtk_container_add (GTK_CONTAINER (menubar1), help);
1151 gtk_menu_item_right_justify (GTK_MENU_ITEM (help));
1152
1153 help_menu = gtk_menu_new ();
1154 gtk_widget_ref (help_menu);
1155 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "help_menu", help_menu,
1156 (GtkDestroyNotify) gtk_widget_unref);
1157 gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu);
1158 help_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (help_menu));
1159
1160 about = gtk_menu_item_new_with_label ("About");
1161 gtk_widget_ref (about);
1162 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "about", about,
1163 (GtkDestroyNotify) gtk_widget_unref);
1164 gtk_widget_show (about);
1165 gtk_container_add (GTK_CONTAINER (help_menu), about);
1166 gtk_widget_add_accelerator (about, "activate", accel_group,
1167 GDK_F1, 0,
1168 GTK_ACCEL_VISIBLE);
1169
1170 table1 = gtk_table_new (4, 5, FALSE);
1171 gtk_widget_ref (table1);
1172 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "table1", table1,
1173 (GtkDestroyNotify) gtk_widget_unref);
1174 gtk_widget_show (table1);
1175 gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
1176 gtk_container_set_border_width (GTK_CONTAINER (table1), 5);
1177 gtk_table_set_row_spacings (GTK_TABLE (table1), 5);
1178 gtk_table_set_col_spacings (GTK_TABLE (table1), 5);
1179
1180 seek = gtk_adjustment_new(0.0, 0.0, 100.0, 1.0, 0.0, 0.0);
1181 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "seek", seek,
1182 (GtkDestroyNotify) (0));
1183 scale = gtk_hscale_new(GTK_ADJUSTMENT(seek));
1184 gtv_trackbar_dragging = 0;
1185 gtk_widget_ref (scale);
1186 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "scale", scale,
1187 (GtkDestroyNotify) gtk_widget_unref);
1188 gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
1189 gtk_widget_show (scale);
1190 gtk_table_attach (GTK_TABLE (table1), scale, 0, 5, 3, 4,
1191 (GtkAttachOptions) (GTK_FILL),
1192 (GtkAttachOptions) (0), 0, 0);
1193
1194 play = gtk_button_new_with_label (" Play ");
1195 gtk_widget_ref (play);
1196 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "play", play,
1197 (GtkDestroyNotify) gtk_widget_unref);
1198 gtk_widget_show (play);
1199 gtk_table_attach (GTK_TABLE (table1), play, 0, 1, 1, 2,
1200 (GtkAttachOptions) (0),
1201 (GtkAttachOptions) (0), 0, 0);
1202
1203 pause = gtk_button_new_with_label (" Pause ");
1204 gtk_widget_ref (pause);
1205 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "pause", pause,
1206 (GtkDestroyNotify) gtk_widget_unref);
1207 gtk_widget_show (pause);
1208 gtk_table_attach (GTK_TABLE (table1), pause, 1, 2, 1, 2,
1209 (GtkAttachOptions) (0),
1210 (GtkAttachOptions) (0), 0, 0);
1211
1212 stop = gtk_button_new_with_label (" Stop ");
1213 gtk_widget_ref (stop);
1214 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "stop", stop,
1215 (GtkDestroyNotify) gtk_widget_unref);
1216 gtk_widget_show (stop);
1217 gtk_table_attach (GTK_TABLE (table1), stop, 2, 3, 1, 2,
1218 (GtkAttachOptions) (0),
1219 (GtkAttachOptions) (0), 0, 0);
1220
1221 step = gtk_button_new_with_label (" Step ");
1222 gtk_widget_ref (step);
1223 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "step", step,
1224 (GtkDestroyNotify) gtk_widget_unref);
1225 gtk_widget_show (step);
1226 gtk_table_attach (GTK_TABLE (table1), step, 3, 4, 1, 2,
1227 (GtkAttachOptions) (0),
1228 (GtkAttachOptions) (0), 0, 0);
1229
1230 to_end = gtk_button_new_with_label (" To End ");
1231 gtk_widget_ref (to_end);
1232 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "to_end", to_end,
1233 (GtkDestroyNotify) gtk_widget_unref);
1234 gtk_widget_show (to_end);
1235 gtk_table_attach (GTK_TABLE (table1), to_end, 4, 5, 1, 2,
1236 (GtkAttachOptions) (0),
1237 (GtkAttachOptions) (0), 0, 0);
1238
1239 twotimes = gtk_check_button_new_with_label ("Double");
1240 gtk_widget_ref (twotimes);
1241 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "twotimes", twotimes,
1242 (GtkDestroyNotify) gtk_widget_unref);
1243 gtk_widget_show (twotimes);
1244 gtk_table_attach (GTK_TABLE (table1), twotimes, 0, 1, 2, 3,
1245 (GtkAttachOptions) (0),
1246 (GtkAttachOptions) (0), 0, 0);
1247
1248 loop = gtk_check_button_new_with_label ("Loop");
1249 gtk_widget_ref (loop);
1250 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "loop", loop,
1251 (GtkDestroyNotify) gtk_widget_unref);
1252 gtk_widget_show (loop);
1253 gtk_table_attach (GTK_TABLE (table1), loop, 1, 2, 2, 3,
1254 (GtkAttachOptions) (0),
1255 (GtkAttachOptions) (0), 0, 0);
1256
1257 audio = gtk_check_button_new_with_label ("Audio");
1258 gtk_widget_ref (audio);
1259 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "audio", audio,
1260 (GtkDestroyNotify) gtk_widget_unref);
1261 gtk_widget_show (audio);
1262 gtk_table_attach (GTK_TABLE (table1), audio, 2, 3, 2, 3,
1263 (GtkAttachOptions) (0),
1264 (GtkAttachOptions) (0), 0, 0);
1265
1266 filter = gtk_check_button_new_with_label ("Filter");
1267 gtk_widget_ref (filter);
1268 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "filter", filter,
1269 (GtkDestroyNotify) gtk_widget_unref);
1270 gtk_widget_show (filter);
1271 gtk_table_attach (GTK_TABLE (table1), filter, 3, 4, 2, 3,
1272 (GtkAttachOptions) (0),
1273 (GtkAttachOptions) (0), 0, 0);
1274
1275 label3 = gtk_label_new ("Current frame:");
1276 gtk_widget_ref (label3);
1277 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "label3", label3,
1278 (GtkDestroyNotify) gtk_widget_unref);
1279 gtk_widget_show (label3);
1280 gtk_table_attach (GTK_TABLE (table1), label3, 0, 2, 0, 1,
1281 (GtkAttachOptions) (GTK_FILL),
1282 (GtkAttachOptions) (0), 0, 0);
1283 gtk_misc_set_alignment (GTK_MISC (label3), 1, 0.5);
1284
1285 fps = gtk_label_new ("<fps>");
1286 gtk_widget_ref (fps);
1287 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "fps", fps,
1288 (GtkDestroyNotify) gtk_widget_unref);
1289 gtk_widget_show (fps);
1290 gtk_table_attach (GTK_TABLE (table1), fps, 3, 4, 0, 1,
1291 (GtkAttachOptions) (GTK_FILL),
1292 (GtkAttachOptions) (0), 0, 0);
1293 gtk_misc_set_alignment (GTK_MISC (fps), 1, 0.5);
1294
1295 label2 = gtk_label_new ("fps");
1296 gtk_widget_ref (label2);
1297 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "label2", label2,
1298 (GtkDestroyNotify) gtk_widget_unref);
1299 gtk_widget_show (label2);
1300 gtk_table_attach (GTK_TABLE (table1), label2, 4, 5, 0, 1,
1301 (GtkAttachOptions) (GTK_FILL),
1302 (GtkAttachOptions) (0), 0, 0);
1303 gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
1304
1305 frame = gtk_label_new ("<frame>");
1306 gtk_widget_ref (frame);
1307 gtk_object_set_data_full (GTK_OBJECT (gtv_window), "frame", frame,
1308 (GtkDestroyNotify) gtk_widget_unref);
1309 gtk_widget_show (frame);
1310 gtk_table_attach (GTK_TABLE (table1), frame, 2, 3, 0, 1,
1311 (GtkAttachOptions) (GTK_FILL),
1312 (GtkAttachOptions) (0), 0, 0);
1313 gtk_misc_set_alignment (GTK_MISC (frame), 0, 0.5);
1314
1315 gtk_window_add_accel_group (GTK_WINDOW (gtv_window), accel_group);
1316
1317 return gtv_window;
1318 }
1319