10 #include "interface.h"
11 #include "skin/skin.h"
13 #include "mplayer/gtk/eq.h"
14 #include "mplayer/widgets.h"
15 #include "mplayer/gmplayer.h"
16 #include "mplayer/play.h"
18 #include "access_mpcontext.h"
23 #include "libvo/x11_common.h"
24 #include "libvo/video_out.h"
25 #include "libvo/font_load.h"
26 #include "libvo/sub.h"
27 #include "input/input.h"
28 #include "libao2/audio_out.h"
31 #include "libaf/equalizer.h"
32 #include "libass/ass.h"
33 #include "libass/ass_mp.h"
35 extern af_cfg_t af_cfg
;
41 #include "stream/stream.h"
42 #include "libmpdemux/demuxer.h"
43 #include "libmpdemux/stheader.h"
44 #include "libmpcodecs/dec_video.h"
47 #include "stream/stream_dvd.h"
50 int vcd_seek_to_track(void *vcd
, int track
);
56 guiInterface_t guiIntfStruct
;
59 char * gstrcat( char ** dest
,const char * src
)
63 if ( !src
) return NULL
;
67 tmp
=malloc( strlen( *dest
) + strlen( src
) + 1 );
69 if ( tmp
) /* TODO: advanced error handling */
71 strcpy( tmp
,*dest
); strcat( tmp
,src
); free( *dest
);
75 { tmp
=malloc( strlen( src
) + 1 ); strcpy( tmp
,src
); }
80 int gstrcmp( const char * a
,const char * b
)
82 if ( !a
&& !b
) return 0;
83 if ( !a
|| !b
) return -1;
87 int gstrncmp( const char * a
,const char * b
,int size
)
89 if ( !a
&& !b
) return 0;
90 if ( !a
|| !b
) return -1;
91 return strncmp( a
,b
,size
);
94 char * gstrdup( const char * str
)
96 if ( !str
) return NULL
;
100 char * gstrchr( char * str
,int c
)
102 if ( !str
) return NULL
;
103 return strchr( str
,c
);
106 void gfree( void ** p
)
108 if ( *p
== NULL
) return;
112 void gset( char ** str
, const char * what
)
114 if ( *str
) { if ( !strstr( *str
,what
) ) { gstrcat( str
,"," ); gstrcat( str
,what
); }}
115 else gstrcat( str
,what
);
119 * \brief this actually creates a new list containing only one element...
121 void gaddlist( char *** list
,const char * entry
)
127 for ( i
=0;(*list
)[i
];i
++ ) free( (*list
)[i
] );
131 (*list
)=malloc( 2 * sizeof(char **) );
132 (*list
)[0]=gstrdup( entry
);
137 * \brief this replaces a string starting with search by replace.
138 * If not found, replace is appended.
140 void greplace(char ***list
, const char *search
, const char *replace
)
143 int len
= (search
) ? strlen(search
) : 0;
146 for (i
= 0; (*list
)[i
]; i
++) {
147 if (search
&& (strncmp((*list
)[i
], search
, len
) == 0)) {
149 (*list
)[i
] = gstrdup(replace
);
153 *list
= realloc(*list
, (i
+ 2) * sizeof(char *));
156 *list
= malloc(2 * sizeof(char *));
158 (*list
)[i
] = gstrdup(replace
);
159 (*list
)[i
+ 1] = NULL
;
166 memset( &guiIntfStruct
,0,sizeof( guiIntfStruct
) );
167 guiIntfStruct
.Balance
=50.0f
;
168 guiIntfStruct
.StreamType
=-1;
170 memset( >kEquChannels
,0,sizeof( gtkEquChannels
) );
172 if ( !gtkDXR3Device
) gtkDXR3Device
=strdup( "/dev/em8300-0" );
174 if ( stream_cache_size
> 0 ) { gtkCacheOn
=1; gtkCacheSize
=stream_cache_size
; }
175 else if ( stream_cache_size
== 0 ) gtkCacheOn
= 0;
176 if ( autosync
&& autosync
!= gtkAutoSync
) { gtkAutoSyncOn
=1; gtkAutoSync
=autosync
; }
179 gtkASS
.enabled
= ass_enabled
;
180 gtkASS
.use_margins
= ass_use_margins
;
181 gtkASS
.top_margin
= ass_top_margin
;
182 gtkASS
.bottom_margin
= ass_bottom_margin
;
187 wsXInit( (void *)mDisplay
);
189 skinDirInHome
=get_path("skins");
190 skinDirInHome_obsolete
=get_path("Skin");
191 skinMPlayerDir
=MPLAYER_DATADIR
"/skins";
192 skinMPlayerDir_obsolete
=MPLAYER_DATADIR
"/Skin";
193 mp_msg( MSGT_GPLAYER
,MSGL_V
,"SKIN dir 1: '%s'\n",skinDirInHome
);
194 mp_msg( MSGT_GPLAYER
,MSGL_V
,"SKIN dir 1 (obsolete): '%s'\n",skinDirInHome_obsolete
);
195 mp_msg( MSGT_GPLAYER
,MSGL_V
,"SKIN dir 2: '%s'\n",skinMPlayerDir
);
196 mp_msg( MSGT_GPLAYER
,MSGL_V
,"SKIN dir 2 (obsolete): '%s'\n",skinMPlayerDir_obsolete
);
197 if ( !skinName
) skinName
=strdup( "default" );
198 i
= skinRead( skinName
);
199 if ((i
== -1) && strcmp(skinName
,"default"))
201 mp_msg( MSGT_GPLAYER
,MSGL_WARN
,MSGTR_SKIN_SKINCFG_SelectedSkinNotFound
, skinName
);
202 skinName
=strdup( "default" );
203 i
= skinRead( skinName
);
206 case -1: mp_msg( MSGT_GPLAYER
,MSGL_ERR
,MSGTR_SKIN_SKINCFG_SkinNotFound
,skinName
); exit( 0 );
207 case -2: mp_msg( MSGT_GPLAYER
,MSGL_ERR
,MSGTR_SKIN_SKINCFG_SkinCfgReadError
,skinName
); exit( 0 );
209 // --- initialize windows
210 if ( ( mplDrawBuffer
= malloc( appMPlayer
.main
.Bitmap
.ImageSize
) ) == NULL
)
212 fprintf( stderr
,MSGTR_NEMDB
);
218 appMPlayer
.main
.x
= gui_main_pos_x
;
219 appMPlayer
.main
.y
= gui_main_pos_y
;
220 appMPlayer
.sub
.x
= gui_sub_pos_x
;
221 appMPlayer
.sub
.y
= gui_sub_pos_y
;
226 appMPlayer
.subWindow
.Parent
=WinID
;
230 if (guiWinID
>=0) appMPlayer
.mainWindow
.Parent
=guiWinID
;
232 wsCreateWindow( &appMPlayer
.subWindow
,
233 appMPlayer
.sub
.x
,appMPlayer
.sub
.y
,appMPlayer
.sub
.width
,appMPlayer
.sub
.height
,
234 wsNoBorder
,wsShowMouseCursor
|wsHandleMouseButton
|wsHandleMouseMove
,wsShowFrame
|wsHideWindow
,"MPlayer - Video" );
236 wsDestroyImage( &appMPlayer
.subWindow
);
237 wsCreateImage( &appMPlayer
.subWindow
,appMPlayer
.sub
.Bitmap
.Width
,appMPlayer
.sub
.Bitmap
.Height
);
238 wsXDNDMakeAwareness(&appMPlayer
.subWindow
);
243 vo_setwindow( appMPlayer
.subWindow
.WindowID
, appMPlayer
.subWindow
.wGC
);
245 // i=wsHideFrame|wsMaxSize|wsHideWindow;
246 // if ( appMPlayer.mainDecoration ) i=wsShowFrame|wsMaxSize|wsHideWindow;
247 i
=wsShowFrame
|wsMaxSize
|wsHideWindow
;
248 wsCreateWindow( &appMPlayer
.mainWindow
,
249 appMPlayer
.main
.x
,appMPlayer
.main
.y
,appMPlayer
.main
.width
,appMPlayer
.main
.height
,
250 wsNoBorder
,wsShowMouseCursor
|wsHandleMouseButton
|wsHandleMouseMove
,i
,"MPlayer" );
252 wsSetShape( &appMPlayer
.mainWindow
,appMPlayer
.main
.Mask
.Image
);
253 wsXDNDMakeAwareness(&appMPlayer
.mainWindow
);
256 mp_msg( MSGT_GPLAYER
,MSGL_DBG2
,"[main] depth on screen: %d\n",wsDepthOnScreen
);
257 mp_msg( MSGT_GPLAYER
,MSGL_DBG2
,"[main] parent: 0x%x\n",(int)appMPlayer
.mainWindow
.WindowID
);
258 mp_msg( MSGT_GPLAYER
,MSGL_DBG2
,"[main] sub: 0x%x\n",(int)appMPlayer
.subWindow
.WindowID
);
261 appMPlayer
.mainWindow
.ReDraw
=(void *)mplMainDraw
;
262 appMPlayer
.mainWindow
.MouseHandler
=mplMainMouseHandle
;
263 appMPlayer
.mainWindow
.KeyHandler
=mplMainKeyHandle
;
264 appMPlayer
.mainWindow
.DandDHandler
=mplDandDHandler
;
266 appMPlayer
.subWindow
.ReDraw
=(void *)mplSubDraw
;
267 appMPlayer
.subWindow
.MouseHandler
=mplSubMouseHandle
;
268 appMPlayer
.subWindow
.KeyHandler
=mplMainKeyHandle
;
269 appMPlayer
.subWindow
.DandDHandler
=mplDandDHandler
;
271 wsSetBackgroundRGB( &appMPlayer
.subWindow
,appMPlayer
.sub
.R
,appMPlayer
.sub
.G
,appMPlayer
.sub
.B
);
272 wsClearWindow( appMPlayer
.subWindow
);
273 if ( appMPlayer
.sub
.Bitmap
.Image
) wsConvert( &appMPlayer
.subWindow
,appMPlayer
.sub
.Bitmap
.Image
,appMPlayer
.sub
.Bitmap
.ImageSize
);
275 btnModify( evSetVolume
,guiIntfStruct
.Volume
);
276 btnModify( evSetBalance
,guiIntfStruct
.Balance
);
277 btnModify( evSetMoviePosition
,guiIntfStruct
.Position
);
279 wsSetIcon( wsDisplay
,appMPlayer
.mainWindow
.WindowID
,guiIcon
,guiIconMask
);
280 wsSetIcon( wsDisplay
,appMPlayer
.subWindow
.WindowID
,guiIcon
,guiIconMask
);
282 guiIntfStruct
.Playing
=0;
284 if ( !appMPlayer
.mainDecoration
) wsWindowDecoration( &appMPlayer
.mainWindow
,0 );
286 wsVisibleWindow( &appMPlayer
.mainWindow
,wsShowWindow
);
288 wsVisibleWindow( &appMPlayer
.subWindow
,wsShowWindow
);
292 do { XNextEvent( wsDisplay
,&xev
); } while ( xev
.type
!= MapNotify
|| xev
.xmap
.event
!= appMPlayer
.subWindow
.WindowID
);
293 appMPlayer
.subWindow
.Mapped
=wsMapped
;
296 if ( !fullscreen
) fullscreen
=gtkLoadFullscreen
;
300 btnModify( evFullScreen
,btnPressed
);
303 if ( !fullscreen
) fullscreen
=gtkLoadFullscreen
;
304 if ( gtkShowVideoWindow
)
306 wsVisibleWindow( &appMPlayer
.subWindow
,wsShowWindow
);
309 do { XNextEvent( wsDisplay
,&xev
); } while ( xev
.type
!= MapNotify
|| xev
.xmap
.event
!= appMPlayer
.subWindow
.WindowID
);
310 appMPlayer
.subWindow
.Mapped
=wsMapped
;
316 btnModify( evFullScreen
,btnPressed
);
323 wsVisibleWindow( &appMPlayer
.subWindow
,wsShowWindow
);
326 do { XNextEvent( wsDisplay
,&xev
); } while ( xev
.type
!= MapNotify
|| xev
.xmap
.event
!= appMPlayer
.subWindow
.WindowID
);
327 appMPlayer
.subWindow
.Mapped
=wsMapped
;
329 wsVisibleWindow( &appMPlayer
.subWindow
, wsShowWindow
);
332 btnModify( evFullScreen
,btnPressed
);
339 if ( filename
) mplSetFileName( NULL
,filename
,STREAMTYPE_FILE
);
340 if ( plCurrent
&& !filename
) mplSetFileName( plCurrent
->path
,plCurrent
->name
,STREAMTYPE_FILE
);
341 if ( subdata
) guiSetFilename( guiIntfStruct
.Subtitlename
, subdata
->filename
);
348 mp_msg( MSGT_GPLAYER
,MSGL_V
,"[GUI] done.\n" );
352 gui_main_pos_x
=appMPlayer
.mainWindow
.X
; gui_main_pos_y
=appMPlayer
.mainWindow
.Y
;
353 gui_sub_pos_x
=appMPlayer
.subWindow
.X
; gui_sub_pos_y
=appMPlayer
.subWindow
.Y
;
357 ass_enabled
= gtkASS
.enabled
;
358 ass_use_margins
= gtkASS
.use_margins
;
359 ass_top_margin
= gtkASS
.top_margin
;
360 ass_bottom_margin
= gtkASS
.bottom_margin
;
380 extern int stream_dump_type
;
381 extern int vcd_track
;
382 extern m_obj_settings_t
* vf_settings
;
384 void guiLoadFont( void )
387 load_font_ft(vo_image_width
, vo_image_height
, &vo_font
, font_name
);
392 if ( vo_font
->name
) free( vo_font
->name
);
393 if ( vo_font
->fpath
) free( vo_font
->fpath
);
395 if ( vo_font
->pic_a
[i
] )
397 if ( vo_font
->pic_a
[i
]->bmp
) free( vo_font
->pic_a
[i
]->bmp
);
398 if ( vo_font
->pic_a
[i
]->pal
) free( vo_font
->pic_a
[i
]->pal
);
401 if ( vo_font
->pic_b
[i
] )
403 if ( vo_font
->pic_b
[i
]->bmp
) free( vo_font
->pic_b
[i
]->bmp
);
404 if ( vo_font
->pic_b
[i
]->pal
) free( vo_font
->pic_b
[i
]->pal
);
406 free( vo_font
); vo_font
=NULL
;
410 vo_font
=read_font_desc( font_name
,font_factor
,0 );
411 if ( !vo_font
) mp_msg( MSGT_CPLAYER
,MSGL_ERR
,MSGTR_CantLoadFont
,font_name
);
415 font_name
=gstrdup( get_path( "font/font.desc" ) );
416 vo_font
=read_font_desc( font_name
,font_factor
,0 );
419 gfree( (void **)&font_name
); font_name
=gstrdup(MPLAYER_DATADIR
"/font/font.desc" );
420 vo_font
=read_font_desc( font_name
,font_factor
,0 );
426 extern mp_osd_obj_t
* vo_osd_list
;
428 extern char **sub_name
;
430 void guiLoadSubtitle( char * name
)
432 if ( guiIntfStruct
.Playing
== 0 )
434 guiIntfStruct
.SubtitleChanged
=1; //what is this for? (mw)
439 mp_msg( MSGT_GPLAYER
,MSGL_INFO
,MSGTR_DeletingSubtitles
);
446 mp_osd_obj_t
* osd
= vo_osd_list
;
449 if ( osd
->type
== OSDTYPE_SUBTITLE
) break;
452 if ( osd
&& osd
->flags
&OSDFLAG_VISIBLE
)
454 len
=osd
->stride
* ( osd
->bbox
.y2
- osd
->bbox
.y1
);
455 memset( osd
->bitmap_buffer
,0,len
);
456 memset( osd
->alpha_buffer
,0,len
);
462 mp_msg( MSGT_GPLAYER
,MSGL_INFO
,MSGTR_LoadingSubtitles
,name
);
463 subdata
=sub_read_file( name
, guiIntfStruct
.FPS
);
464 if ( !subdata
) mp_msg( MSGT_GPLAYER
,MSGL_ERR
,MSGTR_CantLoadSub
,name
);
465 sub_name
= (malloc(2 * sizeof(char*))); //when mplayer will be restarted
466 sub_name
[0] = strdup(name
); //sub_name[0] will be read
469 update_set_of_subtitles();
473 static void add_vf( char * str
)
475 mp_msg( MSGT_GPLAYER
,MSGL_STATUS
,MSGTR_AddingVideoFilter
,str
);
479 while ( vf_settings
[i
].name
) if ( !gstrcmp( vf_settings
[i
++].name
,str
) ) { i
=-1; break; }
481 { vf_settings
=realloc( vf_settings
,( i
+ 2 ) * sizeof( m_obj_settings_t
) ); vf_settings
[i
].name
=strdup( str
);vf_settings
[i
].attribs
= NULL
; vf_settings
[i
+1].name
=NULL
; }
482 } else { vf_settings
=malloc( 2 * sizeof( m_obj_settings_t
) ); vf_settings
[0].name
=strdup( str
);vf_settings
[0].attribs
= NULL
; vf_settings
[1].name
=NULL
; }
485 static void remove_vf( char * str
)
489 if ( !vf_settings
) return;
491 mp_msg( MSGT_GPLAYER
,MSGL_STATUS
,MSGTR_RemovingVideoFilter
,str
);
493 while ( vf_settings
[n
++].name
); n
--;
497 while ( vf_settings
[i
].name
) if ( !gstrcmp( vf_settings
[i
++].name
,str
) ) { m
=i
- 1; break; }
501 if ( n
== 1 ) { free( vf_settings
[0].name
);free( vf_settings
[0].attribs
); free( vf_settings
); vf_settings
=NULL
; }
502 else { free( vf_settings
[i
].name
);free( vf_settings
[i
].attribs
); memcpy( &vf_settings
[i
],&vf_settings
[i
+ 1],( n
- i
) * sizeof( m_obj_settings_t
) ); }
507 int guiGetEvent( int type
,char * arg
)
509 ao_functions_t
*audio_out
= NULL
;
510 const vo_functions_t
*video_out
= NULL
;
511 mixer_t
*mixer
= NULL
;
513 stream_t
* stream
= (stream_t
*) arg
;
515 dvd_priv_t
* dvdp
= (dvd_priv_t
*) arg
;
518 if (guiIntfStruct
.mpcontext
) {
519 audio_out
= mpctx_get_audio_out(guiIntfStruct
.mpcontext
);
520 video_out
= mpctx_get_video_out(guiIntfStruct
.mpcontext
);
521 mixer
= mpctx_get_mixer(guiIntfStruct
.mpcontext
);
527 guiIntfStruct
.event_struct
=(void *)arg
;
528 wsEvents( wsDisplay
,(XEvent
*)arg
,NULL
);
535 guiIntfStruct
.Playing
=1;
536 // if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow );
539 guiIntfStruct
.Playing
=0;
540 // if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow );
542 case guiSetPause
: guiIntfStruct
.Playing
=2; break;
550 if ( arg
) guiSetFilename( guiIntfStruct
.Filename
,arg
);
552 case guiSetAudioOnly
:
553 guiIntfStruct
.AudioOnly
=(int)arg
;
554 if ( (int)arg
) { guiIntfStruct
.NoWindow
=True
; wsVisibleWindow( &appMPlayer
.subWindow
,wsHideWindow
); }
555 else wsVisibleWindow( &appMPlayer
.subWindow
,wsShowWindow
);
558 guiIntfStruct
.mpcontext
=(void *)arg
;
560 guiIntfStruct
.demuxer
=(void *)arg
;
563 guiIntfStruct
.afilter
=(void *)arg
;
567 if ( !appMPlayer
.subWindow
.isFullScreen
)
569 wsResizeWindow( &appMPlayer
.subWindow
,vo_dwidth
,vo_dheight
);
570 wsMoveWindow( &appMPlayer
.subWindow
,True
,appMPlayer
.sub
.x
,appMPlayer
.sub
.y
);
572 guiIntfStruct
.MovieWidth
=vo_dwidth
;
573 guiIntfStruct
.MovieHeight
=vo_dheight
;
575 wsMoveWindow( &appMPlayer
.mainWindow
,0,0, vo_dheight
);
580 guiIntfStruct
.DVD
.titles
=dvdp
->vmg_file
->tt_srpt
->nr_of_srpts
;
581 guiIntfStruct
.DVD
.chapters
=dvdp
->vmg_file
->tt_srpt
->title
[dvd_title
].nr_of_ptts
;
582 guiIntfStruct
.DVD
.angles
=dvdp
->vmg_file
->tt_srpt
->title
[dvd_title
].nr_of_angles
;
583 guiIntfStruct
.DVD
.nr_of_audio_channels
=dvdp
->nr_of_channels
;
584 memcpy( guiIntfStruct
.DVD
.audio_streams
,dvdp
->audio_streams
,sizeof( dvdp
->audio_streams
) );
585 guiIntfStruct
.DVD
.nr_of_subtitles
=dvdp
->nr_of_subtitles
;
586 memcpy( guiIntfStruct
.DVD
.subtitles
,dvdp
->subtitles
,sizeof( dvdp
->subtitles
) );
587 guiIntfStruct
.DVD
.current_title
=dvd_title
+ 1;
588 guiIntfStruct
.DVD
.current_chapter
=dvd_chapter
+ 1;
589 guiIntfStruct
.DVD
.current_angle
=dvd_angle
+ 1;
590 guiIntfStruct
.Track
=dvd_title
+ 1;
594 guiIntfStruct
.StreamType
=stream
->type
;
595 switch( stream
->type
)
599 guiGetEvent( guiSetDVD
,(char *)stream
->priv
);
609 guiIntfStruct
.VCDTracks
=0;
612 for ( i
=1;i
< 100;i
++ )
613 if ( vcd_seek_to_track( stream
->priv
,i
) < 0 ) break;
614 vcd_seek_to_track( stream
->priv
,vcd_track
);
615 guiIntfStruct
.VCDTracks
=--i
;
623 mp_msg( MSGT_GPLAYER
,MSGL_V
,"cmd: %d\n",(int)arg
);
627 mplEventHandling( evExit
,0 );
629 case MP_CMD_VO_FULLSCREEN
:
630 mplEventHandling( evFullScreen
,0 );
633 mplEventHandling( guiCMDArray
[ (int)arg
- MP_CMD_GUI_EVENTS
- 1 ],0 );
637 mplEventHandling( evRedraw
,0 );
643 mixer_getvolume( mixer
,&l
,&r
);
644 guiIntfStruct
.Volume
=(r
>l
?r
:l
);
645 if ( r
!= l
) guiIntfStruct
.Balance
=( ( r
- l
) + 100 ) * 0.5f
;
646 else guiIntfStruct
.Balance
=50.0f
;
647 btnModify( evSetVolume
,guiIntfStruct
.Volume
);
648 btnModify( evSetBalance
,guiIntfStruct
.Balance
);
651 case guiSetFileFormat
:
652 guiIntfStruct
.FileFormat
=(int)arg
;
656 guiIntfStruct
.sh_video
=arg
;
659 sh_video_t
* sh
= (sh_video_t
*)arg
;
660 guiIntfStruct
.FPS
=sh
->fps
;
663 if ( guiIntfStruct
.NoWindow
) wsVisibleWindow( &appMPlayer
.subWindow
,wsHideWindow
);
665 if ( guiIntfStruct
.StreamType
== STREAMTYPE_STREAM
) btnSet( evSetMoviePosition
,btnDisabled
);
666 else btnSet( evSetMoviePosition
,btnReleased
);
672 mixer_getvolume( mixer
,&l
,&r
);
673 guiIntfStruct
.Volume
=(r
>l
?r
:l
);
674 if ( r
!= l
) guiIntfStruct
.Balance
=( ( r
- l
) + 100 ) * 0.5f
;
675 else guiIntfStruct
.Balance
=50.0f
;
676 btnModify( evSetVolume
,guiIntfStruct
.Volume
);
677 btnModify( evSetBalance
,guiIntfStruct
.Balance
);
680 if ( gtkEnableAudioEqualizer
)
687 eq
.channel
=i
; eq
.band
=j
; eq
.gain
=gtkEquChannels
[i
][j
];
688 gtkSet( gtkSetEqualizer
,0,&eq
);
693 if ( video_driver_list
&& !gstrcmp( video_driver_list
[0],"dxr3" ) && guiIntfStruct
.FileFormat
!= DEMUXER_TYPE_MPEG_PS
694 #ifdef USE_LIBAVCODEC
699 gtkMessageBox( GTK_MB_FATAL
,MSGTR_NEEDLAVC
);
700 guiIntfStruct
.Playing
=0;
706 // if ( guiIntfStruct.Playing == 1 && guiIntfStruct.FilenameChanged )
707 if ( guiIntfStruct
.FilenameChanged
)
713 stream_cache_size
=-1;
719 guiIntfStruct
.demuxer
=NULL
;
720 guiIntfStruct
.sh_video
=NULL
;
721 wsPostRedisplay( &appMPlayer
.subWindow
);
723 case guiSetParameters
:
724 guiGetEvent( guiSetDefaults
,NULL
);
725 switch ( guiIntfStruct
.StreamType
)
727 case STREAMTYPE_PLAYLIST
:
733 sprintf( tmp
,"vcd://%d",guiIntfStruct
.Track
+ 1 );
734 guiSetFilename( guiIntfStruct
.Filename
,tmp
);
742 sprintf( tmp
,"dvd://%d",guiIntfStruct
.Title
);
743 guiSetFilename( guiIntfStruct
.Filename
,tmp
);
745 dvd_chapter
=guiIntfStruct
.Chapter
;
746 dvd_angle
=guiIntfStruct
.Angle
;
750 //if ( guiIntfStruct.StreamType != STREAMTYPE_PLAYLIST ) // Does not make problems anymore!
752 if ( guiIntfStruct
.Filename
) filename
=gstrdup( guiIntfStruct
.Filename
);
753 else if ( filename
) guiSetFilename( guiIntfStruct
.Filename
,filename
);
757 if ( !video_driver_list
)
760 while ( video_out_drivers
[i
++] )
761 if ( video_out_drivers
[i
- 1]->control( VOCTRL_GUISUPPORT
,NULL
) == VO_TRUE
)
763 gaddlist( &video_driver_list
,(char *)video_out_drivers
[i
- 1]->info
->short_name
);
768 if ( !video_driver_list
&& !video_driver_list
[0] ) { gtkMessageBox( GTK_MB_FATAL
,MSGTR_IDFGCVD
); exit_player( "gui init" ); }
772 guiIntfStruct
.NoWindow
=False
;
773 while ( video_out_drivers
[i
++] )
774 if ( video_out_drivers
[i
- 1]->control( VOCTRL_GUISUPPORT
,NULL
) == VO_TRUE
)
776 if ( ( video_driver_list
&& !gstrcmp( video_driver_list
[0],(char *)video_out_drivers
[i
- 1]->info
->short_name
) )&&( video_out_drivers
[i
- 1]->control( VOCTRL_GUI_NOWINDOW
,NULL
) == VO_TRUE
) )
777 { guiIntfStruct
.NoWindow
=True
; break; }
782 #ifdef USE_LIBAVCODEC
785 if ( video_driver_list
&& !gstrcmp( video_driver_list
[0],"dxr3" ) )
787 if ( ( guiIntfStruct
.StreamType
!= STREAMTYPE_DVD
)&&( guiIntfStruct
.StreamType
!= STREAMTYPE_VCD
) )
789 #ifdef USE_LIBAVCODEC
790 if ( gtkVfLAVC
) add_vf( "lavc" );
796 if ( gtkVfPP
) add_vf( "pp" );
797 else remove_vf( "pp" );
800 // if ( ao_plugin_cfg.plugin_list ) { free( ao_plugin_cfg.plugin_list ); ao_plugin_cfg.plugin_list=NULL; }
802 greplace(&af_cfg
.list
, "volnorm", "volnorm");
803 if (gtkEnableAudioEqualizer
)
804 greplace(&af_cfg
.list
, "equalizer", "equalizer");
805 if ( gtkAOExtraStereo
)
807 char *name
= malloc(12 + 20 + 1);
808 snprintf(name
, 12 + 20, "extrastereo=%f", gtkAOExtraStereoMul
);
810 greplace(&af_cfg
.list
, "extrastereo", name
);
814 if ( audio_driver_list
&& !gstrncmp( audio_driver_list
[0],"oss",3 ) )
817 mixer_device
= gtkAOOSSMixer
;
818 mixer_channel
= gtkAOOSSMixerChannel
;
819 if (gtkAOOSSDevice
) {
820 tmp
= calloc( 1,strlen( gtkAOOSSDevice
) + 7 );
821 sprintf( tmp
,"oss:%s",gtkAOOSSDevice
);
824 gaddlist( &audio_driver_list
,tmp
);
828 #if defined(HAVE_ALSA9) || defined (HAVE_ALSA1X)
829 if ( audio_driver_list
&& !gstrncmp( audio_driver_list
[0],"alsa",4 ) )
832 mixer_device
= gtkAOALSAMixer
;
833 mixer_channel
= gtkAOALSAMixerChannel
;
834 if (gtkAOALSADevice
) {
835 tmp
= calloc( 1,strlen( gtkAOALSADevice
) + 14 );
836 sprintf( tmp
,"alsa:device=%s",gtkAOALSADevice
);
838 tmp
= strdup("alsa");
839 gaddlist( &audio_driver_list
,tmp
);
844 if ( audio_driver_list
&& !gstrncmp( audio_driver_list
[0],"sdl",3 ) )
847 if (gtkAOSDLDriver
) {
848 tmp
= calloc( 1,strlen( gtkAOSDLDriver
) + 10 );
849 sprintf( tmp
,"sdl:%s",gtkAOSDLDriver
);
852 gaddlist( &audio_driver_list
,tmp
);
857 if ( audio_driver_list
&& !gstrncmp( audio_driver_list
[0],"esd",3 ) )
860 if (gtkAOESDDevice
) {
861 tmp
= calloc( 1,strlen( gtkAOESDDevice
) + 10 );
862 sprintf( tmp
,"esd:%s",gtkAOESDDevice
);
865 gaddlist( &audio_driver_list
,tmp
);
870 //subdata->filename=gstrdup( guiIntfStruct.Subtitlename );
872 if ( gtkSubDumpMPSub
) stream_dump_type
=4;
873 if ( gtkSubDumpSrt
) stream_dump_type
=6;
874 gtkSubDumpMPSub
=gtkSubDumpSrt
=0;
878 if ( gtkCacheOn
) stream_cache_size
=gtkCacheSize
;
879 if ( gtkAutoSyncOn
) autosync
=gtkAutoSync
;
881 if ( guiIntfStruct
.AudioFile
) audio_stream
=gstrdup( guiIntfStruct
.AudioFile
);
882 else if ( guiIntfStruct
.FilenameChanged
) gfree( (void**)&audio_stream
);
885 guiIntfStruct
.DiskChanged
=0;
886 guiIntfStruct
.FilenameChanged
=0;
887 guiIntfStruct
.NewPlay
=0;
890 ass_enabled
= gtkASS
.enabled
;
891 ass_use_margins
= gtkASS
.use_margins
;
892 ass_top_margin
= gtkASS
.top_margin
;
893 ass_bottom_margin
= gtkASS
.bottom_margin
;
901 void guiEventHandling( void )
903 if ( !guiIntfStruct
.Playing
|| guiIntfStruct
.NoWindow
) wsHandleEvents();
909 float gtkEquChannels
[6][10];
911 plItem
* plCurrent
= NULL
;
912 plItem
* plList
= NULL
;
913 plItem
* plLastPlayed
= NULL
;
915 URLItem
*URLList
= NULL
;
917 char *fsHistory
[fsPersistant_MaxPos
] = { NULL
,NULL
,NULL
,NULL
,NULL
};
919 #if defined( MP_DEBUG ) && 0
922 plItem
* next
= plList
;
923 printf( "--- list ---\n" );
924 while( next
|| next
->next
)
926 printf( "item: %s/%s\n",next
->path
,next
->name
);
927 if ( next
->next
) next
=next
->next
; else break;
929 printf( "--- end of list ---\n" );
935 void * gtkSet( int cmd
,float fparam
, void * vparam
)
937 equalizer_t
* eq
= (equalizer_t
*)vparam
;
938 plItem
* item
= (plItem
*)vparam
;
940 URLItem
* url_item
= (URLItem
*)vparam
;
945 // --- handle playlist
946 case gtkAddPlItem
: // add item to playlist
949 plItem
* next
= plList
;
950 while ( next
->next
) { /*printf( "%s\n",next->name );*/ next
=next
->next
; }
951 next
->next
=item
; item
->prev
=next
;
952 } else { item
->prev
=item
->next
=NULL
; plCurrent
=plList
=item
; }
955 case gtkInsertPlItem
: // add item into playlist after current
958 plItem
* curr
= plCurrent
;
959 item
->next
=curr
->next
;
961 item
->next
->prev
=item
;
964 plCurrent
=plCurrent
->next
;
968 return gtkSet(gtkAddPlItem
,0,(void*)item
);
970 case gtkGetNextPlItem
: // get current item from playlist
971 if ( plCurrent
&& plCurrent
->next
)
973 plCurrent
=plCurrent
->next
;
974 /*if ( !plCurrent && plList )
976 plItem * next = plList;
977 while ( next->next ) { if ( !next->next ) break; next=next->next; }
983 case gtkGetPrevPlItem
:
984 if ( plCurrent
&& plCurrent
->prev
)
986 plCurrent
=plCurrent
->prev
;
987 //if ( !plCurrent && plList ) plCurrent=plList;
991 case gtkSetCurrPlItem
: // set current item
994 case gtkGetCurrPlItem
: // get current item
996 case gtkDelCurrPlItem
: // delete current item
998 plItem
* curr
= plCurrent
;
1003 curr
->prev
->next
=curr
->next
;
1005 curr
->next
->prev
=curr
->prev
;
1008 plCurrent
=curr
->next
;
1010 if ( curr
->path
) free( curr
->path
);
1011 if ( curr
->name
) free( curr
->name
);
1014 mplCurr(); // Instead of using mplNext && mplPrev
1017 case gtkDelPl
: // delete list
1019 plItem
* curr
= plList
;
1021 if ( !plList
) return NULL
;
1024 if ( curr
->path
) free( curr
->path
);
1025 if ( curr
->name
) free( curr
->name
);
1030 while ( curr
->next
)
1033 if ( curr
->path
) free( curr
->path
);
1034 if ( curr
->name
) free( curr
->name
);
1039 plList
=NULL
; plCurrent
=NULL
;
1046 URLItem
* next_url
= URLList
;
1048 while ( next_url
->next
)
1050 if ( !gstrcmp( next_url
->url
,url_item
->url
) )
1055 next_url
=next_url
->next
;
1057 if ( ( !is_added
)&&( gstrcmp( next_url
->url
,url_item
->url
) ) ) next_url
->next
=url_item
;
1058 } else { url_item
->next
=NULL
; URLList
=url_item
; }
1061 #ifndef HAVE_FREETYPE
1062 case gtkSetFontFactor
:
1067 case gtkSetFontOutLine
:
1068 subtitle_font_thickness
=( 8.0f
/ 100.0f
) * fparam
;
1071 case gtkSetFontBlur
:
1072 subtitle_font_radius
=( 8.0f
/ 100.0f
) * fparam
;
1075 case gtkSetFontTextScale
:
1076 text_font_scale_factor
=fparam
;
1079 case gtkSetFontOSDScale
:
1080 osd_font_scale_factor
=fparam
;
1083 case gtkSetFontEncoding
:
1084 gfree( (void **)&subtitle_font_encoding
);
1085 subtitle_font_encoding
=gstrdup( (char *)vparam
);
1088 case gtkSetFontAutoScale
:
1089 subtitle_autoscale
=(int)fparam
;
1094 case gtkSetSubEncoding
:
1095 gfree( (void **)&sub_cp
);
1096 sub_cp
=gstrdup( (char *)vparam
);
1100 case gtkClearStruct
:
1101 if ( (unsigned int)vparam
& guiFilenames
)
1103 gfree( (void **)&guiIntfStruct
.Filename
);
1104 gfree( (void **)&guiIntfStruct
.Subtitlename
);
1105 gfree( (void **)&guiIntfStruct
.AudioFile
);
1106 gtkSet( gtkDelPl
,0,NULL
);
1109 if ( (unsigned int)vparam
& guiDVD
) memset( &guiIntfStruct
.DVD
,0,sizeof( guiDVDStruct
) );
1112 if ( (unsigned int)vparam
& guiVCD
) guiIntfStruct
.VCDTracks
=0;
1115 case gtkSetExtraStereo
:
1116 gtkAOExtraStereoMul
=fparam
;
1117 if (guiIntfStruct
.afilter
)
1118 af_control_any_rev(guiIntfStruct
.afilter
,
1119 AF_CONTROL_ES_MUL
| AF_CONTROL_SET
, >kAOExtraStereoMul
);
1124 mp_cmd
=calloc( 1,sizeof( *mp_cmd
) );
1125 mp_cmd
->id
=MP_CMD_PANSCAN
; mp_cmd
->name
=strdup( "panscan" );
1126 mp_cmd
->args
[0].v
.f
=fparam
; mp_cmd
->args
[1].v
.i
=1;
1127 mp_input_queue_cmd( mp_cmd
);
1131 auto_quality
=(int)fparam
;
1133 // --- set equalizers
1134 case gtkSetContrast
:
1135 if ( guiIntfStruct
.sh_video
) set_video_colors( guiIntfStruct
.sh_video
,"contrast",(int)fparam
);
1137 case gtkSetBrightness
:
1138 if ( guiIntfStruct
.sh_video
) set_video_colors( guiIntfStruct
.sh_video
,"brightness",(int)fparam
);
1141 if ( guiIntfStruct
.sh_video
) set_video_colors( guiIntfStruct
.sh_video
,"hue",(int)fparam
);
1143 case gtkSetSaturation
:
1144 if ( guiIntfStruct
.sh_video
) set_video_colors( guiIntfStruct
.sh_video
,"saturation",(int)fparam
);
1146 case gtkSetEqualizer
:
1148 af_control_ext_t tmp
;
1151 gtkEquChannels
[eq
->channel
][eq
->band
]=eq
->gain
;
1152 tmp
.ch
= eq
->channel
;
1153 tmp
.arg
= gtkEquChannels
[eq
->channel
];
1154 if (guiIntfStruct
.afilter
)
1155 af_control_any_rev(guiIntfStruct
.afilter
,
1156 AF_CONTROL_EQUALIZER_GAIN
| AF_CONTROL_SET
, &tmp
);
1161 memset( gtkEquChannels
,0,sizeof( gtkEquChannels
) );
1162 if (guiIntfStruct
.afilter
)
1166 tmp
.arg
= gtkEquChannels
[i
];
1167 af_control_any_rev(guiIntfStruct
.afilter
,
1168 AF_CONTROL_EQUALIZER_GAIN
| AF_CONTROL_SET
, &tmp
);
1177 #define mp_basename(s) (strrchr(s,'/')==NULL?(char*)s:(strrchr(s,'/')+1))
1179 #include "playtree.h"
1181 //This function adds/inserts one file into the gui playlist
1183 int import_file_into_gui(char* temp
, int insert
)
1185 char *filename
, *pathname
;
1188 filename
= strdup(mp_basename(temp
));
1189 pathname
= strdup(temp
);
1190 if (strlen(pathname
)-strlen(filename
)>0)
1191 pathname
[strlen(pathname
)-strlen(filename
)-1]='\0'; // We have some path so remove / at end
1193 pathname
[strlen(pathname
)-strlen(filename
)]='\0';
1194 mp_msg(MSGT_PLAYTREE
,MSGL_V
, "Adding filename %s && pathname %s\n",filename
,pathname
); //FIXME: Change to MSGL_DBG2 ?
1195 item
=calloc( 1,sizeof( plItem
) );
1198 item
->name
=filename
;
1199 item
->path
=pathname
;
1201 gtkSet( gtkInsertPlItem
,0,(void*)item
); // Inserts the item after current, and makes current=item
1203 gtkSet( gtkAddPlItem
,0,(void*)item
);
1208 // This function imports the initial playtree (based on cmd-line files) into the gui playlist
1210 // - overwriting gui pl (enqueue=0)
1211 // - appending it to gui pl (enqueue=1)
1213 int import_initial_playtree_into_gui(play_tree_t
* my_playtree
, m_config_t
* config
, int enqueue
)
1215 play_tree_iter_t
* my_pt_iter
=NULL
;
1218 if (!enqueue
) // Delete playlist before "appending"
1219 gtkSet(gtkDelPl
,0,0);
1221 if((my_pt_iter
=pt_iter_create(&my_playtree
,config
)))
1223 while ((filename
=pt_iter_get_next_file(my_pt_iter
))!=NULL
)
1225 if (import_file_into_gui(filename
, 0)) // Add it to end of list
1230 mplCurr(); // Update filename
1234 filename
=guiIntfStruct
.Filename
; // Backward compatibility; if file is specified on commandline,
1235 // gmplayer does directly start in Play-Mode.
1242 // This function imports and inserts an playtree, that is created "on the fly", for example by
1243 // parsing some MOV-Reference-File; or by loading an playlist with "File Open"
1245 // The file which contained the playlist is thereby replaced with it's contents.
1247 int import_playtree_playlist_into_gui(play_tree_t
* my_playtree
, m_config_t
* config
)
1249 play_tree_iter_t
* my_pt_iter
=NULL
;
1251 plItem
* save
=(plItem
*)gtkSet( gtkGetCurrPlItem
, 0, 0); // Save current item
1253 if((my_pt_iter
=pt_iter_create(&my_playtree
,config
)))
1255 while ((filename
=pt_iter_get_next_file(my_pt_iter
))!=NULL
)
1257 if (import_file_into_gui(filename
, 1)) // insert it into the list and set plCurrent=new item
1260 pt_iter_destroy(&my_pt_iter
);
1264 gtkSet(gtkSetCurrPlItem
, 0, (void*)save
);
1266 gtkSet(gtkSetCurrPlItem
, 0, (void*)plList
); // go to head, if plList was empty before
1269 gtkSet(gtkDelCurrPlItem
, 0, 0);
1271 mplCurr(); // Update filename
1277 // wrapper function for mp_msg to display a message box for errors and warnings.
1279 void guiMessageBox(int level
, char * str
) {
1282 gtkMessageBox(GTK_MB_FATAL
|GTK_MB_SIMPLE
, str
);
1285 gtkMessageBox(GTK_MB_ERROR
|GTK_MB_SIMPLE
, str
);
1288 // WARNING! Do NOT enable this! There are too many non-critical messages with
1289 // MSGL_WARN, for example: broken SPU packets, codec's bit error messages,
1290 // etc etc, they should not raise up a new window every time.
1292 gtkMessageBox(GTK_MB_WARNING
|GTK_MB_SIMPLE
, str
);