10l fix by Jindrich Makovicka
[mplayer/greg.git] / Gui / interface.c
blobeeaf75d544fa9745d0948827662c457c024b33da
2 #include <inttypes.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <sys/types.h>
8 #include "wm/ws.h"
9 #include "wm/wsxdnd.h"
10 #include "interface.h"
11 #include "skin/skin.h"
13 #include "mplayer/gtk/eq.h"
14 #include "mplayer/widgets.h"
15 #include "mplayer/mplayer.h"
16 #include "mplayer/play.h"
18 #include "../mplayer.h"
19 #include "app.h"
20 #include "cfg.h"
21 #include "../help_mp.h"
22 #include "../subreader.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"
29 #include "../mixer.h"
30 #include "../libao2/audio_plugin.h"
31 #include "../libao2/eq.h"
33 #ifdef USE_ICONV
34 #include <iconv.h>
35 #endif
37 #include "../libmpdemux/stream.h"
38 #include "../libmpdemux/demuxer.h"
39 #include "../libmpdemux/stheader.h"
40 #include "../libmpcodecs/dec_video.h"
42 #include "../m_config.h"
43 #include "../m_option.h"
45 guiInterface_t guiIntfStruct;
46 int guiWinID=-1;
48 char * gstrcat( char ** dest,char * src )
50 char * tmp = NULL;
52 if ( !src ) return NULL;
54 if ( *dest )
56 tmp=malloc( strlen( *dest ) + strlen( src ) + 1 );
57 strcpy( tmp,*dest ); strcat( tmp,src ); free( *dest );
59 else
60 { tmp=malloc( strlen( src ) + 1 ); strcpy( tmp,src ); }
61 *dest=tmp;
62 return tmp;
65 int gstrcmp( char * a,char * b )
67 if ( !a && !b ) return 0;
68 if ( !a || !b ) return -1;
69 return strcmp( a,b );
72 int gstrncmp( char * a,char * b,int size )
74 if ( !a && !b ) return 0;
75 if ( !a || !b ) return -1;
76 return strncmp( a,b,size );
79 char * gstrdup( char * str )
81 if ( !str ) return NULL;
82 return strdup( str );
85 char * gstrchr( char * str,int c )
87 if ( !str ) return NULL;
88 return strchr( str,c );
91 void gfree( void ** p )
93 if ( *p == NULL ) return;
94 free( *p ); *p=NULL;
97 void gset( char ** str,char * what )
99 if ( *str ) { if ( !strstr( *str,what ) ) { gstrcat( str,"," ); gstrcat( str,what ); }}
100 else gstrcat( str,what );
103 void gaddlist( char *** list,char * entry )
105 int i;
107 if ( (*list) )
109 for ( i=0;(*list)[i];i++ ) free( (*list)[i] );
110 free( (*list) );
113 (*list)=malloc( 8 );
114 (*list)[0]=gstrdup( entry );
115 (*list)[1]=NULL;
118 #ifdef USE_ICONV
119 char * gconvert_uri_to_filename( char * str )
121 iconv_t d;
122 char * out = strdup( str );
123 char * tmp = NULL;
124 char * ize;
125 size_t inb,outb;
126 char * charset = "ISO8859-1";
127 char * cs;
129 if ( !strchr( str,'%' ) ) return str;
132 char * t = calloc( 1,strlen( out ) );
133 int i,c = 0;
134 for ( i=0;i < (int)strlen( out );i++ )
135 if ( out[i] != '%' ) t[c++]=out[i];
136 else
138 char tmp[4] = "0xXX";
139 // if ( out[++i] == '%' ) { t[c++]='%'; continue; };
140 tmp[2]=out[++i]; tmp[3]=out[++i];
141 t[c++]=(char)strtol( tmp,(char **)NULL,0 );
143 free( out );
144 out=t;
147 if ( (cs=getenv( "CHARSET" )) && *cs ) charset=cs;
149 inb=outb=strlen( out );
150 tmp=calloc( 1,outb + 1 );
151 ize=tmp;
152 d=iconv_open( charset,"UTF-8" );
153 if ( (iconv_t)(-1) == d ) return str;
154 iconv( d,&out,&inb,&tmp,&outb );
155 iconv_close( d );
156 free( out );
157 return ize;
159 #endif
161 void guiInit( void )
163 int i;
165 memset( &guiIntfStruct,0,sizeof( guiIntfStruct ) );
166 guiIntfStruct.Balance=50.0f;
167 guiIntfStruct.StreamType=-1;
169 memset( &gtkEquChannels,0,sizeof( gtkEquChannels ) );
170 #ifdef USE_OSS_AUDIO
171 if ( !gtkAOOSSMixer ) gtkAOOSSMixer=strdup( PATH_DEV_MIXER );
172 if ( !gtkAOOSSDevice ) gtkAOOSSDevice=strdup( PATH_DEV_DSP );
173 #endif
174 #ifdef HAVE_DXR3
175 if ( !gtkDXR3Device ) gtkDXR3Device=strdup( "/dev/em8300-0" );
176 #endif
177 if ( stream_cache_size != -1 ) { gtkCacheOn=1; gtkCacheSize=stream_cache_size; }
178 if ( autosync && autosync != gtkAutoSync ) { gtkAutoSyncOn=1; gtkAutoSync=autosync; }
180 gtkInit();
181 // --- initialize X
182 wsXInit( (void *)mDisplay );
183 // --- load skin
184 skinDirInHome=get_path("Skin");
185 skinMPlayerDir=MPLAYER_DATADIR "/Skin";
186 printf("SKIN dir 1: '%s'\n",skinDirInHome);
187 printf("SKIN dir 2: '%s'\n",skinMPlayerDir);
188 if ( !skinName ) skinName=strdup( "default" );
189 i = skinRead( skinName );
190 if ((i == -1) && strcmp(skinName,"default"))
192 mp_msg( MSGT_GPLAYER,MSGL_INFO,"Selected skin ( %s ) not found, trying 'default'...\n", skinName);
193 skinName=strdup( "default" );
194 i = skinRead( skinName );
196 switch (i) {
197 case -1: mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_SKIN_SKINCFG_SkinNotFound,skinName ); exit( 0 );
198 case -2: mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_SKIN_SKINCFG_SkinCfgReadError,skinName ); exit( 0 );
200 // --- initialize windows
201 if ( ( mplDrawBuffer = (unsigned char *)malloc( appMPlayer.main.Bitmap.ImageSize ) ) == NULL )
203 fprintf( stderr,MSGTR_NEMDB );
204 exit( 0 );
207 if ( gui_save_pos )
209 appMPlayer.main.x = gui_main_pos_x;
210 appMPlayer.main.y = gui_main_pos_y;
211 appMPlayer.sub.x = gui_sub_pos_x;
212 appMPlayer.sub.y = gui_sub_pos_y;
215 if (WinID>0)
217 appMPlayer.subWindow.Parent=WinID;
218 appMPlayer.sub.x=0;
219 appMPlayer.sub.y=0;
221 if (guiWinID>=0) appMPlayer.mainWindow.Parent=guiWinID;
223 wsCreateWindow( &appMPlayer.subWindow,
224 appMPlayer.sub.x,appMPlayer.sub.y,appMPlayer.sub.width,appMPlayer.sub.height,
225 wsNoBorder,wsShowMouseCursor|wsHandleMouseButton|wsHandleMouseMove,wsShowFrame|wsHideWindow,"MPlayer - Video" );
227 wsDestroyImage( &appMPlayer.subWindow );
228 wsCreateImage( &appMPlayer.subWindow,appMPlayer.sub.Bitmap.Width,appMPlayer.sub.Bitmap.Height );
229 wsXDNDMakeAwareness(&appMPlayer.subWindow);
231 mplMenuInit();
232 mplPBInit();
234 vo_setwindow( appMPlayer.subWindow.WindowID, appMPlayer.subWindow.wGC );
236 // i=wsHideFrame|wsMaxSize|wsHideWindow;
237 // if ( appMPlayer.mainDecoration ) i=wsShowFrame|wsMaxSize|wsHideWindow;
238 i=wsShowFrame|wsMaxSize|wsHideWindow;
239 wsCreateWindow( &appMPlayer.mainWindow,
240 appMPlayer.main.x,appMPlayer.main.y,appMPlayer.main.width,appMPlayer.main.height,
241 wsNoBorder,wsShowMouseCursor|wsHandleMouseButton|wsHandleMouseMove,i,"MPlayer" );
243 wsSetShape( &appMPlayer.mainWindow,appMPlayer.main.Mask.Image );
244 wsXDNDMakeAwareness(&appMPlayer.mainWindow);
246 #ifdef DEBUG
247 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] Depth on screen: %d\n",wsDepthOnScreen );
248 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] parent: 0x%x\n",(int)appMPlayer.mainWindow.WindowID );
249 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] sub: 0x%x\n",(int)appMPlayer.subWindow.WindowID );
250 #endif
252 appMPlayer.mainWindow.ReDraw=(void *)mplMainDraw;
253 appMPlayer.mainWindow.MouseHandler=mplMainMouseHandle;
254 appMPlayer.mainWindow.KeyHandler=mplMainKeyHandle;
255 appMPlayer.mainWindow.DandDHandler=mplDandDHandler;
257 appMPlayer.subWindow.ReDraw=(void *)mplSubDraw;
258 appMPlayer.subWindow.MouseHandler=mplSubMouseHandle;
259 appMPlayer.subWindow.KeyHandler=mplMainKeyHandle;
260 appMPlayer.subWindow.DandDHandler=mplDandDHandler;
262 wsSetBackgroundRGB( &appMPlayer.subWindow,appMPlayer.sub.R,appMPlayer.sub.G,appMPlayer.sub.B );
263 wsClearWindow( appMPlayer.subWindow );
264 if ( appMPlayer.sub.Bitmap.Image ) wsConvert( &appMPlayer.subWindow,appMPlayer.sub.Bitmap.Image,appMPlayer.sub.Bitmap.ImageSize );
266 btnModify( evSetVolume,guiIntfStruct.Volume );
267 btnModify( evSetBalance,guiIntfStruct.Balance );
268 btnModify( evSetMoviePosition,guiIntfStruct.Position );
270 wsSetIcon( wsDisplay,appMPlayer.mainWindow.WindowID,guiIcon,guiIconMask );
271 wsSetIcon( wsDisplay,appMPlayer.subWindow.WindowID,guiIcon,guiIconMask );
273 guiIntfStruct.Playing=0;
275 if ( !appMPlayer.mainDecoration ) wsWindowDecoration( &appMPlayer.mainWindow,0 );
277 wsVisibleWindow( &appMPlayer.mainWindow,wsShowWindow );
278 #if 0
279 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow );
282 XEvent xev;
283 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID );
284 appMPlayer.subWindow.Mapped=wsMapped;
287 if ( !fullscreen ) fullscreen=gtkLoadFullscreen;
288 if ( fullscreen )
290 mplFullScreen();
291 btnModify( evFullScreen,btnPressed );
293 #else
294 if ( !fullscreen ) fullscreen=gtkLoadFullscreen;
295 if ( gtkShowVideoWindow )
297 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow );
299 XEvent xev;
300 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID );
301 appMPlayer.subWindow.Mapped=wsMapped;
304 if ( fullscreen )
306 mplFullScreen();
307 btnModify( evFullScreen,btnPressed );
310 else
312 if ( fullscreen )
314 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow );
316 XEvent xev;
317 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID );
318 appMPlayer.subWindow.Mapped=wsMapped;
320 wsVisibleWindow( &appMPlayer.subWindow, wsShowWindow );
322 mplFullScreen();
323 btnModify( evFullScreen,btnPressed );
326 #endif
327 mplSubRender=1;
328 // ---
330 if ( filename ) mplSetFileName( NULL,filename,STREAMTYPE_FILE );
331 if ( plCurrent && !filename ) mplSetFileName( plCurrent->path,plCurrent->name,STREAMTYPE_FILE );
332 if ( subdata ) guiSetFilename( guiIntfStruct.Subtitlename, subdata->filename );
333 #if defined( USE_OSD ) || defined( USE_SUB )
334 guiLoadFont();
335 #endif
338 void guiDone( void )
340 mplMainRender=0;
341 mp_msg( MSGT_GPLAYER,MSGL_V,"[gui] done.\n" );
343 if ( gui_save_pos )
345 gui_main_pos_x=appMPlayer.mainWindow.X; gui_main_pos_y=appMPlayer.mainWindow.Y;
346 gui_sub_pos_x=appMPlayer.subWindow.X; gui_sub_pos_y=appMPlayer.subWindow.Y;
349 cfg_write();
350 wsXDone();
353 int guiCMDArray[] =
355 evLoadPlay,
356 evLoadSubtitle,
357 evAbout,
358 evPlay,
359 evStop,
360 evPlayList,
361 evPreferences,
362 evFullScreen,
363 evSkinBrowser
366 extern ao_functions_t * audio_out;
367 extern vo_functions_t * video_out;
368 extern int frame_dropping;
369 extern int stream_dump_type;
370 extern int vcd_track;
371 extern m_obj_settings_t*vo_plugin_args;
373 #if defined( USE_OSD ) || defined( USE_SUB )
374 void guiLoadFont( void )
376 #ifdef HAVE_FREETYPE
377 load_font_ft(vo_image_width, vo_image_height);
378 #else
379 if ( vo_font )
381 int i;
382 if ( vo_font->name ) free( vo_font->name );
383 if ( vo_font->fpath ) free( vo_font->fpath );
384 for ( i=0;i<16;i++ )
385 if ( vo_font->pic_a[i] )
387 if ( vo_font->pic_a[i]->bmp ) free( vo_font->pic_a[i]->bmp );
388 if ( vo_font->pic_a[i]->pal ) free( vo_font->pic_a[i]->pal );
390 for ( i=0;i<16;i++ )
391 if ( vo_font->pic_b[i] )
393 if ( vo_font->pic_b[i]->bmp ) free( vo_font->pic_b[i]->bmp );
394 if ( vo_font->pic_b[i]->pal ) free( vo_font->pic_b[i]->pal );
396 free( vo_font ); vo_font=NULL;
398 if ( font_name )
400 vo_font=read_font_desc( font_name,font_factor,0 );
401 if ( !vo_font ) mp_msg( MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadFont,font_name );
403 else
405 font_name=gstrdup( get_path( "font/font.desc" ) );
406 vo_font=read_font_desc( font_name,font_factor,0 );
407 if ( !vo_font )
409 gfree( (void **)&font_name ); font_name=gstrdup(MPLAYER_DATADIR "/font/font.desc" );
410 vo_font=read_font_desc( font_name,font_factor,0 );
413 #endif
415 #endif
417 #ifdef USE_SUB
418 extern mp_osd_obj_t* vo_osd_list;
420 extern char **sub_name;
422 void guiLoadSubtitle( char * name )
424 if ( guiIntfStruct.Playing == 0 )
426 guiIntfStruct.SubtitleChanged=1; //what is this for? (mw)
427 return;
429 if ( subdata )
431 mp_msg( MSGT_GPLAYER,MSGL_INFO,"[gui] Delete subtitles.\n" );
432 sub_free( subdata );
433 subdata=NULL;
434 vo_sub=NULL;
435 if ( vo_osd_list )
437 int len;
438 mp_osd_obj_t * osd = vo_osd_list;
439 while ( osd )
441 if ( osd->type == OSDTYPE_SUBTITLE ) break;
442 osd=osd->next;
444 if ( osd && osd->flags&OSDFLAG_VISIBLE )
446 len=osd->stride * ( osd->bbox.y2 - osd->bbox.y1 );
447 memset( osd->bitmap_buffer,0,len );
448 memset( osd->alpha_buffer,0,len );
452 if ( name )
454 mp_msg( MSGT_GPLAYER,MSGL_INFO,"[gui] Load subtitle: %s\n",name );
455 subdata=sub_read_file( gstrdup( name ), guiIntfStruct.FPS );
456 if ( !subdata ) mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_CantLoadSub,name );
457 sub_name = (malloc(2 * sizeof(char*))); //when mplayer will be restarted
458 sub_name[0] = strdup(name); //sub_name[0] will be read
459 sub_name[1] = NULL;
461 update_set_of_subtitles();
464 #endif
466 static void add_vop( char * str )
468 mp_msg( MSGT_GPLAYER,MSGL_STATUS,"[gui] add video filter: %s\n",str );
469 if ( vo_plugin_args )
471 int i = 0;
472 while ( vo_plugin_args[i].name ) if ( !gstrcmp( vo_plugin_args[i++].name,str ) ) { i=-1; break; }
473 if ( i != -1 )
474 { vo_plugin_args=realloc( vo_plugin_args,( i + 2 ) * sizeof( m_obj_settings_t ) ); vo_plugin_args[i].name=strdup( str );vo_plugin_args[i].attribs = NULL; vo_plugin_args[i+1].name=NULL; }
475 } else { vo_plugin_args=malloc( 2 * sizeof( m_obj_settings_t ) ); vo_plugin_args[0].name=strdup( str );vo_plugin_args[0].attribs = NULL; vo_plugin_args[1].name=NULL; }
478 static void remove_vop( char * str )
480 int n = 0;
482 if ( !vo_plugin_args ) return;
484 mp_msg( MSGT_GPLAYER,MSGL_STATUS,"[gui] remove video filter: %s\n",str );
486 while ( vo_plugin_args[n++].name ); n--;
487 if ( n > -1 )
489 int i = 0,m = -1;
490 while ( vo_plugin_args[i].name ) if ( !gstrcmp( vo_plugin_args[i++].name,str ) ) { m=i - 1; break; }
491 i--;
492 if ( m > -1 )
494 if ( n == 1 ) { free( vo_plugin_args[0].name );free( vo_plugin_args[0].attribs ); free( vo_plugin_args ); vo_plugin_args=NULL; }
495 else { free( vo_plugin_args[i].name );free( vo_plugin_args[i].attribs ); memcpy( &vo_plugin_args[i],&vo_plugin_args[i + 1],( n - i ) * sizeof( m_obj_settings_t ) ); }
500 int guiGetEvent( int type,char * arg )
502 stream_t * stream = (stream_t *) arg;
503 #ifdef USE_DVDREAD
504 dvd_priv_t * dvdp = (dvd_priv_t *) arg;
505 #endif
507 switch ( type )
509 case guiXEvent:
510 guiIntfStruct.event_struct=(void *)arg;
511 wsEvents( wsDisplay,(XEvent *)arg,NULL );
512 gtkEventHandling();
513 break;
514 case guiCEvent:
515 switch ( (int)arg )
517 case guiSetPlay:
518 guiIntfStruct.Playing=1;
519 if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow );
520 break;
521 case guiSetStop:
522 guiIntfStruct.Playing=0;
523 if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow );
524 break;
525 case guiSetPause: guiIntfStruct.Playing=2; break;
527 mplState();
528 break;
529 case guiSetState:
530 mplState();
531 break;
532 case guiSetFileName:
533 if ( arg ) guiSetFilename( guiIntfStruct.Filename,arg );
534 break;
535 case guiSetAudioOnly:
536 guiIntfStruct.AudioOnly=(int)arg;
537 if ( (int)arg ) { guiIntfStruct.NoWindow=True; wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow ); }
538 else wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow );
539 break;
540 case guiSetDemuxer:
541 guiIntfStruct.demuxer=(void *)arg;
542 break;
543 case guiSetShVideo:
545 if ( !appMPlayer.subWindow.isFullScreen )
547 wsResizeWindow( &appMPlayer.subWindow,vo_dwidth,vo_dheight );
548 wsMoveWindow( &appMPlayer.subWindow,True,appMPlayer.sub.x,appMPlayer.sub.y );
550 guiIntfStruct.MovieWidth=vo_dwidth;
551 guiIntfStruct.MovieHeight=vo_dheight;
552 if (guiWinID>=0)
553 wsMoveWindow( &appMPlayer.mainWindow,0,0, vo_dheight);
555 break;
556 #ifdef USE_DVDREAD
557 case guiSetDVD:
558 guiIntfStruct.DVD.titles=dvdp->vmg_file->tt_srpt->nr_of_srpts;
559 guiIntfStruct.DVD.chapters=dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_ptts;
560 guiIntfStruct.DVD.angles=dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_angles;
561 guiIntfStruct.DVD.nr_of_audio_channels=dvdp->nr_of_channels;
562 memcpy( guiIntfStruct.DVD.audio_streams,dvdp->audio_streams,sizeof( dvdp->audio_streams ) );
563 guiIntfStruct.DVD.nr_of_subtitles=dvdp->nr_of_subtitles;
564 memcpy( guiIntfStruct.DVD.subtitles,dvdp->subtitles,sizeof( dvdp->subtitles ) );
565 guiIntfStruct.DVD.current_title=dvd_title + 1;
566 guiIntfStruct.DVD.current_chapter=dvd_chapter + 1;
567 guiIntfStruct.DVD.current_angle=dvd_angle + 1;
568 guiIntfStruct.Track=dvd_title + 1;
569 break;
570 #endif
571 case guiSetStream:
572 guiIntfStruct.StreamType=stream->type;
573 switch( stream->type )
575 #ifdef USE_DVDREAD
576 case STREAMTYPE_DVD:
577 guiGetEvent( guiSetDVD,(char *)stream->priv );
578 break;
579 #endif
580 #ifdef HAVE_VCD
581 case STREAMTYPE_VCD:
583 int i;
585 if (!stream->priv)
587 guiIntfStruct.VCDTracks=0;
588 break;
590 for ( i=1;i < 100;i++ )
591 if ( vcd_seek_to_track( stream->priv,i ) < 0 ) break;
592 vcd_seek_to_track( stream->priv,vcd_track );
593 guiIntfStruct.VCDTracks=--i;
594 break;
596 #endif
597 default: break;
599 break;
600 case guiIEvent:
601 printf( "cmd: %d\n",(int)arg );
602 switch( (int)arg )
604 case MP_CMD_QUIT:
605 mplEventHandling( evExit,0 );
606 break;
607 case MP_CMD_VO_FULLSCREEN:
608 mplEventHandling( evFullScreen,0 );
609 break;
610 default:
611 mplEventHandling( guiCMDArray[ (int)arg - MP_CMD_GUI_EVENTS - 1 ],0 );
613 break;
614 case guiReDraw:
615 mplEventHandling( evRedraw,0 );
616 break;
617 case guiSetVolume:
618 if ( audio_out )
620 float l,r;
621 mixer_getvolume( &l,&r );
622 guiIntfStruct.Volume=(r>l?r:l);
623 if ( r != l ) guiIntfStruct.Balance=( ( r - l ) + 100 ) * 0.5f;
624 else guiIntfStruct.Balance=50.0f;
625 btnModify( evSetVolume,guiIntfStruct.Volume );
626 btnModify( evSetBalance,guiIntfStruct.Balance );
628 break;
629 case guiSetFileFormat:
630 guiIntfStruct.FileFormat=(int)arg;
631 break;
632 case guiSetValues:
633 // -- video
634 guiIntfStruct.sh_video=arg;
635 if ( arg )
637 sh_video_t * sh = (sh_video_t *)arg;
638 guiIntfStruct.FPS=sh->fps;
641 if ( guiIntfStruct.NoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow );
643 if ( guiIntfStruct.StreamType == STREAMTYPE_STREAM ) btnSet( evSetMoviePosition,btnDisabled );
644 else btnSet( evSetMoviePosition,btnReleased );
646 // -- audio
647 if ( audio_out )
649 float l,r;
650 mixer_getvolume( &l,&r );
651 guiIntfStruct.Volume=(r>l?r:l);
652 if ( r != l ) guiIntfStruct.Balance=( ( r - l ) + 100 ) * 0.5f;
653 else guiIntfStruct.Balance=50.0f;
654 btnModify( evSetVolume,guiIntfStruct.Volume );
655 btnModify( evSetBalance,guiIntfStruct.Balance );
658 if ( gtkEnableAudioEqualizer )
660 equalizer_t eq;
661 int i,j;
662 for ( i=0;i<6;i++ )
663 for ( j=0;j<10;j++ )
665 eq.channel=i; eq.band=j; eq.gain=gtkEquChannels[i][j];
666 gtkSet( gtkSetEqualizer,0,&eq );
669 // -- subtitle
670 #ifdef HAVE_DXR3
671 if ( video_driver_list && !gstrcmp( video_driver_list[0],"dxr3" ) && guiIntfStruct.FileFormat != DEMUXER_TYPE_MPEG_PS
672 #ifdef USE_LIBAVCODEC
673 && !gtkVopLAVC
674 #endif
675 #ifdef USE_LIBFAME
676 && !gtkVopFAME
677 #endif
680 gtkMessageBox( GTK_MB_FATAL,MSGTR_NEEDLAVCFAME );
681 guiIntfStruct.Playing=0;
682 return True;
684 #endif
685 break;
686 case guiSetDefaults:
687 // if ( guiIntfStruct.Playing == 1 && guiIntfStruct.FilenameChanged )
688 if ( guiIntfStruct.FilenameChanged )
690 audio_id=-1;
691 video_id=-1;
692 dvdsub_id=-1;
693 vobsub_id=-1;
694 stream_cache_size=-1;
695 autosync=0;
696 vcd_track=0;
697 dvd_title=0;
698 force_fps=0;
700 wsPostRedisplay( &appMPlayer.subWindow );
701 break;
702 case guiSetParameters:
703 guiGetEvent( guiSetDefaults,NULL );
704 switch ( guiIntfStruct.StreamType )
706 case STREAMTYPE_PLAYLIST:
707 break;
708 #ifdef HAVE_VCD
709 case STREAMTYPE_VCD:
711 char tmp[512];
712 sprintf( tmp,"vcd://%d",guiIntfStruct.Track + 1 );
713 guiSetFilename( guiIntfStruct.Filename,tmp );
715 break;
716 #endif
717 #ifdef USE_DVDREAD
718 case STREAMTYPE_DVD:
720 char tmp[512];
721 sprintf( tmp,"dvd://%d",guiIntfStruct.Title );
722 guiSetFilename( guiIntfStruct.Filename,tmp );
724 dvd_chapter=guiIntfStruct.Chapter;
725 dvd_angle=guiIntfStruct.Angle;
726 break;
727 #endif
729 //if ( guiIntfStruct.StreamType != STREAMTYPE_PLAYLIST ) // Does not make problems anymore!
731 if ( guiIntfStruct.Filename ) filename=gstrdup( guiIntfStruct.Filename );
732 else if ( filename ) guiSetFilename( guiIntfStruct.Filename,filename );
734 // --- video opts
736 if ( !video_driver_list )
738 int i = 0;
739 while ( video_out_drivers[i++] )
740 if ( video_out_drivers[i - 1]->control( VOCTRL_GUISUPPORT,NULL ) == VO_TRUE )
742 gaddlist( &video_driver_list,(char *)video_out_drivers[i - 1]->info->short_name );
743 break;
747 if ( !video_driver_list && !video_driver_list[0] ) { gtkMessageBox( GTK_MB_FATAL,MSGTR_IDFGCVD ); exit_player( "gui init" ); }
750 int i = 0;
751 guiIntfStruct.NoWindow=False;
752 while ( video_out_drivers[i++] )
753 if ( video_out_drivers[i - 1]->control( VOCTRL_GUISUPPORT,NULL ) == VO_TRUE )
755 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 ) )
756 { guiIntfStruct.NoWindow=True; break; }
760 #ifdef HAVE_DXR3
761 #ifdef USE_LIBAVCODEC
762 remove_vop( "lavc" );
763 #endif
764 #ifdef USE_LIBFAME
765 remove_vop( "fame" );
766 #endif
767 if ( video_driver_list && !gstrcmp( video_driver_list[0],"dxr3" ) )
769 if ( ( guiIntfStruct.StreamType != STREAMTYPE_DVD)&&( guiIntfStruct.StreamType != STREAMTYPE_VCD ) )
771 #ifdef USE_LIBAVCODEC
772 if ( gtkVopLAVC ) add_vop( "lavc" );
773 #endif
774 #ifdef USE_LIBFAME
775 if ( gtkVopFAME ) add_vop( "fame" );
776 #endif
779 #endif
780 // ---
781 if ( gtkVopPP ) add_vop( "pp" );
782 else remove_vop( "pp" );
784 // --- audio opts
785 // if ( ao_plugin_cfg.plugin_list ) { free( ao_plugin_cfg.plugin_list ); ao_plugin_cfg.plugin_list=NULL; }
786 if ( gtkAONorm ) gset( &ao_plugin_cfg.plugin_list,"volnorm" );
787 if ( gtkEnableAudioEqualizer ) gset( &ao_plugin_cfg.plugin_list,"eq" );
788 if ( gtkAOExtraStereo )
790 gset( &ao_plugin_cfg.plugin_list,"extrastereo" );
791 ao_plugin_cfg.pl_extrastereo_mul=gtkAOExtraStereoMul;
793 #ifdef USE_OSS_AUDIO
794 mixer_device=gstrdup( gtkAOOSSMixer );
795 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"oss",3 ) && gtkAOOSSDevice )
797 char * tmp = calloc( 1,strlen( gtkAOOSSDevice ) + 7 );
798 sprintf( tmp,"oss:%s",gtkAOOSSDevice );
799 gaddlist( &audio_driver_list,tmp );
801 #endif
802 #ifdef HAVE_SDL
803 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"sdl",3 ) && gtkAOSDLDriver )
805 char * tmp = calloc( 1,strlen( gtkAOSDLDriver ) + 10 );
806 sprintf( tmp,"sdl:%s",gtkAOSDLDriver );
807 gaddlist( &audio_driver_list,tmp );
809 #endif
810 // -- subtitle
811 #ifdef USE_SUB
812 //subdata->filename=gstrdup( guiIntfStruct.Subtitlename );
813 stream_dump_type=0;
814 if ( gtkSubDumpMPSub ) stream_dump_type=4;
815 if ( gtkSubDumpSrt ) stream_dump_type=6;
816 gtkSubDumpMPSub=gtkSubDumpSrt=0;
817 #endif
818 #if defined( USE_OSD ) || defined( USE_SUB )
819 guiLoadFont();
820 #endif
822 // --- misc
823 if ( gtkCacheOn ) stream_cache_size=gtkCacheSize;
824 if ( gtkAutoSyncOn ) autosync=gtkAutoSync;
826 if ( guiIntfStruct.AudioFile ) audio_stream=gstrdup( guiIntfStruct.AudioFile );
827 else if ( guiIntfStruct.FilenameChanged ) gfree( (void**)&audio_stream );
828 //audio_stream=NULL;
830 guiIntfStruct.DiskChanged=0;
831 guiIntfStruct.FilenameChanged=0;
832 guiIntfStruct.NewPlay=0;
834 break;
836 return False;
839 void guiEventHandling( void )
841 if ( !guiIntfStruct.Playing || guiIntfStruct.NoWindow ) wsHandleEvents();
842 gtkEventHandling();
845 // ---
847 float gtkEquChannels[6][10];
849 plItem * plCurrent = NULL;
850 plItem * plList = NULL;
851 plItem * plLastPlayed = NULL;
853 URLItem *URLList = NULL;
855 char *fsHistory[fsPersistant_MaxPos] = { NULL,NULL,NULL,NULL,NULL };
857 #if defined( MP_DEBUG ) && 0
858 void list( void )
860 plItem * next = plList;
861 printf( "--- list ---\n" );
862 while( next || next->next )
864 printf( "item: %s/%s\n",next->path,next->name );
865 if ( next->next ) next=next->next; else break;
867 printf( "--- end of list ---\n" );
869 #else
870 #define list();
871 #endif
873 void * gtkSet( int cmd,float fparam, void * vparam )
875 equalizer_t * eq = (equalizer_t *)vparam;
876 plItem * item = (plItem *)vparam;
878 URLItem * url_item = (URLItem *)vparam;
879 int is_added = True;
881 switch ( cmd )
883 // --- handle playlist
884 case gtkAddPlItem: // add item to playlist
885 if ( plList )
887 plItem * next = plList;
888 while ( next->next ) { /*printf( "%s\n",next->name );*/ next=next->next; }
889 next->next=item; item->prev=next;
890 } else { item->prev=item->next=NULL; plCurrent=plList=item; }
891 list();
892 return NULL;
893 case gtkInsertPlItem: // add item into playlist after current
894 if ( plCurrent )
896 plItem * curr = plCurrent;
897 item->next=curr->next;
898 if (item->next)
899 item->next->prev=item;
900 item->prev=curr;
901 curr->next=item;
902 plCurrent=plCurrent->next;
903 return plCurrent;
905 else
906 return gtkSet(gtkAddPlItem,0,(void*)item);
907 return NULL;
908 case gtkGetNextPlItem: // get current item from playlist
909 if ( plCurrent && plCurrent->next)
911 plCurrent=plCurrent->next;
912 /*if ( !plCurrent && plList )
914 plItem * next = plList;
915 while ( next->next ) { if ( !next->next ) break; next=next->next; }
916 plCurrent=next;
918 return plCurrent;
920 return NULL;
921 case gtkGetPrevPlItem:
922 if ( plCurrent && plCurrent->prev)
924 plCurrent=plCurrent->prev;
925 //if ( !plCurrent && plList ) plCurrent=plList;
926 return plCurrent;
928 return NULL;
929 case gtkSetCurrPlItem: // set current item
930 plCurrent=item;
931 return plCurrent;
932 case gtkGetCurrPlItem: // get current item
933 return plCurrent;
934 case gtkDelCurrPlItem: // delete current item
936 plItem * curr = plCurrent;
938 if (!curr)
939 return NULL;
940 if (curr->prev)
941 curr->prev->next=curr->next;
942 if (curr->next)
943 curr->next->prev=curr->prev;
944 if (curr==plList)
945 plList=curr->next;
946 plCurrent=curr->next;
947 // Free it
948 if ( curr->path ) free( curr->path );
949 if ( curr->name ) free( curr->name );
950 free( curr );
952 mplCurr(); // Instead of using mplNext && mplPrev
954 return plCurrent;
955 case gtkDelPl: // delete list
957 plItem * curr = plList;
958 plItem * next;
959 if ( !plList ) return NULL;
960 if ( !curr->next )
962 if ( curr->path ) free( curr->path );
963 if ( curr->name ) free( curr->name );
964 free( curr );
966 else
968 while ( curr->next )
970 next=curr->next;
971 if ( curr->path ) free( curr->path );
972 if ( curr->name ) free( curr->name );
973 free( curr );
974 curr=next;
977 plList=NULL; plCurrent=NULL;
979 return NULL;
980 // ----- Handle url
981 case gtkAddURLItem:
982 if ( URLList )
984 URLItem * next_url = URLList;
985 is_added = False;
986 while ( next_url->next )
988 if ( !gstrcmp( next_url->url,url_item->url ) )
990 is_added=True;
991 break;
993 next_url=next_url->next;
995 if ( ( !is_added )&&( gstrcmp( next_url->url,url_item->url ) ) ) next_url->next=url_item;
996 } else { url_item->next=NULL; URLList=url_item; }
997 return NULL;
998 // --- subtitle
999 #ifndef HAVE_FREETYPE
1000 case gtkSetFontFactor:
1001 font_factor=fparam;
1002 guiLoadFont();
1003 return NULL;
1004 #else
1005 case gtkSetFontOutLine:
1006 subtitle_font_thickness=( 8.0f / 100.0f ) * fparam;
1007 guiLoadFont();
1008 return NULL;
1009 case gtkSetFontBlur:
1010 subtitle_font_radius=( 8.0f / 100.0f ) * fparam;
1011 guiLoadFont();
1012 return NULL;
1013 case gtkSetFontTextScale:
1014 text_font_scale_factor=fparam;
1015 guiLoadFont();
1016 return NULL;
1017 case gtkSetFontOSDScale:
1018 osd_font_scale_factor=fparam;
1019 guiLoadFont();
1020 return NULL;
1021 case gtkSetFontEncoding:
1022 gfree( (void **)&subtitle_font_encoding );
1023 subtitle_font_encoding=gstrdup( (char *)vparam );
1024 guiLoadFont();
1025 return NULL;
1026 case gtkSetFontAutoScale:
1027 subtitle_autoscale=(int)fparam;
1028 guiLoadFont();
1029 return NULL;
1030 #endif
1031 #ifdef USE_ICONV
1032 case gtkSetSubEncoding:
1033 gfree( (void **)&sub_cp );
1034 sub_cp=gstrdup( (char *)vparam );
1035 break;
1036 #endif
1037 // --- misc
1038 case gtkClearStruct:
1039 if ( (unsigned int)vparam & guiFilenames )
1041 gfree( (void **)&guiIntfStruct.Filename );
1042 gfree( (void **)&guiIntfStruct.Subtitlename );
1043 gfree( (void **)&guiIntfStruct.AudioFile );
1044 gtkSet( gtkDelPl,0,NULL );
1046 #ifdef USE_DVDREAD
1047 if ( (unsigned int)vparam & guiDVD ) memset( &guiIntfStruct.DVD,0,sizeof( guiDVDStruct ) );
1048 #endif
1049 #ifdef HAVE_VCD
1050 if ( (unsigned int)vparam & guiVCD ) guiIntfStruct.VCDTracks=0;
1051 #endif
1052 return NULL;
1053 case gtkSetExtraStereo:
1054 gtkAOExtraStereoMul=fparam;
1055 audio_plugin_extrastereo.control( AOCONTROL_PLUGIN_ES_SET,(void *)&gtkAOExtraStereoMul );
1056 return NULL;
1057 case gtkSetPanscan:
1059 mp_cmd_t * mp_cmd;
1060 mp_cmd=(mp_cmd_t *)calloc( 1,sizeof( *mp_cmd ) );
1061 mp_cmd->id=MP_CMD_PANSCAN; mp_cmd->name=strdup( "panscan" );
1062 mp_cmd->args[0].v.f=fparam; mp_cmd->args[1].v.i=1;
1063 mp_input_queue_cmd( mp_cmd );
1065 return NULL;
1066 case gtkSetAutoq:
1067 auto_quality=(int)fparam;
1068 return NULL;
1069 // --- set equalizers
1070 case gtkSetContrast:
1071 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"contrast",(int)fparam );
1072 return NULL;
1073 case gtkSetBrightness:
1074 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"brightness",(int)fparam );
1075 return NULL;
1076 case gtkSetHue:
1077 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"hue",(int)fparam );
1078 return NULL;
1079 case gtkSetSaturation:
1080 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"saturation",(int)fparam );
1081 return NULL;
1082 case gtkSetEqualizer:
1083 if ( eq )
1085 gtkEquChannels[eq->channel][eq->band]=eq->gain;
1086 audio_plugin_eq.control( AOCONTROL_PLUGIN_EQ_SET_GAIN,(void *)eq );
1088 else
1090 int i,j; equalizer_t tmp; tmp.gain=0.0f;
1091 memset( gtkEquChannels,0,sizeof( gtkEquChannels ) );
1092 for ( i=0;i<6;i++ )
1093 for ( j=0;j<10;j++ )
1094 { tmp.channel=i; tmp.band=j; audio_plugin_eq.control( AOCONTROL_PLUGIN_EQ_SET_GAIN,(void *)&tmp ); }
1096 return NULL;
1098 return NULL;
1101 #define mp_basename(s) (strrchr(s,'/')==NULL?(char*)s:(strrchr(s,'/')+1))
1103 #include "../playtree.h"
1105 //This function adds/inserts one file into the gui playlist
1107 int import_file_into_gui(char* temp, int insert)
1109 char *filename, *pathname;
1110 plItem * item;
1112 filename = strdup(mp_basename(temp));
1113 pathname = strdup(temp);
1114 if (strlen(pathname)-strlen(filename)>0)
1115 pathname[strlen(pathname)-strlen(filename)-1]='\0'; // We have some path so remove / at end
1116 else
1117 pathname[strlen(pathname)-strlen(filename)]='\0';
1118 mp_msg(MSGT_PLAYTREE,MSGL_V, "Adding filename %s && pathname %s\n",filename,pathname); //FIXME: Change to MSGL_DBG2 ?
1119 item=calloc( 1,sizeof( plItem ) );
1120 if (!item)
1121 return 0;
1122 item->name=filename;
1123 item->path=pathname;
1124 if (insert)
1125 gtkSet( gtkInsertPlItem,0,(void*)item ); // Inserts the item after current, and makes current=item
1126 else
1127 gtkSet( gtkAddPlItem,0,(void*)item );
1128 return 1;
1132 // This function imports the initial playtree (based on cmd-line files) into the gui playlist
1133 // by either:
1134 // - overwriting gui pl (enqueue=0)
1135 // - appending it to gui pl (enqueue=1)
1137 int import_initial_playtree_into_gui(play_tree_t* my_playtree, m_config_t* config, int enqueue)
1139 play_tree_iter_t* my_pt_iter=NULL;
1140 int result=0;
1142 if (!enqueue) // Delete playlist before "appending"
1143 gtkSet(gtkDelPl,0,0);
1145 if((my_pt_iter=pt_iter_create(&my_playtree,config)))
1147 while ((filename=pt_iter_get_next_file(my_pt_iter))!=NULL)
1149 if (import_file_into_gui(filename, 0)) // Add it to end of list
1150 result=1;
1154 mplCurr(); // Update filename
1155 mplGotoTheNext=1;
1157 if (!enqueue)
1158 filename=guiIntfStruct.Filename; // Backward compatibility; if file is specified on commandline,
1159 // gmplayer does directly start in Play-Mode.
1160 else
1161 filename=NULL;
1163 return result;
1166 // This function imports and inserts an playtree, that is created "on the fly", for example by
1167 // parsing some MOV-Reference-File; or by loading an playlist with "File Open"
1169 // The file which contained the playlist is thereby replaced with it's contents.
1171 int import_playtree_playlist_into_gui(play_tree_t* my_playtree, m_config_t* config)
1173 play_tree_iter_t* my_pt_iter=NULL;
1174 int result=0;
1175 plItem * save=(plItem*)gtkSet( gtkGetCurrPlItem, 0, 0); // Save current item
1177 if((my_pt_iter=pt_iter_create(&my_playtree,config)))
1179 while ((filename=pt_iter_get_next_file(my_pt_iter))!=NULL)
1181 if (import_file_into_gui(filename, 1)) // insert it into the list and set plCurrent=new item
1182 result=1;
1184 pt_iter_destroy(&my_pt_iter);
1187 if (save)
1188 gtkSet(gtkSetCurrPlItem, 0, (void*)save);
1189 else
1190 gtkSet(gtkSetCurrPlItem, 0, (void*)plList); // go to head, if plList was empty before
1192 if (save && result)
1193 gtkSet(gtkDelCurrPlItem, 0, 0);
1195 mplCurr(); // Update filename
1196 filename=NULL;
1198 return result;